1 //===- Attribute.cpp - Attribute wrapper class ----------------------------===// 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 // 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 // Return the type constraint corresponding to the type of this attribute, or 79 // None if this is not a TypedAttr. 80 llvm::Optional<tblgen::Type> tblgen::Attribute::getValueType() const { 81 if (auto *defInit = dyn_cast<llvm::DefInit>(def->getValueInit("valueType"))) 82 return tblgen::Type(defInit->getDef()); 83 return llvm::None; 84 } 85 86 StringRef tblgen::Attribute::getConvertFromStorageCall() const { 87 const auto *init = def->getValueInit("convertFromStorage"); 88 return getValueAsString(init); 89 } 90 91 bool tblgen::Attribute::isConstBuildable() const { 92 const auto *init = def->getValueInit("constBuilderCall"); 93 return !getValueAsString(init).empty(); 94 } 95 96 StringRef tblgen::Attribute::getConstBuilderTemplate() const { 97 const auto *init = def->getValueInit("constBuilderCall"); 98 return getValueAsString(init); 99 } 100 101 tblgen::Attribute tblgen::Attribute::getBaseAttr() const { 102 if (const auto *defInit = 103 llvm::dyn_cast<llvm::DefInit>(def->getValueInit("baseAttr"))) { 104 return Attribute(defInit).getBaseAttr(); 105 } 106 return *this; 107 } 108 109 bool tblgen::Attribute::hasDefaultValue() const { 110 const auto *init = def->getValueInit("defaultValue"); 111 return !getValueAsString(init).empty(); 112 } 113 114 StringRef tblgen::Attribute::getDefaultValue() const { 115 const auto *init = def->getValueInit("defaultValue"); 116 return getValueAsString(init); 117 } 118 119 bool tblgen::Attribute::isOptional() const { 120 return def->getValueAsBit("isOptional"); 121 } 122 123 StringRef tblgen::Attribute::getAttrDefName() const { 124 if (def->isAnonymous()) { 125 return getBaseAttr().def->getName(); 126 } 127 return def->getName(); 128 } 129 130 StringRef tblgen::Attribute::getDerivedCodeBody() const { 131 assert(isDerivedAttr() && "only derived attribute has 'body' field"); 132 return def->getValueAsString("body"); 133 } 134 135 tblgen::Dialect tblgen::Attribute::getDialect() const { 136 return Dialect(def->getValueAsDef("dialect")); 137 } 138 139 tblgen::ConstantAttr::ConstantAttr(const DefInit *init) : def(init->getDef()) { 140 assert(def->isSubClassOf("ConstantAttr") && 141 "must be subclass of TableGen 'ConstantAttr' class"); 142 } 143 144 tblgen::Attribute tblgen::ConstantAttr::getAttribute() const { 145 return Attribute(def->getValueAsDef("attr")); 146 } 147 148 StringRef tblgen::ConstantAttr::getConstantValue() const { 149 return def->getValueAsString("value"); 150 } 151 152 tblgen::EnumAttrCase::EnumAttrCase(const llvm::Record *record) 153 : Attribute(record) { 154 assert(isSubClassOf("EnumAttrCaseInfo") && 155 "must be subclass of TableGen 'EnumAttrInfo' class"); 156 } 157 158 tblgen::EnumAttrCase::EnumAttrCase(const llvm::DefInit *init) 159 : EnumAttrCase(init->getDef()) {} 160 161 bool tblgen::EnumAttrCase::isStrCase() const { 162 return isSubClassOf("StrEnumAttrCase"); 163 } 164 165 StringRef tblgen::EnumAttrCase::getSymbol() const { 166 return def->getValueAsString("symbol"); 167 } 168 169 StringRef tblgen::EnumAttrCase::getStr() const { 170 return def->getValueAsString("str"); 171 } 172 173 int64_t tblgen::EnumAttrCase::getValue() const { 174 return def->getValueAsInt("value"); 175 } 176 177 const llvm::Record &tblgen::EnumAttrCase::getDef() const { return *def; } 178 179 tblgen::EnumAttr::EnumAttr(const llvm::Record *record) : Attribute(record) { 180 assert(isSubClassOf("EnumAttrInfo") && 181 "must be subclass of TableGen 'EnumAttr' class"); 182 } 183 184 tblgen::EnumAttr::EnumAttr(const llvm::Record &record) : Attribute(&record) {} 185 186 tblgen::EnumAttr::EnumAttr(const llvm::DefInit *init) 187 : EnumAttr(init->getDef()) {} 188 189 bool tblgen::EnumAttr::classof(const Attribute *attr) { 190 return attr->isSubClassOf("EnumAttrInfo"); 191 } 192 193 bool tblgen::EnumAttr::isBitEnum() const { return isSubClassOf("BitEnumAttr"); } 194 195 StringRef tblgen::EnumAttr::getEnumClassName() const { 196 return def->getValueAsString("className"); 197 } 198 199 StringRef tblgen::EnumAttr::getCppNamespace() const { 200 return def->getValueAsString("cppNamespace"); 201 } 202 203 StringRef tblgen::EnumAttr::getUnderlyingType() const { 204 return def->getValueAsString("underlyingType"); 205 } 206 207 StringRef tblgen::EnumAttr::getUnderlyingToSymbolFnName() const { 208 return def->getValueAsString("underlyingToSymbolFnName"); 209 } 210 211 StringRef tblgen::EnumAttr::getStringToSymbolFnName() const { 212 return def->getValueAsString("stringToSymbolFnName"); 213 } 214 215 StringRef tblgen::EnumAttr::getSymbolToStringFnName() const { 216 return def->getValueAsString("symbolToStringFnName"); 217 } 218 219 StringRef tblgen::EnumAttr::getSymbolToStringFnRetType() const { 220 return def->getValueAsString("symbolToStringFnRetType"); 221 } 222 223 StringRef tblgen::EnumAttr::getMaxEnumValFnName() const { 224 return def->getValueAsString("maxEnumValFnName"); 225 } 226 227 std::vector<tblgen::EnumAttrCase> tblgen::EnumAttr::getAllCases() const { 228 const auto *inits = def->getValueAsListInit("enumerants"); 229 230 std::vector<tblgen::EnumAttrCase> cases; 231 cases.reserve(inits->size()); 232 233 for (const llvm::Init *init : *inits) { 234 cases.push_back(tblgen::EnumAttrCase(cast<llvm::DefInit>(init))); 235 } 236 237 return cases; 238 } 239 240 tblgen::StructFieldAttr::StructFieldAttr(const llvm::Record *record) 241 : def(record) { 242 assert(def->isSubClassOf("StructFieldAttr") && 243 "must be subclass of TableGen 'StructFieldAttr' class"); 244 } 245 246 tblgen::StructFieldAttr::StructFieldAttr(const llvm::Record &record) 247 : StructFieldAttr(&record) {} 248 249 tblgen::StructFieldAttr::StructFieldAttr(const llvm::DefInit *init) 250 : StructFieldAttr(init->getDef()) {} 251 252 StringRef tblgen::StructFieldAttr::getName() const { 253 return def->getValueAsString("name"); 254 } 255 256 tblgen::Attribute tblgen::StructFieldAttr::getType() const { 257 auto init = def->getValueInit("type"); 258 return tblgen::Attribute(cast<llvm::DefInit>(init)); 259 } 260 261 tblgen::StructAttr::StructAttr(const llvm::Record *record) : Attribute(record) { 262 assert(isSubClassOf("StructAttr") && 263 "must be subclass of TableGen 'StructAttr' class"); 264 } 265 266 tblgen::StructAttr::StructAttr(const llvm::DefInit *init) 267 : StructAttr(init->getDef()) {} 268 269 StringRef tblgen::StructAttr::getStructClassName() const { 270 return def->getValueAsString("className"); 271 } 272 273 StringRef tblgen::StructAttr::getCppNamespace() const { 274 Dialect dialect(def->getValueAsDef("structDialect")); 275 return dialect.getCppNamespace(); 276 } 277 278 std::vector<mlir::tblgen::StructFieldAttr> 279 tblgen::StructAttr::getAllFields() const { 280 std::vector<mlir::tblgen::StructFieldAttr> attributes; 281 282 const auto *inits = def->getValueAsListInit("fields"); 283 attributes.reserve(inits->size()); 284 285 for (const llvm::Init *init : *inits) { 286 attributes.emplace_back(cast<llvm::DefInit>(init)); 287 } 288 289 return attributes; 290 } 291