1 //===- AttrOrTypeDef.cpp - AttrOrTypeDef wrapper classes ------------------===// 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 #include "mlir/TableGen/AttrOrTypeDef.h" 10 #include "mlir/TableGen/Dialect.h" 11 #include "llvm/ADT/StringExtras.h" 12 #include "llvm/TableGen/Error.h" 13 #include "llvm/TableGen/Record.h" 14 15 using namespace mlir; 16 using namespace mlir::tblgen; 17 18 //===----------------------------------------------------------------------===// 19 // AttrOrTypeBuilder 20 //===----------------------------------------------------------------------===// 21 22 /// Returns true if this builder is able to infer the MLIRContext parameter. 23 bool AttrOrTypeBuilder::hasInferredContextParameter() const { 24 return def->getValueAsBit("hasInferredContextParam"); 25 } 26 27 //===----------------------------------------------------------------------===// 28 // AttrOrTypeDef 29 //===----------------------------------------------------------------------===// 30 31 AttrOrTypeDef::AttrOrTypeDef(const llvm::Record *def) : def(def) { 32 // Populate the builders. 33 auto *builderList = 34 dyn_cast_or_null<llvm::ListInit>(def->getValueInit("builders")); 35 if (builderList && !builderList->empty()) { 36 for (llvm::Init *init : builderList->getValues()) { 37 AttrOrTypeBuilder builder(cast<llvm::DefInit>(init)->getDef(), 38 def->getLoc()); 39 40 // Ensure that all parameters have names. 41 for (const AttrOrTypeBuilder::Parameter ¶m : 42 builder.getParameters()) { 43 if (!param.getName()) 44 PrintFatalError(def->getLoc(), "builder parameters must have a name"); 45 } 46 builders.emplace_back(builder); 47 } 48 } else if (skipDefaultBuilders()) { 49 PrintFatalError( 50 def->getLoc(), 51 "default builders are skipped and no custom builders provided"); 52 } 53 } 54 55 Dialect AttrOrTypeDef::getDialect() const { 56 auto *dialect = dyn_cast<llvm::DefInit>(def->getValue("dialect")->getValue()); 57 return Dialect(dialect ? dialect->getDef() : nullptr); 58 } 59 60 StringRef AttrOrTypeDef::getName() const { return def->getName(); } 61 62 StringRef AttrOrTypeDef::getCppClassName() const { 63 return def->getValueAsString("cppClassName"); 64 } 65 66 StringRef AttrOrTypeDef::getCppBaseClassName() const { 67 return def->getValueAsString("cppBaseClassName"); 68 } 69 70 bool AttrOrTypeDef::hasDescription() const { 71 const llvm::RecordVal *desc = def->getValue("description"); 72 return desc && isa<llvm::StringInit>(desc->getValue()); 73 } 74 75 StringRef AttrOrTypeDef::getDescription() const { 76 return def->getValueAsString("description"); 77 } 78 79 bool AttrOrTypeDef::hasSummary() const { 80 const llvm::RecordVal *summary = def->getValue("summary"); 81 return summary && isa<llvm::StringInit>(summary->getValue()); 82 } 83 84 StringRef AttrOrTypeDef::getSummary() const { 85 return def->getValueAsString("summary"); 86 } 87 88 StringRef AttrOrTypeDef::getStorageClassName() const { 89 return def->getValueAsString("storageClass"); 90 } 91 92 StringRef AttrOrTypeDef::getStorageNamespace() const { 93 return def->getValueAsString("storageNamespace"); 94 } 95 96 bool AttrOrTypeDef::genStorageClass() const { 97 return def->getValueAsBit("genStorageClass"); 98 } 99 100 bool AttrOrTypeDef::hasStorageCustomConstructor() const { 101 return def->getValueAsBit("hasStorageCustomConstructor"); 102 } 103 104 void AttrOrTypeDef::getParameters( 105 SmallVectorImpl<AttrOrTypeParameter> ¶meters) const { 106 if (auto *parametersDag = def->getValueAsDag("parameters")) { 107 for (unsigned i = 0, e = parametersDag->getNumArgs(); i < e; ++i) 108 parameters.push_back(AttrOrTypeParameter(parametersDag, i)); 109 } 110 } 111 112 unsigned AttrOrTypeDef::getNumParameters() const { 113 auto *parametersDag = def->getValueAsDag("parameters"); 114 return parametersDag ? parametersDag->getNumArgs() : 0; 115 } 116 117 Optional<StringRef> AttrOrTypeDef::getMnemonic() const { 118 return def->getValueAsOptionalString("mnemonic"); 119 } 120 121 Optional<StringRef> AttrOrTypeDef::getPrinterCode() const { 122 return def->getValueAsOptionalString("printer"); 123 } 124 125 Optional<StringRef> AttrOrTypeDef::getParserCode() const { 126 return def->getValueAsOptionalString("parser"); 127 } 128 129 bool AttrOrTypeDef::genAccessors() const { 130 return def->getValueAsBit("genAccessors"); 131 } 132 133 bool AttrOrTypeDef::genVerifyDecl() const { 134 return def->getValueAsBit("genVerifyDecl"); 135 } 136 137 Optional<StringRef> AttrOrTypeDef::getExtraDecls() const { 138 auto value = def->getValueAsString("extraClassDeclaration"); 139 return value.empty() ? Optional<StringRef>() : value; 140 } 141 142 ArrayRef<llvm::SMLoc> AttrOrTypeDef::getLoc() const { return def->getLoc(); } 143 144 bool AttrOrTypeDef::skipDefaultBuilders() const { 145 return def->getValueAsBit("skipDefaultBuilders"); 146 } 147 148 bool AttrOrTypeDef::operator==(const AttrOrTypeDef &other) const { 149 return def == other.def; 150 } 151 152 bool AttrOrTypeDef::operator<(const AttrOrTypeDef &other) const { 153 return getName() < other.getName(); 154 } 155 156 //===----------------------------------------------------------------------===// 157 // AttrDef 158 //===----------------------------------------------------------------------===// 159 160 Optional<StringRef> AttrDef::getTypeBuilder() const { 161 return def->getValueAsOptionalString("typeBuilder"); 162 } 163 164 bool AttrDef::classof(const AttrOrTypeDef *def) { 165 return def->getDef()->isSubClassOf("AttrDef"); 166 } 167 168 //===----------------------------------------------------------------------===// 169 // AttrOrTypeParameter 170 //===----------------------------------------------------------------------===// 171 172 StringRef AttrOrTypeParameter::getName() const { 173 return def->getArgName(index)->getValue(); 174 } 175 176 Optional<StringRef> AttrOrTypeParameter::getAllocator() const { 177 llvm::Init *parameterType = def->getArg(index); 178 if (isa<llvm::StringInit>(parameterType)) 179 return Optional<StringRef>(); 180 181 if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) { 182 llvm::RecordVal *code = param->getDef()->getValue("allocator"); 183 if (!code) 184 return Optional<StringRef>(); 185 if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(code->getValue())) 186 return ci->getValue(); 187 if (isa<llvm::UnsetInit>(code->getValue())) 188 return Optional<StringRef>(); 189 190 llvm::PrintFatalError( 191 param->getDef()->getLoc(), 192 "Record `" + def->getArgName(index)->getValue() + 193 "', field `printer' does not have a code initializer!"); 194 } 195 196 llvm::PrintFatalError("Parameters DAG arguments must be either strings or " 197 "defs which inherit from AttrOrTypeParameter\n"); 198 } 199 200 StringRef AttrOrTypeParameter::getCppType() const { 201 auto *parameterType = def->getArg(index); 202 if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType)) 203 return stringType->getValue(); 204 if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) 205 return param->getDef()->getValueAsString("cppType"); 206 llvm::PrintFatalError( 207 "Parameters DAG arguments must be either strings or defs " 208 "which inherit from AttrOrTypeParameter\n"); 209 } 210 211 Optional<StringRef> AttrOrTypeParameter::getSummary() const { 212 auto *parameterType = def->getArg(index); 213 if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) { 214 const auto *desc = param->getDef()->getValue("summary"); 215 if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(desc->getValue())) 216 return ci->getValue(); 217 } 218 return Optional<StringRef>(); 219 } 220 221 StringRef AttrOrTypeParameter::getSyntax() const { 222 auto *parameterType = def->getArg(index); 223 if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType)) 224 return stringType->getValue(); 225 if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) { 226 const auto *syntax = param->getDef()->getValue("syntax"); 227 if (syntax && isa<llvm::StringInit>(syntax->getValue())) 228 return cast<llvm::StringInit>(syntax->getValue())->getValue(); 229 return getCppType(); 230 } 231 llvm::PrintFatalError("Parameters DAG arguments must be either strings or " 232 "defs which inherit from AttrOrTypeParameter"); 233 } 234 235 const llvm::Init *AttrOrTypeParameter::getDef() const { 236 return def->getArg(index); 237 } 238 239 //===----------------------------------------------------------------------===// 240 // AttributeSelfTypeParameter 241 //===----------------------------------------------------------------------===// 242 243 bool AttributeSelfTypeParameter::classof(const AttrOrTypeParameter *param) { 244 const llvm::Init *paramDef = param->getDef(); 245 if (auto *paramDefInit = dyn_cast<llvm::DefInit>(paramDef)) 246 return paramDefInit->getDef()->isSubClassOf("AttributeSelfTypeParameter"); 247 return false; 248 } 249