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