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 &param :
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   }
49 }
50 
51 Dialect AttrOrTypeDef::getDialect() const {
52   auto *dialect = dyn_cast<llvm::DefInit>(def->getValue("dialect")->getValue());
53   return Dialect(dialect ? dialect->getDef() : nullptr);
54 }
55 
56 StringRef AttrOrTypeDef::getName() const { return def->getName(); }
57 
58 StringRef AttrOrTypeDef::getCppClassName() const {
59   return def->getValueAsString("cppClassName");
60 }
61 
62 StringRef AttrOrTypeDef::getCppBaseClassName() const {
63   return def->getValueAsString("cppBaseClassName");
64 }
65 
66 bool AttrOrTypeDef::hasDescription() const {
67   const llvm::RecordVal *desc = def->getValue("description");
68   return desc && isa<llvm::StringInit>(desc->getValue());
69 }
70 
71 StringRef AttrOrTypeDef::getDescription() const {
72   return def->getValueAsString("description");
73 }
74 
75 bool AttrOrTypeDef::hasSummary() const {
76   const llvm::RecordVal *summary = def->getValue("summary");
77   return summary && isa<llvm::StringInit>(summary->getValue());
78 }
79 
80 StringRef AttrOrTypeDef::getSummary() const {
81   return def->getValueAsString("summary");
82 }
83 
84 StringRef AttrOrTypeDef::getStorageClassName() const {
85   return def->getValueAsString("storageClass");
86 }
87 
88 StringRef AttrOrTypeDef::getStorageNamespace() const {
89   return def->getValueAsString("storageNamespace");
90 }
91 
92 bool AttrOrTypeDef::genStorageClass() const {
93   return def->getValueAsBit("genStorageClass");
94 }
95 
96 bool AttrOrTypeDef::hasStorageCustomConstructor() const {
97   return def->getValueAsBit("hasStorageCustomConstructor");
98 }
99 
100 void AttrOrTypeDef::getParameters(
101     SmallVectorImpl<AttrOrTypeParameter> &parameters) const {
102   if (auto *parametersDag = def->getValueAsDag("parameters")) {
103     for (unsigned i = 0, e = parametersDag->getNumArgs(); i < e; ++i)
104       parameters.push_back(AttrOrTypeParameter(parametersDag, i));
105   }
106 }
107 
108 unsigned AttrOrTypeDef::getNumParameters() const {
109   auto *parametersDag = def->getValueAsDag("parameters");
110   return parametersDag ? parametersDag->getNumArgs() : 0;
111 }
112 
113 Optional<StringRef> AttrOrTypeDef::getMnemonic() const {
114   return def->getValueAsOptionalString("mnemonic");
115 }
116 
117 Optional<StringRef> AttrOrTypeDef::getPrinterCode() const {
118   return def->getValueAsOptionalString("printer");
119 }
120 
121 Optional<StringRef> AttrOrTypeDef::getParserCode() const {
122   return def->getValueAsOptionalString("parser");
123 }
124 
125 bool AttrOrTypeDef::genAccessors() const {
126   return def->getValueAsBit("genAccessors");
127 }
128 
129 bool AttrOrTypeDef::genVerifyDecl() const {
130   return def->getValueAsBit("genVerifyDecl");
131 }
132 
133 Optional<StringRef> AttrOrTypeDef::getExtraDecls() const {
134   auto value = def->getValueAsString("extraClassDeclaration");
135   return value.empty() ? Optional<StringRef>() : value;
136 }
137 
138 ArrayRef<llvm::SMLoc> AttrOrTypeDef::getLoc() const { return def->getLoc(); }
139 
140 bool AttrOrTypeDef::skipDefaultBuilders() const {
141   return def->getValueAsBit("skipDefaultBuilders");
142 }
143 
144 bool AttrOrTypeDef::operator==(const AttrOrTypeDef &other) const {
145   return def == other.def;
146 }
147 
148 bool AttrOrTypeDef::operator<(const AttrOrTypeDef &other) const {
149   return getName() < other.getName();
150 }
151 
152 //===----------------------------------------------------------------------===//
153 // AttrDef
154 //===----------------------------------------------------------------------===//
155 
156 Optional<StringRef> AttrDef::getTypeBuilder() const {
157   return def->getValueAsOptionalString("typeBuilder");
158 }
159 
160 bool AttrDef::classof(const AttrOrTypeDef *def) {
161   return def->getDef()->isSubClassOf("AttrDef");
162 }
163 
164 //===----------------------------------------------------------------------===//
165 // AttrOrTypeParameter
166 //===----------------------------------------------------------------------===//
167 
168 StringRef AttrOrTypeParameter::getName() const {
169   return def->getArgName(index)->getValue();
170 }
171 
172 Optional<StringRef> AttrOrTypeParameter::getAllocator() const {
173   llvm::Init *parameterType = def->getArg(index);
174   if (isa<llvm::StringInit>(parameterType))
175     return Optional<StringRef>();
176   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
177     return param->getDef()->getValueAsOptionalString("allocator");
178   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
179                         "defs which inherit from AttrOrTypeParameter\n");
180 }
181 
182 Optional<StringRef> AttrOrTypeParameter::getComparator() const {
183   llvm::Init *parameterType = def->getArg(index);
184   if (isa<llvm::StringInit>(parameterType))
185     return Optional<StringRef>();
186   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
187     return param->getDef()->getValueAsOptionalString("comparator");
188   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
189                         "defs which inherit from AttrOrTypeParameter\n");
190 }
191 
192 StringRef AttrOrTypeParameter::getCppType() const {
193   auto *parameterType = def->getArg(index);
194   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
195     return stringType->getValue();
196   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
197     return param->getDef()->getValueAsString("cppType");
198   llvm::PrintFatalError(
199       "Parameters DAG arguments must be either strings or defs "
200       "which inherit from AttrOrTypeParameter\n");
201 }
202 
203 Optional<StringRef> AttrOrTypeParameter::getSummary() const {
204   auto *parameterType = def->getArg(index);
205   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
206     const auto *desc = param->getDef()->getValue("summary");
207     if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(desc->getValue()))
208       return ci->getValue();
209   }
210   return Optional<StringRef>();
211 }
212 
213 StringRef AttrOrTypeParameter::getSyntax() const {
214   auto *parameterType = def->getArg(index);
215   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
216     return stringType->getValue();
217   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
218     const auto *syntax = param->getDef()->getValue("syntax");
219     if (syntax && isa<llvm::StringInit>(syntax->getValue()))
220       return cast<llvm::StringInit>(syntax->getValue())->getValue();
221     return getCppType();
222   }
223   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
224                         "defs which inherit from AttrOrTypeParameter");
225 }
226 
227 const llvm::Init *AttrOrTypeParameter::getDef() const {
228   return def->getArg(index);
229 }
230 
231 //===----------------------------------------------------------------------===//
232 // AttributeSelfTypeParameter
233 //===----------------------------------------------------------------------===//
234 
235 bool AttributeSelfTypeParameter::classof(const AttrOrTypeParameter *param) {
236   const llvm::Init *paramDef = param->getDef();
237   if (auto *paramDefInit = dyn_cast<llvm::DefInit>(paramDef))
238     return paramDefInit->getDef()->isSubClassOf("AttributeSelfTypeParameter");
239   return false;
240 }
241