1 //===- Attribute.cpp - Attribute wrapper class ----------------------------===// 2 // 3 // Part of the MLIR 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 // Attribute wrapper to simplify using TableGen Record defining a MLIR 10 // Attribute. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "mlir/TableGen/Format.h" 15 #include "mlir/TableGen/Operator.h" 16 #include "llvm/TableGen/Record.h" 17 18 using namespace mlir; 19 20 using llvm::CodeInit; 21 using llvm::DefInit; 22 using llvm::Init; 23 using llvm::Record; 24 using llvm::StringInit; 25 26 // Returns the initializer's value as string if the given TableGen initializer 27 // is a code or string initializer. Returns the empty StringRef otherwise. 28 static StringRef getValueAsString(const Init *init) { 29 if (const auto *code = dyn_cast<CodeInit>(init)) 30 return code->getValue().trim(); 31 else if (const auto *str = dyn_cast<StringInit>(init)) 32 return str->getValue().trim(); 33 return {}; 34 } 35 36 tblgen::AttrConstraint::AttrConstraint(const Record *record) 37 : Constraint(Constraint::CK_Attr, record) { 38 assert(isSubClassOf("AttrConstraint") && 39 "must be subclass of TableGen 'AttrConstraint' class"); 40 } 41 42 bool tblgen::AttrConstraint::isSubClassOf(StringRef className) const { 43 return def->isSubClassOf(className); 44 } 45 46 tblgen::Attribute::Attribute(const Record *record) : AttrConstraint(record) { 47 assert(record->isSubClassOf("Attr") && 48 "must be subclass of TableGen 'Attr' class"); 49 } 50 51 tblgen::Attribute::Attribute(const DefInit *init) : Attribute(init->getDef()) {} 52 53 bool tblgen::Attribute::isDerivedAttr() const { 54 return isSubClassOf("DerivedAttr"); 55 } 56 57 bool tblgen::Attribute::isTypeAttr() const { 58 return isSubClassOf("TypeAttrBase"); 59 } 60 61 bool tblgen::Attribute::isEnumAttr() const { 62 return isSubClassOf("EnumAttrInfo"); 63 } 64 65 StringRef tblgen::Attribute::getStorageType() const { 66 const auto *init = def->getValueInit("storageType"); 67 auto type = getValueAsString(init); 68 if (type.empty()) 69 return "Attribute"; 70 return type; 71 } 72 73 StringRef tblgen::Attribute::getReturnType() const { 74 const auto *init = def->getValueInit("returnType"); 75 return getValueAsString(init); 76 } 77 78 StringRef tblgen::Attribute::getConvertFromStorageCall() const { 79 const auto *init = def->getValueInit("convertFromStorage"); 80 return getValueAsString(init); 81 } 82 83 bool tblgen::Attribute::isConstBuildable() const { 84 const auto *init = def->getValueInit("constBuilderCall"); 85 return !getValueAsString(init).empty(); 86 } 87 88 StringRef tblgen::Attribute::getConstBuilderTemplate() const { 89 const auto *init = def->getValueInit("constBuilderCall"); 90 return getValueAsString(init); 91 } 92 93 tblgen::Attribute tblgen::Attribute::getBaseAttr() const { 94 if (const auto *defInit = 95 llvm::dyn_cast<llvm::DefInit>(def->getValueInit("baseAttr"))) { 96 return Attribute(defInit).getBaseAttr(); 97 } 98 return *this; 99 } 100 101 bool tblgen::Attribute::hasDefaultValue() const { 102 const auto *init = def->getValueInit("defaultValue"); 103 return !getValueAsString(init).empty(); 104 } 105 106 StringRef tblgen::Attribute::getDefaultValue() const { 107 const auto *init = def->getValueInit("defaultValue"); 108 return getValueAsString(init); 109 } 110 111 bool tblgen::Attribute::isOptional() const { 112 return def->getValueAsBit("isOptional"); 113 } 114 115 StringRef tblgen::Attribute::getAttrDefName() const { 116 if (def->isAnonymous()) { 117 return getBaseAttr().def->getName(); 118 } 119 return def->getName(); 120 } 121 122 StringRef tblgen::Attribute::getDerivedCodeBody() const { 123 assert(isDerivedAttr() && "only derived attribute has 'body' field"); 124 return def->getValueAsString("body"); 125 } 126 127 tblgen::ConstantAttr::ConstantAttr(const DefInit *init) : def(init->getDef()) { 128 assert(def->isSubClassOf("ConstantAttr") && 129 "must be subclass of TableGen 'ConstantAttr' class"); 130 } 131 132 tblgen::Attribute tblgen::ConstantAttr::getAttribute() const { 133 return Attribute(def->getValueAsDef("attr")); 134 } 135 136 StringRef tblgen::ConstantAttr::getConstantValue() const { 137 return def->getValueAsString("value"); 138 } 139 140 tblgen::EnumAttrCase::EnumAttrCase(const llvm::DefInit *init) 141 : Attribute(init) { 142 assert(isSubClassOf("EnumAttrCaseInfo") && 143 "must be subclass of TableGen 'EnumAttrInfo' class"); 144 } 145 146 bool tblgen::EnumAttrCase::isStrCase() const { 147 return isSubClassOf("StrEnumAttrCase"); 148 } 149 150 StringRef tblgen::EnumAttrCase::getSymbol() const { 151 return def->getValueAsString("symbol"); 152 } 153 154 int64_t tblgen::EnumAttrCase::getValue() const { 155 return def->getValueAsInt("value"); 156 } 157 158 tblgen::EnumAttr::EnumAttr(const llvm::Record *record) : Attribute(record) { 159 assert(isSubClassOf("EnumAttrInfo") && 160 "must be subclass of TableGen 'EnumAttr' class"); 161 } 162 163 tblgen::EnumAttr::EnumAttr(const llvm::Record &record) : Attribute(&record) {} 164 165 tblgen::EnumAttr::EnumAttr(const llvm::DefInit *init) 166 : EnumAttr(init->getDef()) {} 167 168 bool tblgen::EnumAttr::isBitEnum() const { return isSubClassOf("BitEnumAttr"); } 169 170 StringRef tblgen::EnumAttr::getEnumClassName() const { 171 return def->getValueAsString("className"); 172 } 173 174 StringRef tblgen::EnumAttr::getCppNamespace() const { 175 return def->getValueAsString("cppNamespace"); 176 } 177 178 StringRef tblgen::EnumAttr::getUnderlyingType() const { 179 return def->getValueAsString("underlyingType"); 180 } 181 182 StringRef tblgen::EnumAttr::getUnderlyingToSymbolFnName() const { 183 return def->getValueAsString("underlyingToSymbolFnName"); 184 } 185 186 StringRef tblgen::EnumAttr::getStringToSymbolFnName() const { 187 return def->getValueAsString("stringToSymbolFnName"); 188 } 189 190 StringRef tblgen::EnumAttr::getSymbolToStringFnName() const { 191 return def->getValueAsString("symbolToStringFnName"); 192 } 193 194 StringRef tblgen::EnumAttr::getSymbolToStringFnRetType() const { 195 return def->getValueAsString("symbolToStringFnRetType"); 196 } 197 198 StringRef tblgen::EnumAttr::getMaxEnumValFnName() const { 199 return def->getValueAsString("maxEnumValFnName"); 200 } 201 202 std::vector<tblgen::EnumAttrCase> tblgen::EnumAttr::getAllCases() const { 203 const auto *inits = def->getValueAsListInit("enumerants"); 204 205 std::vector<tblgen::EnumAttrCase> cases; 206 cases.reserve(inits->size()); 207 208 for (const llvm::Init *init : *inits) { 209 cases.push_back(tblgen::EnumAttrCase(cast<llvm::DefInit>(init))); 210 } 211 212 return cases; 213 } 214 215 tblgen::StructFieldAttr::StructFieldAttr(const llvm::Record *record) 216 : def(record) { 217 assert(def->isSubClassOf("StructFieldAttr") && 218 "must be subclass of TableGen 'StructFieldAttr' class"); 219 } 220 221 tblgen::StructFieldAttr::StructFieldAttr(const llvm::Record &record) 222 : StructFieldAttr(&record) {} 223 224 tblgen::StructFieldAttr::StructFieldAttr(const llvm::DefInit *init) 225 : StructFieldAttr(init->getDef()) {} 226 227 StringRef tblgen::StructFieldAttr::getName() const { 228 return def->getValueAsString("name"); 229 } 230 231 tblgen::Attribute tblgen::StructFieldAttr::getType() const { 232 auto init = def->getValueInit("type"); 233 return tblgen::Attribute(cast<llvm::DefInit>(init)); 234 } 235 236 tblgen::StructAttr::StructAttr(const llvm::Record *record) : Attribute(record) { 237 assert(isSubClassOf("StructAttr") && 238 "must be subclass of TableGen 'StructAttr' class"); 239 } 240 241 tblgen::StructAttr::StructAttr(const llvm::DefInit *init) 242 : StructAttr(init->getDef()) {} 243 244 StringRef tblgen::StructAttr::getStructClassName() const { 245 return def->getValueAsString("className"); 246 } 247 248 StringRef tblgen::StructAttr::getCppNamespace() const { 249 Dialect dialect(def->getValueAsDef("structDialect")); 250 return dialect.getCppNamespace(); 251 } 252 253 std::vector<mlir::tblgen::StructFieldAttr> 254 tblgen::StructAttr::getAllFields() const { 255 std::vector<mlir::tblgen::StructFieldAttr> attributes; 256 257 const auto *inits = def->getValueAsListInit("fields"); 258 attributes.reserve(inits->size()); 259 260 for (const llvm::Init *init : *inits) { 261 attributes.emplace_back(cast<llvm::DefInit>(init)); 262 } 263 264 return attributes; 265 } 266