MLIR 23.0.0git
AttrOrTypeDef.cpp
Go to the documentation of this file.
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
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("returnType");
33 return type && !type->empty() ? type : std::nullopt;
34}
35
37 return def->getValueAsBit("hasInferredContextParam");
38}
39
40//===----------------------------------------------------------------------===//
41// AttrOrTypeDef
42//===----------------------------------------------------------------------===//
43
45 // Populate the builders.
46 const auto *builderList =
47 dyn_cast_or_null<ListInit>(def->getValueInit("builders"));
48 if (builderList && !builderList->empty()) {
49 for (const Init *init : builderList->getElements()) {
50 AttrOrTypeBuilder builder(cast<DefInit>(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(def->getLoc(), "builder parameters must have a name");
57 }
58 builders.emplace_back(builder);
59 }
60 }
61
62 // Populate the traits.
63 if (auto *traitList = def->getValueAsListInit("traits")) {
65 traits.reserve(traitSet.size());
66 llvm::unique_function<void(const ListInit *)> processTraitList =
67 [&](const ListInit *traitList) {
68 for (auto *traitInit : *traitList) {
69 if (!traitSet.insert(traitInit).second)
70 continue;
71
72 // If this is an interface, add any bases to the trait list.
73 auto *traitDef = cast<DefInit>(traitInit)->getDef();
74 if (traitDef->isSubClassOf("Interface")) {
75 if (auto *bases = traitDef->getValueAsListInit("baseInterfaces"))
76 processTraitList(bases);
77 }
78
79 traits.push_back(Trait::create(traitInit));
80 }
81 };
82 processTraitList(traitList);
83 }
84
85 // Populate the parameters.
86 if (auto *parametersDag = def->getValueAsDag("parameters")) {
87 for (unsigned i = 0, e = parametersDag->getNumArgs(); i < e; ++i)
88 parameters.push_back(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(getLoc(), "cannot specify both 'assemblyFormat' "
97 "and 'hasCustomAssemblyFormat'");
98 }
99 if (!parameters.empty() && !hasCppFormat && !hasDeclarativeFormat) {
100 PrintFatalError(getLoc(),
101 "must specify either 'assemblyFormat' or "
102 "'hasCustomAssemblyFormat' when 'mnemonic' is set");
103 }
104 } else if (hasCppFormat || hasDeclarativeFormat) {
105 PrintFatalError(getLoc(),
106 "'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(getLoc(),
112 "'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
119 const auto *dialect = dyn_cast<DefInit>(def->getValue("dialect")->getValue());
120 return Dialect(dialect ? dialect->getDef() : nullptr);
121}
122
123StringRef AttrOrTypeDef::getName() const { return def->getName(); }
124
126 return def->getValueAsString("cppClassName");
127}
128
130 return def->getValueAsString("cppBaseClassName");
131}
132
134 const RecordVal *desc = def->getValue("description");
135 return desc && isa<StringInit>(desc->getValue());
136}
137
139 return def->getValueAsString("description");
140}
141
143 const RecordVal *summary = def->getValue("summary");
144 return summary && isa<StringInit>(summary->getValue());
145}
146
147StringRef AttrOrTypeDef::getSummary() const {
148 return def->getValueAsString("summary");
149}
150
152 return def->getValueAsString("storageClass");
154
156 return def->getValueAsString("storageNamespace");
157}
158
160 return def->getValueAsBit("genStorageClass");
161}
162
164 return def->getValueAsBit("hasStorageCustomConstructor");
165}
166
168 auto *parametersDag = def->getValueAsDag("parameters");
169 return parametersDag ? parametersDag->getNumArgs() : 0;
170}
171
172std::optional<StringRef> AttrOrTypeDef::getMnemonic() const {
173 return def->getValueAsOptionalString("mnemonic");
174}
175
177 return def->getValueAsBit("hasCustomAssemblyFormat");
178}
179
180std::optional<StringRef> AttrOrTypeDef::getAssemblyFormat() const {
181 return def->getValueAsOptionalString("assemblyFormat");
182}
183
185 return def->getValueAsBit("genAccessors");
186}
187
189 return def->getValueAsBit("genVerifyDecl");
190}
191
193 return any_of(parameters,
194 [](const AttrOrTypeParameter &p) {
195 return p.getConstraint() != std::nullopt;
196 }) ||
197 any_of(traits, [](const Trait &t) { return isa<PredTrait>(&t); });
198}
199
200std::optional<StringRef> AttrOrTypeDef::getExtraDecls() const {
201 auto value = def->getValueAsString("extraClassDeclaration");
202 return value.empty() ? std::optional<StringRef>() : value;
203}
204
205std::optional<StringRef> AttrOrTypeDef::getExtraDefs() const {
206 auto value = def->getValueAsString("extraClassDefinition");
207 return value.empty() ? std::optional<StringRef>() : value;
208}
209
211 return def->getValueAsBit("genMnemonicAlias");
212}
213
214ArrayRef<SMLoc> AttrOrTypeDef::getLoc() const { return def->getLoc(); }
215
217 return def->getValueAsBit("skipDefaultBuilders");
218}
219
220bool AttrOrTypeDef::operator==(const AttrOrTypeDef &other) const {
221 return def == other.def;
222}
223
224bool AttrOrTypeDef::operator<(const AttrOrTypeDef &other) const {
225 return getName() < other.getName();
226}
227
228//===----------------------------------------------------------------------===//
229// AttrDef
230//===----------------------------------------------------------------------===//
231
232std::optional<StringRef> AttrDef::getTypeBuilder() const {
233 return def->getValueAsOptionalString("typeBuilder");
234}
235
237 return def->getDef()->isSubClassOf("AttrDef");
238}
239
240StringRef AttrDef::getAttrName() const {
241 return def->getValueAsString("attrName");
242}
243
244//===----------------------------------------------------------------------===//
245// TypeDef
246//===----------------------------------------------------------------------===//
247
249 return def->getDef()->isSubClassOf("TypeDef");
250}
251
252StringRef TypeDef::getTypeName() const {
253 return def->getValueAsString("typeName");
254}
255
256//===----------------------------------------------------------------------===//
257// AttrOrTypeParameter
258//===----------------------------------------------------------------------===//
259
260template <typename InitT>
261auto AttrOrTypeParameter::getDefValue(StringRef name) const {
262 std::optional<decltype(std::declval<InitT>().getValue())> result;
263 if (const auto *param = dyn_cast<DefInit>(getDef()))
264 if (const auto *init = param->getDef()->getValue(name))
265 if (const auto *value = dyn_cast_or_null<InitT>(init->getValue()))
266 result = value->getValue();
267 return result;
268}
269
271 return !def->getArgName(index);
272}
273
275 return def->getArgName(index)->getValue();
276}
277
279 return "get" +
280 llvm::convertToCamelFromSnakeCase(getName(), /*capitalizeFirst=*/true);
281}
282
283std::optional<StringRef> AttrOrTypeParameter::getAllocator() const {
284 return getDefValue<StringInit>("allocator");
285}
286
288 return getDefValue<StringInit>("comparator").has_value();
289}
290
292 return getDefValue<StringInit>("comparator").value_or("$_lhs == $_rhs");
293}
294
296 if (auto *stringType = dyn_cast<StringInit>(getDef()))
297 return stringType->getValue();
298 auto cppType = getDefValue<StringInit>("cppType");
299 if (cppType)
300 return *cppType;
301 if (const auto *init = dyn_cast<DefInit>(getDef()))
302 llvm::PrintFatalError(
303 init->getDef()->getLoc(),
304 Twine("Missing `cppType` field in Attribute/Type parameter: ") +
305 init->getAsString());
306 llvm::reportFatalUsageError(
307 Twine("Missing `cppType` field in Attribute/Type parameter: ") +
308 getDef()->getAsString());
309}
310
312 return getDefValue<StringInit>("cppAccessorType").value_or(getCppType());
313}
314
316 return getDefValue<StringInit>("cppStorageType").value_or(getCppType());
317}
318
320 return getDefValue<StringInit>("convertFromStorage").value_or("$_self");
321}
322
323std::optional<StringRef> AttrOrTypeParameter::getParser() const {
324 return getDefValue<StringInit>("parser");
325}
326
327std::optional<StringRef> AttrOrTypeParameter::getPrinter() const {
328 return getDefValue<StringInit>("printer");
329}
330
331std::optional<StringRef> AttrOrTypeParameter::getSummary() const {
332 return getDefValue<StringInit>("summary");
333}
334
336 if (auto *stringType = dyn_cast<StringInit>(getDef()))
337 return stringType->getValue();
338 return getDefValue<StringInit>("syntax").value_or(getCppType());
339}
340
342 return getDefaultValue().has_value();
343}
344
345std::optional<StringRef> AttrOrTypeParameter::getDefaultValue() const {
346 std::optional<StringRef> result = getDefValue<StringInit>("defaultValue");
347 return result && !result->empty() ? result : std::nullopt;
348}
349
350const Init *AttrOrTypeParameter::getDef() const { return def->getArg(index); }
351
352std::optional<Constraint> AttrOrTypeParameter::getConstraint() const {
353 if (const auto *param = dyn_cast<DefInit>(getDef()))
354 if (param->getDef()->isSubClassOf("Constraint"))
355 return Constraint(param->getDef());
356 return std::nullopt;
357}
358
359//===----------------------------------------------------------------------===//
360// AttributeSelfTypeParameter
361//===----------------------------------------------------------------------===//
362
364 const Init *paramDef = param->getDef();
365 if (const auto *paramDefInit = dyn_cast<DefInit>(paramDef))
366 return paramDefInit->getDef()->isSubClassOf("AttributeSelfTypeParameter");
367 return false;
368}
AttrOrTypeDef(const llvm::Record *def)
StringRef getAttrName() const
Get the unique attribute name "dialect.attrname".
std::optional< StringRef > getTypeBuilder() const
Returns the attributes value type builder code block, or std::nullopt if it doesn't have one.
static bool classof(const AttrOrTypeDef *def)
Wrapper class that represents a Tablegen AttrOrTypeBuilder.
bool hasInferredContextParameter() const
Returns true if this builder is able to infer the MLIRContext parameter.
std::optional< StringRef > getReturnType() const
Returns an optional builder return type.
SmallVector< AttrOrTypeParameter > parameters
The parameters of this attribute or type.
bool hasCustomAssemblyFormat() const
Returns if the attribute or type has a custom assembly format implemented in C++.
std::optional< StringRef > getMnemonic() const
Return the keyword/mnemonic to use in the printer/parser methods if we are supposed to auto-generate ...
bool operator==(const AttrOrTypeDef &other) const
Returns whether two AttrOrTypeDefs are equal by checking the equality of the underlying record.
StringRef getCppClassName() const
Returns the name of the C++ class to generate.
AttrOrTypeDef(const llvm::Record *def)
const llvm::Record * def
StringRef getStorageNamespace() const
Returns the C++ namespace for this def's storage class.
bool genVerifyDecl() const
Return true if we need to generate the verify declaration and getChecked method.
bool genMnemonicAlias() const
Returns true if we need to generate a default 'getAlias' implementation using the mnemonic.
ArrayRef< SMLoc > getLoc() const
Get the code location (for error printing).
bool hasDescription() const
Query functions for the documentation of the def.
StringRef getCppBaseClassName() const
Returns the name of the C++ base class to use when generating this def.
const llvm::Record * getDef() const
Return the underlying def.
Dialect getDialect() const
Get the dialect for which this def belongs.
SmallVector< Trait > traits
The traits of this definition.
std::optional< StringRef > getExtraDefs() const
Returns the def's extra class definition code.
bool genStorageClass() const
Returns true if we should generate the storage class.
StringRef getDescription() const
std::optional< StringRef > getExtraDecls() const
Returns the def's extra class declaration code.
bool genVerifyInvariantsImpl() const
Return true if we need to generate any type constraint verification and the getChecked method.
StringRef getStorageClassName() const
Returns the name of the storage class for this def.
SmallVector< AttrOrTypeBuilder > builders
The builders of this definition.
bool hasStorageCustomConstructor() const
Indicates whether or not to generate the storage class constructor.
bool skipDefaultBuilders() const
Returns true if the default get/getChecked methods should be skipped during generation.
unsigned getNumParameters() const
Return the number of parameters.
std::optional< StringRef > getAssemblyFormat() const
Returns the custom assembly format, if one was specified.
bool operator<(const AttrOrTypeDef &other) const
Compares two AttrOrTypeDefs by comparing the names of the dialects.
StringRef getName() const
Returns the name of this AttrOrTypeDef record.
bool genAccessors() const
Returns true if the accessors based on the parameters should be generated.
A wrapper class for tblgen AttrOrTypeParameter, arrays of which belong to AttrOrTypeDefs to parameter...
bool hasCustomComparator() const
Return true if user defined comparator is specified.
std::optional< StringRef > getParser() const
Get an optional C++ parameter parser.
StringRef getSyntax() const
Get the assembly syntax documentation.
std::optional< Constraint > getConstraint() const
If this is a type constraint, return it.
StringRef getComparator() const
Get the custom comparator code for this parameter or fallback to the default.
StringRef getName() const
Get the parameter name.
const llvm::Init * getDef() const
Return the underlying def of this parameter.
std::optional< StringRef > getPrinter() const
Get an optional C++ parameter printer.
StringRef getConvertFromStorage() const
Get the C++ code to convert from the storage type to the parameter type.
std::optional< StringRef > getDefaultValue() const
Get the default value of the parameter if it has one.
bool isAnonymous() const
Returns true if the parameter is anonymous (has no name).
std::string getAccessorName() const
Get the parameter accessor name.
StringRef getCppType() const
Get the C++ type of this parameter.
std::optional< StringRef > getSummary() const
Get a description of this parameter for documentation purposes.
StringRef getCppStorageType() const
Get the C++ storage type of this parameter.
bool isOptional() const
Returns true if the parameter is optional.
std::optional< StringRef > getAllocator() const
If specified, get the custom allocator code for this parameter.
StringRef getCppAccessorType() const
Get the C++ accessor type of this parameter.
AttrOrTypeParameter(const llvm::DagInit *def, unsigned index)
static bool classof(const AttrOrTypeParameter *param)
This class represents a single parameter to a builder method.
Definition Builder.h:36
const llvm::Record * def
The TableGen definition of this builder.
Definition Builder.h:79
ArrayRef< Parameter > getParameters() const
Return a list of parameters used in this build method.
Definition Builder.h:68
static Trait create(const llvm::Init *init)
Definition Trait.cpp:26
AttrOrTypeDef(const llvm::Record *def)
StringRef getTypeName() const
Get the unique type name "dialect.typename".
static bool classof(const AttrOrTypeDef *def)
Include the generated interface declarations.