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/FunctionExtras.h"
12#include "llvm/ADT/SmallPtrSet.h"
13#include "llvm/ADT/StringExtras.h"
14#include "llvm/Support/ErrorHandling.h"
15#include "llvm/TableGen/Error.h"
16#include "llvm/TableGen/Record.h"
17
18using namespace mlir;
19using namespace mlir::tblgen;
20using llvm::DefInit;
21using llvm::Init;
22using llvm::ListInit;
23using llvm::Record;
24using llvm::RecordVal;
25using llvm::StringInit;
26
27//===----------------------------------------------------------------------===//
28// AttrOrTypeBuilder
29//===----------------------------------------------------------------------===//
30
31std::optional<StringRef> AttrOrTypeBuilder::getReturnType() const {
32 std::optional<StringRef> type = def->getValueAsOptionalString(FieldName: "returnType");
33 return type && !type->empty() ? type : std::nullopt;
34}
35
36bool AttrOrTypeBuilder::hasInferredContextParameter() const {
37 return def->getValueAsBit(FieldName: "hasInferredContextParam");
38}
39
40//===----------------------------------------------------------------------===//
41// AttrOrTypeDef
42//===----------------------------------------------------------------------===//
43
44AttrOrTypeDef::AttrOrTypeDef(const Record *def) : def(def) {
45 // Populate the builders.
46 const auto *builderList =
47 dyn_cast_or_null<ListInit>(Val: def->getValueInit(FieldName: "builders"));
48 if (builderList && !builderList->empty()) {
49 for (const Init *init : builderList->getElements()) {
50 AttrOrTypeBuilder builder(cast<DefInit>(Val: init)->getDef(), def->getLoc());
51
52 // Ensure that all parameters have names.
53 for (const AttrOrTypeBuilder::Parameter &param :
54 builder.getParameters()) {
55 if (!param.getName())
56 PrintFatalError(ErrorLoc: def->getLoc(), Msg: "builder parameters must have a name");
57 }
58 builders.emplace_back(Args&: builder);
59 }
60 }
61
62 // Populate the traits.
63 if (auto *traitList = def->getValueAsListInit(FieldName: "traits")) {
64 SmallPtrSet<const Init *, 32> traitSet;
65 traits.reserve(N: traitSet.size());
66 llvm::unique_function<void(const ListInit *)> processTraitList =
67 [&](const ListInit *traitList) {
68 for (auto *traitInit : *traitList) {
69 if (!traitSet.insert(Ptr: traitInit).second)
70 continue;
71
72 // If this is an interface, add any bases to the trait list.
73 auto *traitDef = cast<DefInit>(Val: traitInit)->getDef();
74 if (traitDef->isSubClassOf(Name: "Interface")) {
75 if (auto *bases = traitDef->getValueAsListInit(FieldName: "baseInterfaces"))
76 processTraitList(bases);
77 }
78
79 traits.push_back(Elt: Trait::create(init: traitInit));
80 }
81 };
82 processTraitList(traitList);
83 }
84
85 // Populate the parameters.
86 if (auto *parametersDag = def->getValueAsDag(FieldName: "parameters")) {
87 for (unsigned i = 0, e = parametersDag->getNumArgs(); i < e; ++i)
88 parameters.push_back(Elt: AttrOrTypeParameter(parametersDag, i));
89 }
90
91 // Verify the use of the mnemonic field.
92 bool hasCppFormat = hasCustomAssemblyFormat();
93 bool hasDeclarativeFormat = getAssemblyFormat().has_value();
94 if (getMnemonic()) {
95 if (hasCppFormat && hasDeclarativeFormat) {
96 PrintFatalError(ErrorLoc: getLoc(), Msg: "cannot specify both 'assemblyFormat' "
97 "and 'hasCustomAssemblyFormat'");
98 }
99 if (!parameters.empty() && !hasCppFormat && !hasDeclarativeFormat) {
100 PrintFatalError(ErrorLoc: getLoc(),
101 Msg: "must specify either 'assemblyFormat' or "
102 "'hasCustomAssemblyFormat' when 'mnemonic' is set");
103 }
104 } else if (hasCppFormat || hasDeclarativeFormat) {
105 PrintFatalError(ErrorLoc: getLoc(),
106 Msg: "'assemblyFormat' or 'hasCustomAssemblyFormat' can only be "
107 "used when 'mnemonic' is set");
108 }
109 // Assembly format printer requires accessors to be generated.
110 if (hasDeclarativeFormat && !genAccessors()) {
111 PrintFatalError(ErrorLoc: getLoc(),
112 Msg: "'assemblyFormat' requires 'genAccessors' to be true");
113 }
114 // TODO: Ensure that a suitable builder prototype can be generated:
115 // https://llvm.org/PR56415
116}
117
118Dialect AttrOrTypeDef::getDialect() const {
119 const auto *dialect = dyn_cast<DefInit>(Val: def->getValue(Name: "dialect")->getValue());
120 return Dialect(dialect ? dialect->getDef() : nullptr);
121}
122
123StringRef AttrOrTypeDef::getName() const { return def->getName(); }
124
125StringRef AttrOrTypeDef::getCppClassName() const {
126 return def->getValueAsString(FieldName: "cppClassName");
127}
128
129StringRef AttrOrTypeDef::getCppBaseClassName() const {
130 return def->getValueAsString(FieldName: "cppBaseClassName");
131}
132
133bool AttrOrTypeDef::hasDescription() const {
134 const RecordVal *desc = def->getValue(Name: "description");
135 return desc && isa<StringInit>(Val: desc->getValue());
136}
137
138StringRef AttrOrTypeDef::getDescription() const {
139 return def->getValueAsString(FieldName: "description");
140}
141
142bool AttrOrTypeDef::hasSummary() const {
143 const RecordVal *summary = def->getValue(Name: "summary");
144 return summary && isa<StringInit>(Val: summary->getValue());
145}
146
147StringRef AttrOrTypeDef::getSummary() const {
148 return def->getValueAsString(FieldName: "summary");
149}
150
151StringRef AttrOrTypeDef::getStorageClassName() const {
152 return def->getValueAsString(FieldName: "storageClass");
153}
154
155StringRef AttrOrTypeDef::getStorageNamespace() const {
156 return def->getValueAsString(FieldName: "storageNamespace");
157}
158
159bool AttrOrTypeDef::genStorageClass() const {
160 return def->getValueAsBit(FieldName: "genStorageClass");
161}
162
163bool AttrOrTypeDef::hasStorageCustomConstructor() const {
164 return def->getValueAsBit(FieldName: "hasStorageCustomConstructor");
165}
166
167unsigned AttrOrTypeDef::getNumParameters() const {
168 auto *parametersDag = def->getValueAsDag(FieldName: "parameters");
169 return parametersDag ? parametersDag->getNumArgs() : 0;
170}
171
172std::optional<StringRef> AttrOrTypeDef::getMnemonic() const {
173 return def->getValueAsOptionalString(FieldName: "mnemonic");
174}
175
176bool AttrOrTypeDef::hasCustomAssemblyFormat() const {
177 return def->getValueAsBit(FieldName: "hasCustomAssemblyFormat");
178}
179
180std::optional<StringRef> AttrOrTypeDef::getAssemblyFormat() const {
181 return def->getValueAsOptionalString(FieldName: "assemblyFormat");
182}
183
184bool AttrOrTypeDef::genAccessors() const {
185 return def->getValueAsBit(FieldName: "genAccessors");
186}
187
188bool AttrOrTypeDef::genVerifyDecl() const {
189 return def->getValueAsBit(FieldName: "genVerifyDecl");
190}
191
192bool AttrOrTypeDef::genVerifyInvariantsImpl() const {
193 return any_of(Range: parameters, P: [](const AttrOrTypeParameter &p) {
194 return p.getConstraint() != std::nullopt;
195 });
196}
197
198std::optional<StringRef> AttrOrTypeDef::getExtraDecls() const {
199 auto value = def->getValueAsString(FieldName: "extraClassDeclaration");
200 return value.empty() ? std::optional<StringRef>() : value;
201}
202
203std::optional<StringRef> AttrOrTypeDef::getExtraDefs() const {
204 auto value = def->getValueAsString(FieldName: "extraClassDefinition");
205 return value.empty() ? std::optional<StringRef>() : value;
206}
207
208bool AttrOrTypeDef::genMnemonicAlias() const {
209 return def->getValueAsBit(FieldName: "genMnemonicAlias");
210}
211
212ArrayRef<SMLoc> AttrOrTypeDef::getLoc() const { return def->getLoc(); }
213
214bool AttrOrTypeDef::skipDefaultBuilders() const {
215 return def->getValueAsBit(FieldName: "skipDefaultBuilders");
216}
217
218bool AttrOrTypeDef::operator==(const AttrOrTypeDef &other) const {
219 return def == other.def;
220}
221
222bool AttrOrTypeDef::operator<(const AttrOrTypeDef &other) const {
223 return getName() < other.getName();
224}
225
226//===----------------------------------------------------------------------===//
227// AttrDef
228//===----------------------------------------------------------------------===//
229
230std::optional<StringRef> AttrDef::getTypeBuilder() const {
231 return def->getValueAsOptionalString(FieldName: "typeBuilder");
232}
233
234bool AttrDef::classof(const AttrOrTypeDef *def) {
235 return def->getDef()->isSubClassOf(Name: "AttrDef");
236}
237
238StringRef AttrDef::getAttrName() const {
239 return def->getValueAsString(FieldName: "attrName");
240}
241
242//===----------------------------------------------------------------------===//
243// TypeDef
244//===----------------------------------------------------------------------===//
245
246bool TypeDef::classof(const AttrOrTypeDef *def) {
247 return def->getDef()->isSubClassOf(Name: "TypeDef");
248}
249
250StringRef TypeDef::getTypeName() const {
251 return def->getValueAsString(FieldName: "typeName");
252}
253
254//===----------------------------------------------------------------------===//
255// AttrOrTypeParameter
256//===----------------------------------------------------------------------===//
257
258template <typename InitT>
259auto AttrOrTypeParameter::getDefValue(StringRef name) const {
260 std::optional<decltype(std::declval<InitT>().getValue())> result;
261 if (const auto *param = dyn_cast<DefInit>(Val: getDef()))
262 if (const auto *init = param->getDef()->getValue(Name: name))
263 if (const auto *value = dyn_cast_or_null<InitT>(init->getValue()))
264 result = value->getValue();
265 return result;
266}
267
268bool AttrOrTypeParameter::isAnonymous() const {
269 return !def->getArgName(Num: index);
270}
271
272StringRef AttrOrTypeParameter::getName() const {
273 return def->getArgName(Num: index)->getValue();
274}
275
276std::string AttrOrTypeParameter::getAccessorName() const {
277 return "get" +
278 llvm::convertToCamelFromSnakeCase(input: getName(), /*capitalizeFirst=*/true);
279}
280
281std::optional<StringRef> AttrOrTypeParameter::getAllocator() const {
282 return getDefValue<StringInit>(name: "allocator");
283}
284
285bool AttrOrTypeParameter::hasCustomComparator() const {
286 return getDefValue<StringInit>(name: "comparator").has_value();
287}
288
289StringRef AttrOrTypeParameter::getComparator() const {
290 return getDefValue<StringInit>(name: "comparator").value_or(u: "$_lhs == $_rhs");
291}
292
293StringRef AttrOrTypeParameter::getCppType() const {
294 if (auto *stringType = dyn_cast<StringInit>(Val: getDef()))
295 return stringType->getValue();
296 auto cppType = getDefValue<StringInit>(name: "cppType");
297 if (cppType)
298 return *cppType;
299 if (const auto *init = dyn_cast<DefInit>(Val: getDef()))
300 llvm::PrintFatalError(
301 ErrorLoc: init->getDef()->getLoc(),
302 Msg: Twine("Missing `cppType` field in Attribute/Type parameter: ") +
303 init->getAsString());
304 llvm::reportFatalUsageError(
305 reason: Twine("Missing `cppType` field in Attribute/Type parameter: ") +
306 getDef()->getAsString());
307}
308
309StringRef AttrOrTypeParameter::getCppAccessorType() const {
310 return getDefValue<StringInit>(name: "cppAccessorType").value_or(u: getCppType());
311}
312
313StringRef AttrOrTypeParameter::getCppStorageType() const {
314 return getDefValue<StringInit>(name: "cppStorageType").value_or(u: getCppType());
315}
316
317StringRef AttrOrTypeParameter::getConvertFromStorage() const {
318 return getDefValue<StringInit>(name: "convertFromStorage").value_or(u: "$_self");
319}
320
321std::optional<StringRef> AttrOrTypeParameter::getParser() const {
322 return getDefValue<StringInit>(name: "parser");
323}
324
325std::optional<StringRef> AttrOrTypeParameter::getPrinter() const {
326 return getDefValue<StringInit>(name: "printer");
327}
328
329std::optional<StringRef> AttrOrTypeParameter::getSummary() const {
330 return getDefValue<StringInit>(name: "summary");
331}
332
333StringRef AttrOrTypeParameter::getSyntax() const {
334 if (auto *stringType = dyn_cast<StringInit>(Val: getDef()))
335 return stringType->getValue();
336 return getDefValue<StringInit>(name: "syntax").value_or(u: getCppType());
337}
338
339bool AttrOrTypeParameter::isOptional() const {
340 return getDefaultValue().has_value();
341}
342
343std::optional<StringRef> AttrOrTypeParameter::getDefaultValue() const {
344 std::optional<StringRef> result = getDefValue<StringInit>(name: "defaultValue");
345 return result && !result->empty() ? result : std::nullopt;
346}
347
348const Init *AttrOrTypeParameter::getDef() const { return def->getArg(Num: index); }
349
350std::optional<Constraint> AttrOrTypeParameter::getConstraint() const {
351 if (const auto *param = dyn_cast<DefInit>(Val: getDef()))
352 if (param->getDef()->isSubClassOf(Name: "Constraint"))
353 return Constraint(param->getDef());
354 return std::nullopt;
355}
356
357//===----------------------------------------------------------------------===//
358// AttributeSelfTypeParameter
359//===----------------------------------------------------------------------===//
360
361bool AttributeSelfTypeParameter::classof(const AttrOrTypeParameter *param) {
362 const Init *paramDef = param->getDef();
363 if (const auto *paramDefInit = dyn_cast<DefInit>(Val: paramDef))
364 return paramDefInit->getDef()->isSubClassOf(Name: "AttributeSelfTypeParameter");
365 return false;
366}
367

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of mlir/lib/TableGen/AttrOrTypeDef.cpp