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 
61 Dialect AttrOrTypeDef::getDialect() const {
62   auto *dialect = dyn_cast<llvm::DefInit>(def->getValue("dialect")->getValue());
63   return Dialect(dialect ? dialect->getDef() : nullptr);
64 }
65 
66 StringRef AttrOrTypeDef::getName() const { return def->getName(); }
67 
68 StringRef AttrOrTypeDef::getCppClassName() const {
69   return def->getValueAsString("cppClassName");
70 }
71 
72 StringRef AttrOrTypeDef::getCppBaseClassName() const {
73   return def->getValueAsString("cppBaseClassName");
74 }
75 
76 bool AttrOrTypeDef::hasDescription() const {
77   const llvm::RecordVal *desc = def->getValue("description");
78   return desc && isa<llvm::StringInit>(desc->getValue());
79 }
80 
81 StringRef AttrOrTypeDef::getDescription() const {
82   return def->getValueAsString("description");
83 }
84 
85 bool AttrOrTypeDef::hasSummary() const {
86   const llvm::RecordVal *summary = def->getValue("summary");
87   return summary && isa<llvm::StringInit>(summary->getValue());
88 }
89 
90 StringRef AttrOrTypeDef::getSummary() const {
91   return def->getValueAsString("summary");
92 }
93 
94 StringRef AttrOrTypeDef::getStorageClassName() const {
95   return def->getValueAsString("storageClass");
96 }
97 
98 StringRef AttrOrTypeDef::getStorageNamespace() const {
99   return def->getValueAsString("storageNamespace");
100 }
101 
102 bool AttrOrTypeDef::genStorageClass() const {
103   return def->getValueAsBit("genStorageClass");
104 }
105 
106 bool AttrOrTypeDef::hasStorageCustomConstructor() const {
107   return def->getValueAsBit("hasStorageCustomConstructor");
108 }
109 
110 void AttrOrTypeDef::getParameters(
111     SmallVectorImpl<AttrOrTypeParameter> &parameters) const {
112   if (auto *parametersDag = def->getValueAsDag("parameters")) {
113     for (unsigned i = 0, e = parametersDag->getNumArgs(); i < e; ++i)
114       parameters.push_back(AttrOrTypeParameter(parametersDag, i));
115   }
116 }
117 
118 unsigned AttrOrTypeDef::getNumParameters() const {
119   auto *parametersDag = def->getValueAsDag("parameters");
120   return parametersDag ? parametersDag->getNumArgs() : 0;
121 }
122 
123 Optional<StringRef> AttrOrTypeDef::getMnemonic() const {
124   return def->getValueAsOptionalString("mnemonic");
125 }
126 
127 Optional<StringRef> AttrOrTypeDef::getPrinterCode() const {
128   return def->getValueAsOptionalString("printer");
129 }
130 
131 Optional<StringRef> AttrOrTypeDef::getParserCode() const {
132   return def->getValueAsOptionalString("parser");
133 }
134 
135 Optional<StringRef> AttrOrTypeDef::getAssemblyFormat() const {
136   return def->getValueAsOptionalString("assemblyFormat");
137 }
138 
139 bool AttrOrTypeDef::genAccessors() const {
140   return def->getValueAsBit("genAccessors");
141 }
142 
143 bool AttrOrTypeDef::genVerifyDecl() const {
144   return def->getValueAsBit("genVerifyDecl");
145 }
146 
147 Optional<StringRef> AttrOrTypeDef::getExtraDecls() const {
148   auto value = def->getValueAsString("extraClassDeclaration");
149   return value.empty() ? Optional<StringRef>() : value;
150 }
151 
152 ArrayRef<llvm::SMLoc> AttrOrTypeDef::getLoc() const { return def->getLoc(); }
153 
154 bool AttrOrTypeDef::skipDefaultBuilders() const {
155   return def->getValueAsBit("skipDefaultBuilders");
156 }
157 
158 bool AttrOrTypeDef::operator==(const AttrOrTypeDef &other) const {
159   return def == other.def;
160 }
161 
162 bool AttrOrTypeDef::operator<(const AttrOrTypeDef &other) const {
163   return getName() < other.getName();
164 }
165 
166 //===----------------------------------------------------------------------===//
167 // AttrDef
168 //===----------------------------------------------------------------------===//
169 
170 Optional<StringRef> AttrDef::getTypeBuilder() const {
171   return def->getValueAsOptionalString("typeBuilder");
172 }
173 
174 bool AttrDef::classof(const AttrOrTypeDef *def) {
175   return def->getDef()->isSubClassOf("AttrDef");
176 }
177 
178 //===----------------------------------------------------------------------===//
179 // AttrOrTypeParameter
180 //===----------------------------------------------------------------------===//
181 
182 StringRef AttrOrTypeParameter::getName() const {
183   return def->getArgName(index)->getValue();
184 }
185 
186 Optional<StringRef> AttrOrTypeParameter::getAllocator() const {
187   llvm::Init *parameterType = def->getArg(index);
188   if (isa<llvm::StringInit>(parameterType))
189     return Optional<StringRef>();
190   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
191     return param->getDef()->getValueAsOptionalString("allocator");
192   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
193                         "defs which inherit from AttrOrTypeParameter\n");
194 }
195 
196 Optional<StringRef> AttrOrTypeParameter::getComparator() const {
197   llvm::Init *parameterType = def->getArg(index);
198   if (isa<llvm::StringInit>(parameterType))
199     return Optional<StringRef>();
200   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
201     return param->getDef()->getValueAsOptionalString("comparator");
202   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
203                         "defs which inherit from AttrOrTypeParameter\n");
204 }
205 
206 StringRef AttrOrTypeParameter::getCppType() const {
207   auto *parameterType = def->getArg(index);
208   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
209     return stringType->getValue();
210   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
211     return param->getDef()->getValueAsString("cppType");
212   llvm::PrintFatalError(
213       "Parameters DAG arguments must be either strings or defs "
214       "which inherit from AttrOrTypeParameter\n");
215 }
216 
217 StringRef AttrOrTypeParameter::getCppAccessorType() const {
218   if (auto *param = dyn_cast<llvm::DefInit>(def->getArg(index))) {
219     if (Optional<StringRef> type =
220             param->getDef()->getValueAsOptionalString("cppAccessorType"))
221       return *type;
222   }
223   return getCppType();
224 }
225 
226 StringRef AttrOrTypeParameter::getCppStorageType() const {
227   if (auto *param = dyn_cast<llvm::DefInit>(def->getArg(index))) {
228     if (auto type = param->getDef()->getValueAsOptionalString("cppStorageType"))
229       return *type;
230   }
231   return getCppType();
232 }
233 
234 Optional<StringRef> AttrOrTypeParameter::getParser() const {
235   auto *parameterType = def->getArg(index);
236   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
237     if (auto parser = param->getDef()->getValueAsOptionalString("parser"))
238       return *parser;
239   }
240   return {};
241 }
242 
243 Optional<StringRef> AttrOrTypeParameter::getPrinter() const {
244   auto *parameterType = def->getArg(index);
245   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
246     if (auto printer = param->getDef()->getValueAsOptionalString("printer"))
247       return *printer;
248   }
249   return {};
250 }
251 
252 Optional<StringRef> AttrOrTypeParameter::getSummary() const {
253   auto *parameterType = def->getArg(index);
254   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
255     const auto *desc = param->getDef()->getValue("summary");
256     if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(desc->getValue()))
257       return ci->getValue();
258   }
259   return Optional<StringRef>();
260 }
261 
262 StringRef AttrOrTypeParameter::getSyntax() const {
263   auto *parameterType = def->getArg(index);
264   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
265     return stringType->getValue();
266   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
267     const auto *syntax = param->getDef()->getValue("syntax");
268     if (syntax && isa<llvm::StringInit>(syntax->getValue()))
269       return cast<llvm::StringInit>(syntax->getValue())->getValue();
270     return getCppType();
271   }
272   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
273                         "defs which inherit from AttrOrTypeParameter");
274 }
275 
276 const llvm::Init *AttrOrTypeParameter::getDef() const {
277   return def->getArg(index);
278 }
279 
280 //===----------------------------------------------------------------------===//
281 // AttributeSelfTypeParameter
282 //===----------------------------------------------------------------------===//
283 
284 bool AttributeSelfTypeParameter::classof(const AttrOrTypeParameter *param) {
285   const llvm::Init *paramDef = param->getDef();
286   if (auto *paramDefInit = dyn_cast<llvm::DefInit>(paramDef))
287     return paramDefInit->getDef()->isSubClassOf("AttributeSelfTypeParameter");
288   return false;
289 }
290