xref: /llvm-project/mlir/lib/TableGen/Attribute.cpp (revision 659192b1843c4af180700783caca4cdc7afa3eab)
1cde4d5a6SJacques Pienaar //===- Attribute.cpp - Attribute wrapper class ----------------------------===//
29b034f0bSLei Zhang //
330857107SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
456222a06SMehdi Amini // See https://llvm.org/LICENSE.txt for license information.
556222a06SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69b034f0bSLei Zhang //
756222a06SMehdi Amini //===----------------------------------------------------------------------===//
89b034f0bSLei Zhang //
99b034f0bSLei Zhang // Attribute wrapper to simplify using TableGen Record defining a MLIR
109b034f0bSLei Zhang // Attribute.
119b034f0bSLei Zhang //
129b034f0bSLei Zhang //===----------------------------------------------------------------------===//
139b034f0bSLei Zhang 
14138c972dSLei Zhang #include "mlir/TableGen/Format.h"
159b034f0bSLei Zhang #include "mlir/TableGen/Operator.h"
169b034f0bSLei Zhang #include "llvm/TableGen/Record.h"
179b034f0bSLei Zhang 
189b034f0bSLei Zhang using namespace mlir;
1912d16de5SRahul Joshi using namespace mlir::tblgen;
209b034f0bSLei Zhang 
21138c972dSLei Zhang using llvm::DefInit;
22138c972dSLei Zhang using llvm::Init;
23138c972dSLei Zhang using llvm::Record;
24138c972dSLei Zhang using llvm::StringInit;
25138c972dSLei Zhang 
269b034f0bSLei Zhang // Returns the initializer's value as string if the given TableGen initializer
279b034f0bSLei Zhang // is a code or string initializer. Returns the empty StringRef otherwise.
28138c972dSLei Zhang static StringRef getValueAsString(const Init *init) {
2912d16de5SRahul Joshi   if (const auto *str = dyn_cast<StringInit>(init))
309b034f0bSLei Zhang     return str->getValue().trim();
319b034f0bSLei Zhang   return {};
329b034f0bSLei Zhang }
339b034f0bSLei Zhang 
3412d16de5SRahul Joshi bool AttrConstraint::isSubClassOf(StringRef className) const {
35aa9dc944SLei Zhang   return def->isSubClassOf(className);
36aa9dc944SLei Zhang }
37aa9dc944SLei Zhang 
3812d16de5SRahul Joshi Attribute::Attribute(const Record *record) : AttrConstraint(record) {
390fbf4ff2SJacques Pienaar   assert(record->isSubClassOf("Attr") &&
409b034f0bSLei Zhang          "must be subclass of TableGen 'Attr' class");
419b034f0bSLei Zhang }
429b034f0bSLei Zhang 
4312d16de5SRahul Joshi Attribute::Attribute(const DefInit *init) : Attribute(init->getDef()) {}
449b034f0bSLei Zhang 
4512d16de5SRahul Joshi bool Attribute::isDerivedAttr() const { return isSubClassOf("DerivedAttr"); }
469b034f0bSLei Zhang 
4712d16de5SRahul Joshi bool Attribute::isTypeAttr() const { return isSubClassOf("TypeAttrBase"); }
48c489f50eSFeng Liu 
49c0958b7bSRiver Riddle bool Attribute::isSymbolRefAttr() const {
50c0958b7bSRiver Riddle   StringRef defName = def->getName();
51c0958b7bSRiver Riddle   if (defName == "SymbolRefAttr" || defName == "FlatSymbolRefAttr")
52c0958b7bSRiver Riddle     return true;
53c0958b7bSRiver Riddle   return isSubClassOf("SymbolRefAttr") || isSubClassOf("FlatSymbolRefAttr");
54c0958b7bSRiver Riddle }
55c0958b7bSRiver Riddle 
5612d16de5SRahul Joshi bool Attribute::isEnumAttr() const { return isSubClassOf("EnumAttrInfo"); }
57c6cfebf1SMahesh Ravishankar 
5812d16de5SRahul Joshi StringRef Attribute::getStorageType() const {
59a5827fc9SJacques Pienaar   const auto *init = def->getValueInit("storageType");
609b034f0bSLei Zhang   auto type = getValueAsString(init);
619b034f0bSLei Zhang   if (type.empty())
620235e3c7SMarkus Böck     return "::mlir::Attribute";
639b034f0bSLei Zhang   return type;
649b034f0bSLei Zhang }
659b034f0bSLei Zhang 
6612d16de5SRahul Joshi StringRef Attribute::getReturnType() const {
67a5827fc9SJacques Pienaar   const auto *init = def->getValueInit("returnType");
689b034f0bSLei Zhang   return getValueAsString(init);
699b034f0bSLei Zhang }
709b034f0bSLei Zhang 
711b2c16f2SRiver Riddle // Return the type constraint corresponding to the type of this attribute, or
724f81805aSKazu Hirata // std::nullopt if this is not a TypedAttr.
733cfe412eSFangrui Song std::optional<Type> Attribute::getValueType() const {
74*659192b1SRahul Joshi   if (const auto *defInit = dyn_cast<DefInit>(def->getValueInit("valueType")))
7512d16de5SRahul Joshi     return Type(defInit->getDef());
761a36588eSKazu Hirata   return std::nullopt;
771b2c16f2SRiver Riddle }
781b2c16f2SRiver Riddle 
7912d16de5SRahul Joshi StringRef Attribute::getConvertFromStorageCall() const {
80a5827fc9SJacques Pienaar   const auto *init = def->getValueInit("convertFromStorage");
819b034f0bSLei Zhang   return getValueAsString(init);
829b034f0bSLei Zhang }
839b034f0bSLei Zhang 
8412d16de5SRahul Joshi bool Attribute::isConstBuildable() const {
85a5827fc9SJacques Pienaar   const auto *init = def->getValueInit("constBuilderCall");
86bd161ae5SAlex Zinenko   return !getValueAsString(init).empty();
87bd161ae5SAlex Zinenko }
88bd161ae5SAlex Zinenko 
8912d16de5SRahul Joshi StringRef Attribute::getConstBuilderTemplate() const {
90a5827fc9SJacques Pienaar   const auto *init = def->getValueInit("constBuilderCall");
91bd161ae5SAlex Zinenko   return getValueAsString(init);
92bd161ae5SAlex Zinenko }
93bd161ae5SAlex Zinenko 
9412d16de5SRahul Joshi Attribute Attribute::getBaseAttr() const {
95*659192b1SRahul Joshi   if (const auto *defInit = dyn_cast<DefInit>(def->getValueInit("baseAttr"))) {
96765b77ccSLei Zhang     return Attribute(defInit).getBaseAttr();
97765b77ccSLei Zhang   }
98765b77ccSLei Zhang   return *this;
99765b77ccSLei Zhang }
100765b77ccSLei Zhang 
10112d16de5SRahul Joshi bool Attribute::hasDefaultValue() const {
10234c6f8c6SJacques Pienaar   const auto *init = def->getValueInit("defaultValue");
10334c6f8c6SJacques Pienaar   return !getValueAsString(init).empty();
10434c6f8c6SJacques Pienaar }
10534c6f8c6SJacques Pienaar 
10612d16de5SRahul Joshi StringRef Attribute::getDefaultValue() const {
107138c972dSLei Zhang   const auto *init = def->getValueInit("defaultValue");
108138c972dSLei Zhang   return getValueAsString(init);
109c81b16e2SStella Laurenzo }
110c81b16e2SStella Laurenzo 
11112d16de5SRahul Joshi bool Attribute::isOptional() const { return def->getValueAsBit("isOptional"); }
11234c6f8c6SJacques Pienaar 
11312d16de5SRahul Joshi StringRef Attribute::getAttrDefName() const {
114765b77ccSLei Zhang   if (def->isAnonymous()) {
115765b77ccSLei Zhang     return getBaseAttr().def->getName();
116765b77ccSLei Zhang   }
117a5827fc9SJacques Pienaar   return def->getName();
118bd161ae5SAlex Zinenko }
119bd161ae5SAlex Zinenko 
12012d16de5SRahul Joshi StringRef Attribute::getDerivedCodeBody() const {
1219b034f0bSLei Zhang   assert(isDerivedAttr() && "only derived attribute has 'body' field");
122a5827fc9SJacques Pienaar   return def->getValueAsString("body");
1239b034f0bSLei Zhang }
124e0774c00SLei Zhang 
12512d16de5SRahul Joshi Dialect Attribute::getDialect() const {
126a3942308SFederico Lebrón   const llvm::RecordVal *record = def->getValue("dialect");
127a3942308SFederico Lebrón   if (record && record->getValue()) {
128e768b076SRahul Joshi     if (const DefInit *init = dyn_cast<DefInit>(record->getValue()))
129a3942308SFederico Lebrón       return Dialect(init->getDef());
130a3942308SFederico Lebrón   }
131a3942308SFederico Lebrón   return Dialect(nullptr);
132429d792fSRiver Riddle }
133429d792fSRiver Riddle 
134*659192b1SRahul Joshi const Record &Attribute::getDef() const { return *def; }
135a29fffc4SLei Zhang 
13612d16de5SRahul Joshi ConstantAttr::ConstantAttr(const DefInit *init) : def(init->getDef()) {
137e0774c00SLei Zhang   assert(def->isSubClassOf("ConstantAttr") &&
138e0774c00SLei Zhang          "must be subclass of TableGen 'ConstantAttr' class");
139e0774c00SLei Zhang }
140e0774c00SLei Zhang 
14112d16de5SRahul Joshi Attribute ConstantAttr::getAttribute() const {
142e0774c00SLei Zhang   return Attribute(def->getValueAsDef("attr"));
143e0774c00SLei Zhang }
144e0774c00SLei Zhang 
14512d16de5SRahul Joshi StringRef ConstantAttr::getConstantValue() const {
146e0774c00SLei Zhang   return def->getValueAsString("value");
147e0774c00SLei Zhang }
148b9e38a79SLei Zhang 
149*659192b1SRahul Joshi EnumAttrCase::EnumAttrCase(const Record *record) : Attribute(record) {
150aa9dc944SLei Zhang   assert(isSubClassOf("EnumAttrCaseInfo") &&
1519dd182e0SLei Zhang          "must be subclass of TableGen 'EnumAttrInfo' class");
1529dd182e0SLei Zhang }
1539dd182e0SLei Zhang 
154*659192b1SRahul Joshi EnumAttrCase::EnumAttrCase(const DefInit *init)
155267483acSLei Zhang     : EnumAttrCase(init->getDef()) {}
156267483acSLei Zhang 
15712d16de5SRahul Joshi StringRef EnumAttrCase::getSymbol() const {
158b9e38a79SLei Zhang   return def->getValueAsString("symbol");
159b9e38a79SLei Zhang }
160b9e38a79SLei Zhang 
16112d16de5SRahul Joshi StringRef EnumAttrCase::getStr() const { return def->getValueAsString("str"); }
162fdc496a3SAlex Zinenko 
16312d16de5SRahul Joshi int64_t EnumAttrCase::getValue() const { return def->getValueAsInt("value"); }
1641be9fc66SLei Zhang 
165*659192b1SRahul Joshi const Record &EnumAttrCase::getDef() const { return *def; }
166a81cb1b8SLei Zhang 
167*659192b1SRahul Joshi EnumAttr::EnumAttr(const Record *record) : Attribute(record) {
168aa9dc944SLei Zhang   assert(isSubClassOf("EnumAttrInfo") &&
169b9e38a79SLei Zhang          "must be subclass of TableGen 'EnumAttr' class");
170b9e38a79SLei Zhang }
171b9e38a79SLei Zhang 
172*659192b1SRahul Joshi EnumAttr::EnumAttr(const Record &record) : Attribute(&record) {}
1731be9fc66SLei Zhang 
174*659192b1SRahul Joshi EnumAttr::EnumAttr(const DefInit *init) : EnumAttr(init->getDef()) {}
175b9e38a79SLei Zhang 
17612d16de5SRahul Joshi bool EnumAttr::classof(const Attribute *attr) {
177a81cb1b8SLei Zhang   return attr->isSubClassOf("EnumAttrInfo");
178a81cb1b8SLei Zhang }
179a81cb1b8SLei Zhang 
18012d16de5SRahul Joshi bool EnumAttr::isBitEnum() const { return isSubClassOf("BitEnumAttr"); }
1816934a337SLei Zhang 
18212d16de5SRahul Joshi StringRef EnumAttr::getEnumClassName() const {
183b9e38a79SLei Zhang   return def->getValueAsString("className");
184b9e38a79SLei Zhang }
185b9e38a79SLei Zhang 
18612d16de5SRahul Joshi StringRef EnumAttr::getCppNamespace() const {
1871be9fc66SLei Zhang   return def->getValueAsString("cppNamespace");
1881be9fc66SLei Zhang }
1891be9fc66SLei Zhang 
19012d16de5SRahul Joshi StringRef EnumAttr::getUnderlyingType() const {
1911be9fc66SLei Zhang   return def->getValueAsString("underlyingType");
1921be9fc66SLei Zhang }
1931be9fc66SLei Zhang 
19412d16de5SRahul Joshi StringRef EnumAttr::getUnderlyingToSymbolFnName() const {
1958f77d2afSLei Zhang   return def->getValueAsString("underlyingToSymbolFnName");
1968f77d2afSLei Zhang }
1978f77d2afSLei Zhang 
19812d16de5SRahul Joshi StringRef EnumAttr::getStringToSymbolFnName() const {
1991be9fc66SLei Zhang   return def->getValueAsString("stringToSymbolFnName");
2001be9fc66SLei Zhang }
2011be9fc66SLei Zhang 
20212d16de5SRahul Joshi StringRef EnumAttr::getSymbolToStringFnName() const {
2031be9fc66SLei Zhang   return def->getValueAsString("symbolToStringFnName");
2041be9fc66SLei Zhang }
2051be9fc66SLei Zhang 
20612d16de5SRahul Joshi StringRef EnumAttr::getSymbolToStringFnRetType() const {
2076934a337SLei Zhang   return def->getValueAsString("symbolToStringFnRetType");
2086934a337SLei Zhang }
2096934a337SLei Zhang 
21012d16de5SRahul Joshi StringRef EnumAttr::getMaxEnumValFnName() const {
211d7ba69e8SMahesh Ravishankar   return def->getValueAsString("maxEnumValFnName");
212d7ba69e8SMahesh Ravishankar }
213d7ba69e8SMahesh Ravishankar 
21412d16de5SRahul Joshi std::vector<EnumAttrCase> EnumAttr::getAllCases() const {
215b9e38a79SLei Zhang   const auto *inits = def->getValueAsListInit("enumerants");
216b9e38a79SLei Zhang 
21712d16de5SRahul Joshi   std::vector<EnumAttrCase> cases;
218b9e38a79SLei Zhang   cases.reserve(inits->size());
219b9e38a79SLei Zhang 
220*659192b1SRahul Joshi   for (const Init *init : *inits) {
221*659192b1SRahul Joshi     cases.emplace_back(cast<DefInit>(init));
222b9e38a79SLei Zhang   }
223b9e38a79SLei Zhang 
224b9e38a79SLei Zhang   return cases;
225b9e38a79SLei Zhang }
2268f90a442SRob Suderman 
227fee90542SVladislav Vinogradov bool EnumAttr::genSpecializedAttr() const {
228fee90542SVladislav Vinogradov   return def->getValueAsBit("genSpecializedAttr");
229fee90542SVladislav Vinogradov }
230fee90542SVladislav Vinogradov 
231*659192b1SRahul Joshi const Record *EnumAttr::getBaseAttrClass() const {
232fee90542SVladislav Vinogradov   return def->getValueAsDef("baseAttrClass");
233fee90542SVladislav Vinogradov }
234fee90542SVladislav Vinogradov 
235fee90542SVladislav Vinogradov StringRef EnumAttr::getSpecializedAttrClassName() const {
236fee90542SVladislav Vinogradov   return def->getValueAsString("specializedAttrClassName");
237fee90542SVladislav Vinogradov }
238fee90542SVladislav Vinogradov 
2394e5dee2fSjfurtek bool EnumAttr::printBitEnumPrimaryGroups() const {
2404e5dee2fSjfurtek   return def->getValueAsBit("printBitEnumPrimaryGroups");
2414e5dee2fSjfurtek }
2424e5dee2fSjfurtek 
24312d16de5SRahul Joshi const char * ::mlir::tblgen::inferTypeOpInterface = "InferTypeOpInterface";
244