1 //===- AttrOrTypeDef.cpp - AttrOrTypeDef wrapper classes ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "mlir/TableGen/AttrOrTypeDef.h"
10 #include "mlir/TableGen/Dialect.h"
11 #include "llvm/ADT/StringExtras.h"
12 #include "llvm/TableGen/Error.h"
13 #include "llvm/TableGen/Record.h"
14 
15 using namespace mlir;
16 using namespace mlir::tblgen;
17 
18 //===----------------------------------------------------------------------===//
19 // AttrOrTypeBuilder
20 //===----------------------------------------------------------------------===//
21 
22 /// Returns true if this builder is able to infer the MLIRContext parameter.
23 bool AttrOrTypeBuilder::hasInferredContextParameter() const {
24   return def->getValueAsBit("hasInferredContextParam");
25 }
26 
27 //===----------------------------------------------------------------------===//
28 // AttrOrTypeDef
29 //===----------------------------------------------------------------------===//
30 
31 AttrOrTypeDef::AttrOrTypeDef(const llvm::Record *def) : def(def) {
32   // Populate the builders.
33   auto *builderList =
34       dyn_cast_or_null<llvm::ListInit>(def->getValueInit("builders"));
35   if (builderList && !builderList->empty()) {
36     for (llvm::Init *init : builderList->getValues()) {
37       AttrOrTypeBuilder builder(cast<llvm::DefInit>(init)->getDef(),
38                                 def->getLoc());
39 
40       // Ensure that all parameters have names.
41       for (const AttrOrTypeBuilder::Parameter &param :
42            builder.getParameters()) {
43         if (!param.getName())
44           PrintFatalError(def->getLoc(), "builder parameters must have a name");
45       }
46       builders.emplace_back(builder);
47     }
48   } else if (skipDefaultBuilders()) {
49     PrintFatalError(
50         def->getLoc(),
51         "default builders are skipped and no custom builders provided");
52   }
53 }
54 
55 Dialect AttrOrTypeDef::getDialect() const {
56   auto *dialect = dyn_cast<llvm::DefInit>(def->getValue("dialect")->getValue());
57   return Dialect(dialect ? dialect->getDef() : nullptr);
58 }
59 
60 StringRef AttrOrTypeDef::getName() const { return def->getName(); }
61 
62 StringRef AttrOrTypeDef::getCppClassName() const {
63   return def->getValueAsString("cppClassName");
64 }
65 
66 StringRef AttrOrTypeDef::getCppBaseClassName() const {
67   return def->getValueAsString("cppBaseClassName");
68 }
69 
70 bool AttrOrTypeDef::hasDescription() const {
71   const llvm::RecordVal *desc = def->getValue("description");
72   return desc && isa<llvm::StringInit>(desc->getValue());
73 }
74 
75 StringRef AttrOrTypeDef::getDescription() const {
76   return def->getValueAsString("description");
77 }
78 
79 bool AttrOrTypeDef::hasSummary() const {
80   const llvm::RecordVal *summary = def->getValue("summary");
81   return summary && isa<llvm::StringInit>(summary->getValue());
82 }
83 
84 StringRef AttrOrTypeDef::getSummary() const {
85   return def->getValueAsString("summary");
86 }
87 
88 StringRef AttrOrTypeDef::getStorageClassName() const {
89   return def->getValueAsString("storageClass");
90 }
91 
92 StringRef AttrOrTypeDef::getStorageNamespace() const {
93   return def->getValueAsString("storageNamespace");
94 }
95 
96 bool AttrOrTypeDef::genStorageClass() const {
97   return def->getValueAsBit("genStorageClass");
98 }
99 
100 bool AttrOrTypeDef::hasStorageCustomConstructor() const {
101   return def->getValueAsBit("hasStorageCustomConstructor");
102 }
103 
104 void AttrOrTypeDef::getParameters(
105     SmallVectorImpl<AttrOrTypeParameter> &parameters) const {
106   if (auto *parametersDag = def->getValueAsDag("parameters")) {
107     for (unsigned i = 0, e = parametersDag->getNumArgs(); i < e; ++i)
108       parameters.push_back(AttrOrTypeParameter(parametersDag, i));
109   }
110 }
111 
112 unsigned AttrOrTypeDef::getNumParameters() const {
113   auto *parametersDag = def->getValueAsDag("parameters");
114   return parametersDag ? parametersDag->getNumArgs() : 0;
115 }
116 
117 Optional<StringRef> AttrOrTypeDef::getMnemonic() const {
118   return def->getValueAsOptionalString("mnemonic");
119 }
120 
121 Optional<StringRef> AttrOrTypeDef::getPrinterCode() const {
122   return def->getValueAsOptionalString("printer");
123 }
124 
125 Optional<StringRef> AttrOrTypeDef::getParserCode() const {
126   return def->getValueAsOptionalString("parser");
127 }
128 
129 bool AttrOrTypeDef::genAccessors() const {
130   return def->getValueAsBit("genAccessors");
131 }
132 
133 bool AttrOrTypeDef::genVerifyDecl() const {
134   return def->getValueAsBit("genVerifyDecl");
135 }
136 
137 Optional<StringRef> AttrOrTypeDef::getExtraDecls() const {
138   auto value = def->getValueAsString("extraClassDeclaration");
139   return value.empty() ? Optional<StringRef>() : value;
140 }
141 
142 ArrayRef<llvm::SMLoc> AttrOrTypeDef::getLoc() const { return def->getLoc(); }
143 
144 bool AttrOrTypeDef::skipDefaultBuilders() const {
145   return def->getValueAsBit("skipDefaultBuilders");
146 }
147 
148 bool AttrOrTypeDef::operator==(const AttrOrTypeDef &other) const {
149   return def == other.def;
150 }
151 
152 bool AttrOrTypeDef::operator<(const AttrOrTypeDef &other) const {
153   return getName() < other.getName();
154 }
155 
156 //===----------------------------------------------------------------------===//
157 // AttrDef
158 //===----------------------------------------------------------------------===//
159 
160 Optional<StringRef> AttrDef::getTypeBuilder() const {
161   return def->getValueAsOptionalString("typeBuilder");
162 }
163 
164 bool AttrDef::classof(const AttrOrTypeDef *def) {
165   return def->getDef()->isSubClassOf("AttrDef");
166 }
167 
168 //===----------------------------------------------------------------------===//
169 // AttrOrTypeParameter
170 //===----------------------------------------------------------------------===//
171 
172 StringRef AttrOrTypeParameter::getName() const {
173   return def->getArgName(index)->getValue();
174 }
175 
176 Optional<StringRef> AttrOrTypeParameter::getAllocator() const {
177   llvm::Init *parameterType = def->getArg(index);
178   if (isa<llvm::StringInit>(parameterType))
179     return Optional<StringRef>();
180 
181   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
182     llvm::RecordVal *code = param->getDef()->getValue("allocator");
183     if (!code)
184       return Optional<StringRef>();
185     if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(code->getValue()))
186       return ci->getValue();
187     if (isa<llvm::UnsetInit>(code->getValue()))
188       return Optional<StringRef>();
189 
190     llvm::PrintFatalError(
191         param->getDef()->getLoc(),
192         "Record `" + def->getArgName(index)->getValue() +
193             "', field `printer' does not have a code initializer!");
194   }
195 
196   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
197                         "defs which inherit from AttrOrTypeParameter\n");
198 }
199 
200 StringRef AttrOrTypeParameter::getCppType() const {
201   auto *parameterType = def->getArg(index);
202   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
203     return stringType->getValue();
204   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
205     return param->getDef()->getValueAsString("cppType");
206   llvm::PrintFatalError(
207       "Parameters DAG arguments must be either strings or defs "
208       "which inherit from AttrOrTypeParameter\n");
209 }
210 
211 Optional<StringRef> AttrOrTypeParameter::getSummary() const {
212   auto *parameterType = def->getArg(index);
213   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
214     const auto *desc = param->getDef()->getValue("summary");
215     if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(desc->getValue()))
216       return ci->getValue();
217   }
218   return Optional<StringRef>();
219 }
220 
221 StringRef AttrOrTypeParameter::getSyntax() const {
222   auto *parameterType = def->getArg(index);
223   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
224     return stringType->getValue();
225   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
226     const auto *syntax = param->getDef()->getValue("syntax");
227     if (syntax && isa<llvm::StringInit>(syntax->getValue()))
228       return cast<llvm::StringInit>(syntax->getValue())->getValue();
229     return getCppType();
230   }
231   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
232                         "defs which inherit from AttrOrTypeParameter");
233 }
234 
235 const llvm::Init *AttrOrTypeParameter::getDef() const {
236   return def->getArg(index);
237 }
238 
239 //===----------------------------------------------------------------------===//
240 // AttributeSelfTypeParameter
241 //===----------------------------------------------------------------------===//
242 
243 bool AttributeSelfTypeParameter::classof(const AttrOrTypeParameter *param) {
244   const llvm::Init *paramDef = param->getDef();
245   if (auto *paramDefInit = dyn_cast<llvm::DefInit>(paramDef))
246     return paramDefInit->getDef()->isSubClassOf("AttributeSelfTypeParameter");
247   return false;
248 }
249