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