1 | //===- Interfaces.cpp - Interface 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/Interfaces.h" |
10 | #include "llvm/ADT/FunctionExtras.h" |
11 | #include "llvm/ADT/StringExtras.h" |
12 | #include "llvm/ADT/StringSet.h" |
13 | #include "llvm/Support/FormatVariadic.h" |
14 | #include "llvm/TableGen/Error.h" |
15 | #include "llvm/TableGen/Record.h" |
16 | |
17 | using namespace mlir; |
18 | using namespace mlir::tblgen; |
19 | using llvm::DagInit; |
20 | using llvm::DefInit; |
21 | using llvm::Init; |
22 | using llvm::ListInit; |
23 | using llvm::Record; |
24 | using llvm::StringInit; |
25 | |
26 | //===----------------------------------------------------------------------===// |
27 | // InterfaceMethod |
28 | //===----------------------------------------------------------------------===// |
29 | |
30 | InterfaceMethod::InterfaceMethod(const Record *def) : def(def) { |
31 | const DagInit *args = def->getValueAsDag(FieldName: "arguments"); |
32 | for (unsigned i = 0, e = args->getNumArgs(); i != e; ++i) { |
33 | arguments.push_back(Elt: {.type: cast<StringInit>(Val: args->getArg(Num: i))->getValue(), |
34 | .name: args->getArgNameStr(Num: i)}); |
35 | } |
36 | } |
37 | |
38 | StringRef InterfaceMethod::getReturnType() const { |
39 | return def->getValueAsString(FieldName: "returnType"); |
40 | } |
41 | |
42 | // Return the name of this method. |
43 | StringRef InterfaceMethod::getName() const { |
44 | return def->getValueAsString(FieldName: "name"); |
45 | } |
46 | |
47 | // Return if this method is static. |
48 | bool InterfaceMethod::isStatic() const { |
49 | return def->isSubClassOf(Name: "StaticInterfaceMethod"); |
50 | } |
51 | |
52 | // Return the body for this method if it has one. |
53 | std::optional<StringRef> InterfaceMethod::getBody() const { |
54 | // Trim leading and trailing spaces from the default implementation. |
55 | auto value = def->getValueAsString(FieldName: "body").trim(); |
56 | return value.empty() ? std::optional<StringRef>() : value; |
57 | } |
58 | |
59 | // Return the default implementation for this method if it has one. |
60 | std::optional<StringRef> InterfaceMethod::getDefaultImplementation() const { |
61 | // Trim leading and trailing spaces from the default implementation. |
62 | auto value = def->getValueAsString(FieldName: "defaultBody").trim(); |
63 | return value.empty() ? std::optional<StringRef>() : value; |
64 | } |
65 | |
66 | // Return the description of this method if it has one. |
67 | std::optional<StringRef> InterfaceMethod::getDescription() const { |
68 | auto value = def->getValueAsString(FieldName: "description"); |
69 | return value.empty() ? std::optional<StringRef>() : value; |
70 | } |
71 | |
72 | ArrayRef<InterfaceMethod::Argument> InterfaceMethod::getArguments() const { |
73 | return arguments; |
74 | } |
75 | |
76 | bool InterfaceMethod::arg_empty() const { return arguments.empty(); } |
77 | |
78 | //===----------------------------------------------------------------------===// |
79 | // Interface |
80 | //===----------------------------------------------------------------------===// |
81 | |
82 | Interface::Interface(const Record *def) : def(def) { |
83 | assert(def->isSubClassOf("Interface") && |
84 | "must be subclass of TableGen 'Interface' class"); |
85 | |
86 | // Initialize the interface methods. |
87 | auto *listInit = dyn_cast<ListInit>(Val: def->getValueInit(FieldName: "methods")); |
88 | for (const Init *init : listInit->getElements()) |
89 | methods.emplace_back(Args: cast<DefInit>(Val: init)->getDef()); |
90 | |
91 | // Initialize the interface base classes. |
92 | auto *basesInit = dyn_cast<ListInit>(Val: def->getValueInit(FieldName: "baseInterfaces")); |
93 | // Chained inheritance will produce duplicates in the base interface set. |
94 | StringSet<> basesAdded; |
95 | llvm::unique_function<void(Interface)> addBaseInterfaceFn = |
96 | [&](const Interface &baseInterface) { |
97 | // Inherit any base interfaces. |
98 | for (const auto &baseBaseInterface : baseInterface.getBaseInterfaces()) |
99 | addBaseInterfaceFn(baseBaseInterface); |
100 | |
101 | // Add the base interface. |
102 | if (basesAdded.contains(key: baseInterface.getName())) |
103 | return; |
104 | baseInterfaces.push_back(Elt: std::make_unique<Interface>(args: baseInterface)); |
105 | basesAdded.insert(key: baseInterface.getName()); |
106 | }; |
107 | for (const Init *init : basesInit->getElements()) |
108 | addBaseInterfaceFn(Interface(cast<DefInit>(Val: init)->getDef())); |
109 | } |
110 | |
111 | // Return the name of this interface. |
112 | StringRef Interface::getName() const { |
113 | return def->getValueAsString(FieldName: "cppInterfaceName"); |
114 | } |
115 | |
116 | // Returns this interface's name prefixed with namespaces. |
117 | std::string Interface::getFullyQualifiedName() const { |
118 | StringRef cppNamespace = getCppNamespace(); |
119 | StringRef name = getName(); |
120 | if (cppNamespace.empty()) |
121 | return name.str(); |
122 | return (cppNamespace + "::"+ name).str(); |
123 | } |
124 | |
125 | // Return the C++ namespace of this interface. |
126 | StringRef Interface::getCppNamespace() const { |
127 | return def->getValueAsString(FieldName: "cppNamespace"); |
128 | } |
129 | |
130 | // Return the methods of this interface. |
131 | ArrayRef<InterfaceMethod> Interface::getMethods() const { return methods; } |
132 | |
133 | // Return the description of this method if it has one. |
134 | std::optional<StringRef> Interface::getDescription() const { |
135 | auto value = def->getValueAsString(FieldName: "description"); |
136 | return value.empty() ? std::optional<StringRef>() : value; |
137 | } |
138 | |
139 | // Return the interfaces extra class declaration code. |
140 | std::optional<StringRef> Interface::getExtraClassDeclaration() const { |
141 | auto value = def->getValueAsString(FieldName: "extraClassDeclaration"); |
142 | return value.empty() ? std::optional<StringRef>() : value; |
143 | } |
144 | |
145 | // Return the traits extra class declaration code. |
146 | std::optional<StringRef> Interface::getExtraTraitClassDeclaration() const { |
147 | auto value = def->getValueAsString(FieldName: "extraTraitClassDeclaration"); |
148 | return value.empty() ? std::optional<StringRef>() : value; |
149 | } |
150 | |
151 | // Return the shared extra class declaration code. |
152 | std::optional<StringRef> Interface::getExtraSharedClassDeclaration() const { |
153 | auto value = def->getValueAsString(FieldName: "extraSharedClassDeclaration"); |
154 | return value.empty() ? std::optional<StringRef>() : value; |
155 | } |
156 | |
157 | std::optional<StringRef> Interface::getExtraClassOf() const { |
158 | auto value = def->getValueAsString(FieldName: "extraClassOf"); |
159 | return value.empty() ? std::optional<StringRef>() : value; |
160 | } |
161 | |
162 | // Return the body for this method if it has one. |
163 | std::optional<StringRef> Interface::getVerify() const { |
164 | // Only OpInterface supports the verify method. |
165 | if (!isa<OpInterface>(Val: this)) |
166 | return std::nullopt; |
167 | auto value = def->getValueAsString(FieldName: "verify"); |
168 | return value.empty() ? std::optional<StringRef>() : value; |
169 | } |
170 | |
171 | bool Interface::verifyWithRegions() const { |
172 | return def->getValueAsBit(FieldName: "verifyWithRegions"); |
173 | } |
174 | |
175 | //===----------------------------------------------------------------------===// |
176 | // AttrInterface |
177 | //===----------------------------------------------------------------------===// |
178 | |
179 | bool AttrInterface::classof(const Interface *interface) { |
180 | return interface->getDef().isSubClassOf(Name: "AttrInterface"); |
181 | } |
182 | |
183 | //===----------------------------------------------------------------------===// |
184 | // OpInterface |
185 | //===----------------------------------------------------------------------===// |
186 | |
187 | bool OpInterface::classof(const Interface *interface) { |
188 | return interface->getDef().isSubClassOf(Name: "OpInterface"); |
189 | } |
190 | |
191 | //===----------------------------------------------------------------------===// |
192 | // TypeInterface |
193 | //===----------------------------------------------------------------------===// |
194 | |
195 | bool TypeInterface::classof(const Interface *interface) { |
196 | return interface->getDef().isSubClassOf(Name: "TypeInterface"); |
197 | } |
198 |
Definitions
- InterfaceMethod
- getReturnType
- getName
- isStatic
- getBody
- getDefaultImplementation
- getDescription
- getArguments
- arg_empty
- Interface
- getName
- getFullyQualifiedName
- getCppNamespace
- getMethods
- getDescription
- getExtraClassDeclaration
- getExtraTraitClassDeclaration
- getExtraSharedClassDeclaration
- getExtraClassOf
- getVerify
- verifyWithRegions
- classof
- classof
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more