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/SmallPtrSet.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/TableGen/Error.h"
14 #include "llvm/TableGen/Record.h"
15 
16 using namespace mlir;
17 using namespace mlir::tblgen;
18 
19 //===----------------------------------------------------------------------===//
20 // AttrOrTypeBuilder
21 //===----------------------------------------------------------------------===//
22 
23 /// Returns true if this builder is able to infer the MLIRContext parameter.
24 bool AttrOrTypeBuilder::hasInferredContextParameter() const {
25   return def->getValueAsBit("hasInferredContextParam");
26 }
27 
28 //===----------------------------------------------------------------------===//
29 // AttrOrTypeDef
30 //===----------------------------------------------------------------------===//
31 
32 AttrOrTypeDef::AttrOrTypeDef(const llvm::Record *def) : def(def) {
33   // Populate the builders.
34   auto *builderList =
35       dyn_cast_or_null<llvm::ListInit>(def->getValueInit("builders"));
36   if (builderList && !builderList->empty()) {
37     for (llvm::Init *init : builderList->getValues()) {
38       AttrOrTypeBuilder builder(cast<llvm::DefInit>(init)->getDef(),
39                                 def->getLoc());
40 
41       // Ensure that all parameters have names.
42       for (const AttrOrTypeBuilder::Parameter &param :
43            builder.getParameters()) {
44         if (!param.getName())
45           PrintFatalError(def->getLoc(), "builder parameters must have a name");
46       }
47       builders.emplace_back(builder);
48     }
49   }
50 
51   // Populate the traits.
52   if (auto *traitList = def->getValueAsListInit("traits")) {
53     SmallPtrSet<const llvm::Init *, 32> traitSet;
54     traits.reserve(traitSet.size());
55     for (auto *traitInit : *traitList)
56       if (traitSet.insert(traitInit).second)
57         traits.push_back(Trait::create(traitInit));
58   }
59 
60   // Populate the parameters.
61   if (auto *parametersDag = def->getValueAsDag("parameters")) {
62     for (unsigned i = 0, e = parametersDag->getNumArgs(); i < e; ++i)
63       parameters.push_back(AttrOrTypeParameter(parametersDag, i));
64   }
65 }
66 
67 Dialect AttrOrTypeDef::getDialect() const {
68   auto *dialect = dyn_cast<llvm::DefInit>(def->getValue("dialect")->getValue());
69   return Dialect(dialect ? dialect->getDef() : nullptr);
70 }
71 
72 StringRef AttrOrTypeDef::getName() const { return def->getName(); }
73 
74 StringRef AttrOrTypeDef::getCppClassName() const {
75   return def->getValueAsString("cppClassName");
76 }
77 
78 StringRef AttrOrTypeDef::getCppBaseClassName() const {
79   return def->getValueAsString("cppBaseClassName");
80 }
81 
82 bool AttrOrTypeDef::hasDescription() const {
83   const llvm::RecordVal *desc = def->getValue("description");
84   return desc && isa<llvm::StringInit>(desc->getValue());
85 }
86 
87 StringRef AttrOrTypeDef::getDescription() const {
88   return def->getValueAsString("description");
89 }
90 
91 bool AttrOrTypeDef::hasSummary() const {
92   const llvm::RecordVal *summary = def->getValue("summary");
93   return summary && isa<llvm::StringInit>(summary->getValue());
94 }
95 
96 StringRef AttrOrTypeDef::getSummary() const {
97   return def->getValueAsString("summary");
98 }
99 
100 StringRef AttrOrTypeDef::getStorageClassName() const {
101   return def->getValueAsString("storageClass");
102 }
103 
104 StringRef AttrOrTypeDef::getStorageNamespace() const {
105   return def->getValueAsString("storageNamespace");
106 }
107 
108 bool AttrOrTypeDef::genStorageClass() const {
109   return def->getValueAsBit("genStorageClass");
110 }
111 
112 bool AttrOrTypeDef::hasStorageCustomConstructor() const {
113   return def->getValueAsBit("hasStorageCustomConstructor");
114 }
115 
116 unsigned AttrOrTypeDef::getNumParameters() const {
117   auto *parametersDag = def->getValueAsDag("parameters");
118   return parametersDag ? parametersDag->getNumArgs() : 0;
119 }
120 
121 Optional<StringRef> AttrOrTypeDef::getMnemonic() const {
122   return def->getValueAsOptionalString("mnemonic");
123 }
124 
125 Optional<StringRef> AttrOrTypeDef::getPrinterCode() const {
126   return def->getValueAsOptionalString("printer");
127 }
128 
129 Optional<StringRef> AttrOrTypeDef::getParserCode() const {
130   return def->getValueAsOptionalString("parser");
131 }
132 
133 Optional<StringRef> AttrOrTypeDef::getAssemblyFormat() const {
134   return def->getValueAsOptionalString("assemblyFormat");
135 }
136 
137 bool AttrOrTypeDef::genAccessors() const {
138   return def->getValueAsBit("genAccessors");
139 }
140 
141 bool AttrOrTypeDef::genVerifyDecl() const {
142   return def->getValueAsBit("genVerifyDecl");
143 }
144 
145 Optional<StringRef> AttrOrTypeDef::getExtraDecls() const {
146   auto value = def->getValueAsString("extraClassDeclaration");
147   return value.empty() ? Optional<StringRef>() : value;
148 }
149 
150 ArrayRef<llvm::SMLoc> AttrOrTypeDef::getLoc() const { return def->getLoc(); }
151 
152 bool AttrOrTypeDef::skipDefaultBuilders() const {
153   return def->getValueAsBit("skipDefaultBuilders");
154 }
155 
156 bool AttrOrTypeDef::operator==(const AttrOrTypeDef &other) const {
157   return def == other.def;
158 }
159 
160 bool AttrOrTypeDef::operator<(const AttrOrTypeDef &other) const {
161   return getName() < other.getName();
162 }
163 
164 //===----------------------------------------------------------------------===//
165 // AttrDef
166 //===----------------------------------------------------------------------===//
167 
168 Optional<StringRef> AttrDef::getTypeBuilder() const {
169   return def->getValueAsOptionalString("typeBuilder");
170 }
171 
172 bool AttrDef::classof(const AttrOrTypeDef *def) {
173   return def->getDef()->isSubClassOf("AttrDef");
174 }
175 
176 //===----------------------------------------------------------------------===//
177 // AttrOrTypeParameter
178 //===----------------------------------------------------------------------===//
179 
180 StringRef AttrOrTypeParameter::getName() const {
181   return def->getArgName(index)->getValue();
182 }
183 
184 Optional<StringRef> AttrOrTypeParameter::getAllocator() const {
185   llvm::Init *parameterType = def->getArg(index);
186   if (isa<llvm::StringInit>(parameterType))
187     return Optional<StringRef>();
188   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
189     return param->getDef()->getValueAsOptionalString("allocator");
190   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
191                         "defs which inherit from AttrOrTypeParameter\n");
192 }
193 
194 Optional<StringRef> AttrOrTypeParameter::getComparator() const {
195   llvm::Init *parameterType = def->getArg(index);
196   if (isa<llvm::StringInit>(parameterType))
197     return Optional<StringRef>();
198   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
199     return param->getDef()->getValueAsOptionalString("comparator");
200   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
201                         "defs which inherit from AttrOrTypeParameter\n");
202 }
203 
204 StringRef AttrOrTypeParameter::getCppType() const {
205   auto *parameterType = def->getArg(index);
206   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
207     return stringType->getValue();
208   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
209     return param->getDef()->getValueAsString("cppType");
210   llvm::PrintFatalError(
211       "Parameters DAG arguments must be either strings or defs "
212       "which inherit from AttrOrTypeParameter\n");
213 }
214 
215 StringRef AttrOrTypeParameter::getCppAccessorType() const {
216   if (auto *param = dyn_cast<llvm::DefInit>(def->getArg(index))) {
217     if (Optional<StringRef> type =
218             param->getDef()->getValueAsOptionalString("cppAccessorType"))
219       return *type;
220   }
221   return getCppType();
222 }
223 
224 StringRef AttrOrTypeParameter::getCppStorageType() const {
225   if (auto *param = dyn_cast<llvm::DefInit>(def->getArg(index))) {
226     if (auto type = param->getDef()->getValueAsOptionalString("cppStorageType"))
227       return *type;
228   }
229   return getCppType();
230 }
231 
232 Optional<StringRef> AttrOrTypeParameter::getParser() const {
233   auto *parameterType = def->getArg(index);
234   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
235     if (auto parser = param->getDef()->getValueAsOptionalString("parser"))
236       return *parser;
237   }
238   return {};
239 }
240 
241 Optional<StringRef> AttrOrTypeParameter::getPrinter() const {
242   auto *parameterType = def->getArg(index);
243   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
244     if (auto printer = param->getDef()->getValueAsOptionalString("printer"))
245       return *printer;
246   }
247   return {};
248 }
249 
250 Optional<StringRef> AttrOrTypeParameter::getSummary() const {
251   auto *parameterType = def->getArg(index);
252   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
253     const auto *desc = param->getDef()->getValue("summary");
254     if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(desc->getValue()))
255       return ci->getValue();
256   }
257   return Optional<StringRef>();
258 }
259 
260 StringRef AttrOrTypeParameter::getSyntax() const {
261   auto *parameterType = def->getArg(index);
262   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
263     return stringType->getValue();
264   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
265     const auto *syntax = param->getDef()->getValue("syntax");
266     if (syntax && isa<llvm::StringInit>(syntax->getValue()))
267       return cast<llvm::StringInit>(syntax->getValue())->getValue();
268     return getCppType();
269   }
270   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
271                         "defs which inherit from AttrOrTypeParameter");
272 }
273 
274 const llvm::Init *AttrOrTypeParameter::getDef() const {
275   return def->getArg(index);
276 }
277 
278 //===----------------------------------------------------------------------===//
279 // AttributeSelfTypeParameter
280 //===----------------------------------------------------------------------===//
281 
282 bool AttributeSelfTypeParameter::classof(const AttrOrTypeParameter *param) {
283   const llvm::Init *paramDef = param->getDef();
284   if (auto *paramDefInit = dyn_cast<llvm::DefInit>(paramDef))
285     return paramDefInit->getDef()->isSubClassOf("AttributeSelfTypeParameter");
286   return false;
287 }
288