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.
getValueAsString(const Init * init)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 
isSubClassOf(StringRef className) const3412d16de5SRahul Joshi bool AttrConstraint::isSubClassOf(StringRef className) const {
35aa9dc944SLei Zhang   return def->isSubClassOf(className);
36aa9dc944SLei Zhang }
37aa9dc944SLei Zhang 
Attribute(const Record * record)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 
Attribute(const DefInit * init)4312d16de5SRahul Joshi Attribute::Attribute(const DefInit *init) : Attribute(init->getDef()) {}
449b034f0bSLei Zhang 
isDerivedAttr() const4512d16de5SRahul Joshi bool Attribute::isDerivedAttr() const { return isSubClassOf("DerivedAttr"); }
469b034f0bSLei Zhang 
isTypeAttr() const4712d16de5SRahul Joshi bool Attribute::isTypeAttr() const { return isSubClassOf("TypeAttrBase"); }
48c489f50eSFeng Liu 
isSymbolRefAttr() const49c0958b7bSRiver 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 
isEnumAttr() const5612d16de5SRahul Joshi bool Attribute::isEnumAttr() const { return isSubClassOf("EnumAttrInfo"); }
57c6cfebf1SMahesh Ravishankar 
getStorageType() const5812d16de5SRahul 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 
getReturnType() const6612d16de5SRahul 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
721b2c16f2SRiver Riddle // None if this is not a TypedAttr.
getValueType() const7312d16de5SRahul Joshi llvm::Optional<Type> Attribute::getValueType() const {
741b2c16f2SRiver Riddle   if (auto *defInit = dyn_cast<llvm::DefInit>(def->getValueInit("valueType")))
7512d16de5SRahul Joshi     return Type(defInit->getDef());
761b2c16f2SRiver Riddle   return llvm::None;
771b2c16f2SRiver Riddle }
781b2c16f2SRiver Riddle 
getConvertFromStorageCall() const7912d16de5SRahul Joshi StringRef Attribute::getConvertFromStorageCall() const {
80a5827fc9SJacques Pienaar   const auto *init = def->getValueInit("convertFromStorage");
819b034f0bSLei Zhang   return getValueAsString(init);
829b034f0bSLei Zhang }
839b034f0bSLei Zhang 
isConstBuildable() const8412d16de5SRahul Joshi bool Attribute::isConstBuildable() const {
85a5827fc9SJacques Pienaar   const auto *init = def->getValueInit("constBuilderCall");
86bd161ae5SAlex Zinenko   return !getValueAsString(init).empty();
87bd161ae5SAlex Zinenko }
88bd161ae5SAlex Zinenko 
getConstBuilderTemplate() const8912d16de5SRahul Joshi StringRef Attribute::getConstBuilderTemplate() const {
90a5827fc9SJacques Pienaar   const auto *init = def->getValueInit("constBuilderCall");
91bd161ae5SAlex Zinenko   return getValueAsString(init);
92bd161ae5SAlex Zinenko }
93bd161ae5SAlex Zinenko 
getBaseAttr() const9412d16de5SRahul Joshi Attribute Attribute::getBaseAttr() const {
95765b77ccSLei Zhang   if (const auto *defInit =
96765b77ccSLei Zhang           llvm::dyn_cast<llvm::DefInit>(def->getValueInit("baseAttr"))) {
97765b77ccSLei Zhang     return Attribute(defInit).getBaseAttr();
98765b77ccSLei Zhang   }
99765b77ccSLei Zhang   return *this;
100765b77ccSLei Zhang }
101765b77ccSLei Zhang 
hasDefaultValue() const10212d16de5SRahul Joshi bool Attribute::hasDefaultValue() const {
10334c6f8c6SJacques Pienaar   const auto *init = def->getValueInit("defaultValue");
10434c6f8c6SJacques Pienaar   return !getValueAsString(init).empty();
10534c6f8c6SJacques Pienaar }
10634c6f8c6SJacques Pienaar 
getDefaultValue() const10712d16de5SRahul Joshi StringRef Attribute::getDefaultValue() const {
108138c972dSLei Zhang   const auto *init = def->getValueInit("defaultValue");
109138c972dSLei Zhang   return getValueAsString(init);
110c81b16e2SStella Laurenzo }
111c81b16e2SStella Laurenzo 
isOptional() const11212d16de5SRahul Joshi bool Attribute::isOptional() const { return def->getValueAsBit("isOptional"); }
11334c6f8c6SJacques Pienaar 
getAttrDefName() const11412d16de5SRahul Joshi StringRef Attribute::getAttrDefName() const {
115765b77ccSLei Zhang   if (def->isAnonymous()) {
116765b77ccSLei Zhang     return getBaseAttr().def->getName();
117765b77ccSLei Zhang   }
118a5827fc9SJacques Pienaar   return def->getName();
119bd161ae5SAlex Zinenko }
120bd161ae5SAlex Zinenko 
getDerivedCodeBody() const12112d16de5SRahul Joshi StringRef Attribute::getDerivedCodeBody() const {
1229b034f0bSLei Zhang   assert(isDerivedAttr() && "only derived attribute has 'body' field");
123a5827fc9SJacques Pienaar   return def->getValueAsString("body");
1249b034f0bSLei Zhang }
125e0774c00SLei Zhang 
getDialect() const12612d16de5SRahul Joshi Dialect Attribute::getDialect() const {
127a3942308SFederico Lebrón   const llvm::RecordVal *record = def->getValue("dialect");
128a3942308SFederico Lebrón   if (record && record->getValue()) {
129a3942308SFederico Lebrón     if (DefInit *init = dyn_cast<DefInit>(record->getValue()))
130a3942308SFederico Lebrón       return Dialect(init->getDef());
131a3942308SFederico Lebrón   }
132a3942308SFederico Lebrón   return Dialect(nullptr);
133429d792fSRiver Riddle }
134429d792fSRiver Riddle 
ConstantAttr(const DefInit * init)13512d16de5SRahul Joshi ConstantAttr::ConstantAttr(const DefInit *init) : def(init->getDef()) {
136e0774c00SLei Zhang   assert(def->isSubClassOf("ConstantAttr") &&
137e0774c00SLei Zhang          "must be subclass of TableGen 'ConstantAttr' class");
138e0774c00SLei Zhang }
139e0774c00SLei Zhang 
getAttribute() const14012d16de5SRahul Joshi Attribute ConstantAttr::getAttribute() const {
141e0774c00SLei Zhang   return Attribute(def->getValueAsDef("attr"));
142e0774c00SLei Zhang }
143e0774c00SLei Zhang 
getConstantValue() const14412d16de5SRahul Joshi StringRef ConstantAttr::getConstantValue() const {
145e0774c00SLei Zhang   return def->getValueAsString("value");
146e0774c00SLei Zhang }
147b9e38a79SLei Zhang 
EnumAttrCase(const llvm::Record * record)14812d16de5SRahul Joshi EnumAttrCase::EnumAttrCase(const llvm::Record *record) : Attribute(record) {
149aa9dc944SLei Zhang   assert(isSubClassOf("EnumAttrCaseInfo") &&
1509dd182e0SLei Zhang          "must be subclass of TableGen 'EnumAttrInfo' class");
1519dd182e0SLei Zhang }
1529dd182e0SLei Zhang 
EnumAttrCase(const llvm::DefInit * init)15312d16de5SRahul Joshi EnumAttrCase::EnumAttrCase(const llvm::DefInit *init)
154267483acSLei Zhang     : EnumAttrCase(init->getDef()) {}
155267483acSLei Zhang 
getSymbol() const15612d16de5SRahul Joshi StringRef EnumAttrCase::getSymbol() const {
157b9e38a79SLei Zhang   return def->getValueAsString("symbol");
158b9e38a79SLei Zhang }
159b9e38a79SLei Zhang 
getStr() const16012d16de5SRahul Joshi StringRef EnumAttrCase::getStr() const { return def->getValueAsString("str"); }
161fdc496a3SAlex Zinenko 
getValue() const16212d16de5SRahul Joshi int64_t EnumAttrCase::getValue() const { return def->getValueAsInt("value"); }
1631be9fc66SLei Zhang 
getDef() const16412d16de5SRahul Joshi const llvm::Record &EnumAttrCase::getDef() const { return *def; }
165a81cb1b8SLei Zhang 
EnumAttr(const llvm::Record * record)16612d16de5SRahul Joshi EnumAttr::EnumAttr(const llvm::Record *record) : Attribute(record) {
167aa9dc944SLei Zhang   assert(isSubClassOf("EnumAttrInfo") &&
168b9e38a79SLei Zhang          "must be subclass of TableGen 'EnumAttr' class");
169b9e38a79SLei Zhang }
170b9e38a79SLei Zhang 
EnumAttr(const llvm::Record & record)17112d16de5SRahul Joshi EnumAttr::EnumAttr(const llvm::Record &record) : Attribute(&record) {}
1721be9fc66SLei Zhang 
EnumAttr(const llvm::DefInit * init)17312d16de5SRahul Joshi EnumAttr::EnumAttr(const llvm::DefInit *init) : EnumAttr(init->getDef()) {}
174b9e38a79SLei Zhang 
classof(const Attribute * attr)17512d16de5SRahul Joshi bool EnumAttr::classof(const Attribute *attr) {
176a81cb1b8SLei Zhang   return attr->isSubClassOf("EnumAttrInfo");
177a81cb1b8SLei Zhang }
178a81cb1b8SLei Zhang 
isBitEnum() const17912d16de5SRahul Joshi bool EnumAttr::isBitEnum() const { return isSubClassOf("BitEnumAttr"); }
1806934a337SLei Zhang 
getEnumClassName() const18112d16de5SRahul Joshi StringRef EnumAttr::getEnumClassName() const {
182b9e38a79SLei Zhang   return def->getValueAsString("className");
183b9e38a79SLei Zhang }
184b9e38a79SLei Zhang 
getCppNamespace() const18512d16de5SRahul Joshi StringRef EnumAttr::getCppNamespace() const {
1861be9fc66SLei Zhang   return def->getValueAsString("cppNamespace");
1871be9fc66SLei Zhang }
1881be9fc66SLei Zhang 
getUnderlyingType() const18912d16de5SRahul Joshi StringRef EnumAttr::getUnderlyingType() const {
1901be9fc66SLei Zhang   return def->getValueAsString("underlyingType");
1911be9fc66SLei Zhang }
1921be9fc66SLei Zhang 
getUnderlyingToSymbolFnName() const19312d16de5SRahul Joshi StringRef EnumAttr::getUnderlyingToSymbolFnName() const {
1948f77d2afSLei Zhang   return def->getValueAsString("underlyingToSymbolFnName");
1958f77d2afSLei Zhang }
1968f77d2afSLei Zhang 
getStringToSymbolFnName() const19712d16de5SRahul Joshi StringRef EnumAttr::getStringToSymbolFnName() const {
1981be9fc66SLei Zhang   return def->getValueAsString("stringToSymbolFnName");
1991be9fc66SLei Zhang }
2001be9fc66SLei Zhang 
getSymbolToStringFnName() const20112d16de5SRahul Joshi StringRef EnumAttr::getSymbolToStringFnName() const {
2021be9fc66SLei Zhang   return def->getValueAsString("symbolToStringFnName");
2031be9fc66SLei Zhang }
2041be9fc66SLei Zhang 
getSymbolToStringFnRetType() const20512d16de5SRahul Joshi StringRef EnumAttr::getSymbolToStringFnRetType() const {
2066934a337SLei Zhang   return def->getValueAsString("symbolToStringFnRetType");
2076934a337SLei Zhang }
2086934a337SLei Zhang 
getMaxEnumValFnName() const20912d16de5SRahul Joshi StringRef EnumAttr::getMaxEnumValFnName() const {
210d7ba69e8SMahesh Ravishankar   return def->getValueAsString("maxEnumValFnName");
211d7ba69e8SMahesh Ravishankar }
212d7ba69e8SMahesh Ravishankar 
getAllCases() const21312d16de5SRahul Joshi std::vector<EnumAttrCase> EnumAttr::getAllCases() const {
214b9e38a79SLei Zhang   const auto *inits = def->getValueAsListInit("enumerants");
215b9e38a79SLei Zhang 
21612d16de5SRahul Joshi   std::vector<EnumAttrCase> cases;
217b9e38a79SLei Zhang   cases.reserve(inits->size());
218b9e38a79SLei Zhang 
219b9e38a79SLei Zhang   for (const llvm::Init *init : *inits) {
220e5639b3fSMehdi Amini     cases.emplace_back(cast<llvm::DefInit>(init));
221b9e38a79SLei Zhang   }
222b9e38a79SLei Zhang 
223b9e38a79SLei Zhang   return cases;
224b9e38a79SLei Zhang }
2258f90a442SRob Suderman 
genSpecializedAttr() const226fee90542SVladislav Vinogradov bool EnumAttr::genSpecializedAttr() const {
227fee90542SVladislav Vinogradov   return def->getValueAsBit("genSpecializedAttr");
228fee90542SVladislav Vinogradov }
229fee90542SVladislav Vinogradov 
getBaseAttrClass() const230fee90542SVladislav Vinogradov llvm::Record *EnumAttr::getBaseAttrClass() const {
231fee90542SVladislav Vinogradov   return def->getValueAsDef("baseAttrClass");
232fee90542SVladislav Vinogradov }
233fee90542SVladislav Vinogradov 
getSpecializedAttrClassName() const234fee90542SVladislav Vinogradov StringRef EnumAttr::getSpecializedAttrClassName() const {
235fee90542SVladislav Vinogradov   return def->getValueAsString("specializedAttrClassName");
236fee90542SVladislav Vinogradov }
237fee90542SVladislav Vinogradov 
printBitEnumPrimaryGroups() const238*4e5dee2fSjfurtek bool EnumAttr::printBitEnumPrimaryGroups() const {
239*4e5dee2fSjfurtek   return def->getValueAsBit("printBitEnumPrimaryGroups");
240*4e5dee2fSjfurtek }
241*4e5dee2fSjfurtek 
24212d16de5SRahul Joshi const char * ::mlir::tblgen::inferTypeOpInterface = "InferTypeOpInterface";
243