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::ConstantAttr::ConstantAttr(const DefInit *init) : def(init->getDef()) { 136 assert(def->isSubClassOf("ConstantAttr") && 137 "must be subclass of TableGen 'ConstantAttr' class"); 138 } 139 140 tblgen::Attribute tblgen::ConstantAttr::getAttribute() const { 141 return Attribute(def->getValueAsDef("attr")); 142 } 143 144 StringRef tblgen::ConstantAttr::getConstantValue() const { 145 return def->getValueAsString("value"); 146 } 147 148 tblgen::EnumAttrCase::EnumAttrCase(const llvm::Record *record) 149 : Attribute(record) { 150 assert(isSubClassOf("EnumAttrCaseInfo") && 151 "must be subclass of TableGen 'EnumAttrInfo' class"); 152 } 153 154 tblgen::EnumAttrCase::EnumAttrCase(const llvm::DefInit *init) 155 : EnumAttrCase(init->getDef()) {} 156 157 bool tblgen::EnumAttrCase::isStrCase() const { 158 return isSubClassOf("StrEnumAttrCase"); 159 } 160 161 StringRef tblgen::EnumAttrCase::getSymbol() const { 162 return def->getValueAsString("symbol"); 163 } 164 165 StringRef tblgen::EnumAttrCase::getStr() const { 166 return def->getValueAsString("str"); 167 } 168 169 int64_t tblgen::EnumAttrCase::getValue() const { 170 return def->getValueAsInt("value"); 171 } 172 173 const llvm::Record &tblgen::EnumAttrCase::getDef() const { return *def; } 174 175 tblgen::EnumAttr::EnumAttr(const llvm::Record *record) : Attribute(record) { 176 assert(isSubClassOf("EnumAttrInfo") && 177 "must be subclass of TableGen 'EnumAttr' class"); 178 } 179 180 tblgen::EnumAttr::EnumAttr(const llvm::Record &record) : Attribute(&record) {} 181 182 tblgen::EnumAttr::EnumAttr(const llvm::DefInit *init) 183 : EnumAttr(init->getDef()) {} 184 185 bool tblgen::EnumAttr::classof(const Attribute *attr) { 186 return attr->isSubClassOf("EnumAttrInfo"); 187 } 188 189 bool tblgen::EnumAttr::isBitEnum() const { return isSubClassOf("BitEnumAttr"); } 190 191 StringRef tblgen::EnumAttr::getEnumClassName() const { 192 return def->getValueAsString("className"); 193 } 194 195 StringRef tblgen::EnumAttr::getCppNamespace() const { 196 return def->getValueAsString("cppNamespace"); 197 } 198 199 StringRef tblgen::EnumAttr::getUnderlyingType() const { 200 return def->getValueAsString("underlyingType"); 201 } 202 203 StringRef tblgen::EnumAttr::getUnderlyingToSymbolFnName() const { 204 return def->getValueAsString("underlyingToSymbolFnName"); 205 } 206 207 StringRef tblgen::EnumAttr::getStringToSymbolFnName() const { 208 return def->getValueAsString("stringToSymbolFnName"); 209 } 210 211 StringRef tblgen::EnumAttr::getSymbolToStringFnName() const { 212 return def->getValueAsString("symbolToStringFnName"); 213 } 214 215 StringRef tblgen::EnumAttr::getSymbolToStringFnRetType() const { 216 return def->getValueAsString("symbolToStringFnRetType"); 217 } 218 219 StringRef tblgen::EnumAttr::getMaxEnumValFnName() const { 220 return def->getValueAsString("maxEnumValFnName"); 221 } 222 223 std::vector<tblgen::EnumAttrCase> tblgen::EnumAttr::getAllCases() const { 224 const auto *inits = def->getValueAsListInit("enumerants"); 225 226 std::vector<tblgen::EnumAttrCase> cases; 227 cases.reserve(inits->size()); 228 229 for (const llvm::Init *init : *inits) { 230 cases.push_back(tblgen::EnumAttrCase(cast<llvm::DefInit>(init))); 231 } 232 233 return cases; 234 } 235 236 tblgen::StructFieldAttr::StructFieldAttr(const llvm::Record *record) 237 : def(record) { 238 assert(def->isSubClassOf("StructFieldAttr") && 239 "must be subclass of TableGen 'StructFieldAttr' class"); 240 } 241 242 tblgen::StructFieldAttr::StructFieldAttr(const llvm::Record &record) 243 : StructFieldAttr(&record) {} 244 245 tblgen::StructFieldAttr::StructFieldAttr(const llvm::DefInit *init) 246 : StructFieldAttr(init->getDef()) {} 247 248 StringRef tblgen::StructFieldAttr::getName() const { 249 return def->getValueAsString("name"); 250 } 251 252 tblgen::Attribute tblgen::StructFieldAttr::getType() const { 253 auto init = def->getValueInit("type"); 254 return tblgen::Attribute(cast<llvm::DefInit>(init)); 255 } 256 257 tblgen::StructAttr::StructAttr(const llvm::Record *record) : Attribute(record) { 258 assert(isSubClassOf("StructAttr") && 259 "must be subclass of TableGen 'StructAttr' class"); 260 } 261 262 tblgen::StructAttr::StructAttr(const llvm::DefInit *init) 263 : StructAttr(init->getDef()) {} 264 265 StringRef tblgen::StructAttr::getStructClassName() const { 266 return def->getValueAsString("className"); 267 } 268 269 StringRef tblgen::StructAttr::getCppNamespace() const { 270 Dialect dialect(def->getValueAsDef("structDialect")); 271 return dialect.getCppNamespace(); 272 } 273 274 std::vector<mlir::tblgen::StructFieldAttr> 275 tblgen::StructAttr::getAllFields() const { 276 std::vector<mlir::tblgen::StructFieldAttr> attributes; 277 278 const auto *inits = def->getValueAsListInit("fields"); 279 attributes.reserve(inits->size()); 280 281 for (const llvm::Init *init : *inits) { 282 attributes.emplace_back(cast<llvm::DefInit>(init)); 283 } 284 285 return attributes; 286 } 287