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   } 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> &parameters) 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 // AttrOrTypeParameter
158 //===----------------------------------------------------------------------===//
159 
160 StringRef AttrOrTypeParameter::getName() const {
161   return def->getArgName(index)->getValue();
162 }
163 
164 Optional<StringRef> AttrOrTypeParameter::getAllocator() const {
165   llvm::Init *parameterType = def->getArg(index);
166   if (isa<llvm::StringInit>(parameterType))
167     return Optional<StringRef>();
168 
169   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
170     llvm::RecordVal *code = param->getDef()->getValue("allocator");
171     if (!code)
172       return Optional<StringRef>();
173     if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(code->getValue()))
174       return ci->getValue();
175     if (isa<llvm::UnsetInit>(code->getValue()))
176       return Optional<StringRef>();
177 
178     llvm::PrintFatalError(
179         param->getDef()->getLoc(),
180         "Record `" + def->getArgName(index)->getValue() +
181             "', field `printer' does not have a code initializer!");
182   }
183 
184   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
185                         "defs which inherit from AttrOrTypeParameter\n");
186 }
187 
188 StringRef AttrOrTypeParameter::getCppType() const {
189   auto *parameterType = def->getArg(index);
190   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
191     return stringType->getValue();
192   if (auto *param = dyn_cast<llvm::DefInit>(parameterType))
193     return param->getDef()->getValueAsString("cppType");
194   llvm::PrintFatalError(
195       "Parameters DAG arguments must be either strings or defs "
196       "which inherit from AttrOrTypeParameter\n");
197 }
198 
199 Optional<StringRef> AttrOrTypeParameter::getSummary() const {
200   auto *parameterType = def->getArg(index);
201   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
202     const auto *desc = param->getDef()->getValue("summary");
203     if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(desc->getValue()))
204       return ci->getValue();
205   }
206   return Optional<StringRef>();
207 }
208 
209 StringRef AttrOrTypeParameter::getSyntax() const {
210   auto *parameterType = def->getArg(index);
211   if (auto *stringType = dyn_cast<llvm::StringInit>(parameterType))
212     return stringType->getValue();
213   if (auto *param = dyn_cast<llvm::DefInit>(parameterType)) {
214     const auto *syntax = param->getDef()->getValue("syntax");
215     if (syntax && isa<llvm::StringInit>(syntax->getValue()))
216       return cast<llvm::StringInit>(syntax->getValue())->getValue();
217     return getCppType();
218   }
219   llvm::PrintFatalError("Parameters DAG arguments must be either strings or "
220                         "defs which inherit from AttrOrTypeParameter");
221 }
222