1 //===- Interfaces.cpp - Interface classes ---------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
18 using namespace mlir::tblgen
;
24 using llvm::StringInit
;
26 //===----------------------------------------------------------------------===//
28 //===----------------------------------------------------------------------===//
30 InterfaceMethod::InterfaceMethod(const Record
*def
) : def(def
) {
31 const DagInit
*args
= def
->getValueAsDag("arguments");
32 for (unsigned i
= 0, e
= args
->getNumArgs(); i
!= e
; ++i
) {
33 arguments
.push_back({cast
<StringInit
>(args
->getArg(i
))->getValue(),
34 args
->getArgNameStr(i
)});
38 StringRef
InterfaceMethod::getReturnType() const {
39 return def
->getValueAsString("returnType");
42 // Return the name of this method.
43 StringRef
InterfaceMethod::getName() const {
44 return def
->getValueAsString("name");
47 // Return if this method is static.
48 bool InterfaceMethod::isStatic() const {
49 return def
->isSubClassOf("StaticInterfaceMethod");
52 // Return the body for this method if it has one.
53 std::optional
<StringRef
> InterfaceMethod::getBody() const {
54 auto value
= def
->getValueAsString("body");
55 return value
.empty() ? std::optional
<StringRef
>() : value
;
58 // Return the default implementation for this method if it has one.
59 std::optional
<StringRef
> InterfaceMethod::getDefaultImplementation() const {
60 auto value
= def
->getValueAsString("defaultBody");
61 return value
.empty() ? std::optional
<StringRef
>() : value
;
64 // Return the description of this method if it has one.
65 std::optional
<StringRef
> InterfaceMethod::getDescription() const {
66 auto value
= def
->getValueAsString("description");
67 return value
.empty() ? std::optional
<StringRef
>() : value
;
70 ArrayRef
<InterfaceMethod::Argument
> InterfaceMethod::getArguments() const {
74 bool InterfaceMethod::arg_empty() const { return arguments
.empty(); }
76 //===----------------------------------------------------------------------===//
78 //===----------------------------------------------------------------------===//
80 Interface::Interface(const Record
*def
) : def(def
) {
81 assert(def
->isSubClassOf("Interface") &&
82 "must be subclass of TableGen 'Interface' class");
84 // Initialize the interface methods.
85 auto *listInit
= dyn_cast
<ListInit
>(def
->getValueInit("methods"));
86 for (const Init
*init
: listInit
->getValues())
87 methods
.emplace_back(cast
<DefInit
>(init
)->getDef());
89 // Initialize the interface base classes.
90 auto *basesInit
= dyn_cast
<ListInit
>(def
->getValueInit("baseInterfaces"));
91 // Chained inheritance will produce duplicates in the base interface set.
92 StringSet
<> basesAdded
;
93 llvm::unique_function
<void(Interface
)> addBaseInterfaceFn
=
94 [&](const Interface
&baseInterface
) {
95 // Inherit any base interfaces.
96 for (const auto &baseBaseInterface
: baseInterface
.getBaseInterfaces())
97 addBaseInterfaceFn(baseBaseInterface
);
99 // Add the base interface.
100 if (basesAdded
.contains(baseInterface
.getName()))
102 baseInterfaces
.push_back(std::make_unique
<Interface
>(baseInterface
));
103 basesAdded
.insert(baseInterface
.getName());
105 for (const Init
*init
: basesInit
->getValues())
106 addBaseInterfaceFn(Interface(cast
<DefInit
>(init
)->getDef()));
109 // Return the name of this interface.
110 StringRef
Interface::getName() const {
111 return def
->getValueAsString("cppInterfaceName");
114 // Returns this interface's name prefixed with namespaces.
115 std::string
Interface::getFullyQualifiedName() const {
116 StringRef cppNamespace
= getCppNamespace();
117 StringRef name
= getName();
118 if (cppNamespace
.empty())
120 return (cppNamespace
+ "::" + name
).str();
123 // Return the C++ namespace of this interface.
124 StringRef
Interface::getCppNamespace() const {
125 return def
->getValueAsString("cppNamespace");
128 // Return the methods of this interface.
129 ArrayRef
<InterfaceMethod
> Interface::getMethods() const { return methods
; }
131 // Return the description of this method if it has one.
132 std::optional
<StringRef
> Interface::getDescription() const {
133 auto value
= def
->getValueAsString("description");
134 return value
.empty() ? std::optional
<StringRef
>() : value
;
137 // Return the interfaces extra class declaration code.
138 std::optional
<StringRef
> Interface::getExtraClassDeclaration() const {
139 auto value
= def
->getValueAsString("extraClassDeclaration");
140 return value
.empty() ? std::optional
<StringRef
>() : value
;
143 // Return the traits extra class declaration code.
144 std::optional
<StringRef
> Interface::getExtraTraitClassDeclaration() const {
145 auto value
= def
->getValueAsString("extraTraitClassDeclaration");
146 return value
.empty() ? std::optional
<StringRef
>() : value
;
149 // Return the shared extra class declaration code.
150 std::optional
<StringRef
> Interface::getExtraSharedClassDeclaration() const {
151 auto value
= def
->getValueAsString("extraSharedClassDeclaration");
152 return value
.empty() ? std::optional
<StringRef
>() : value
;
155 std::optional
<StringRef
> Interface::getExtraClassOf() const {
156 auto value
= def
->getValueAsString("extraClassOf");
157 return value
.empty() ? std::optional
<StringRef
>() : value
;
160 // Return the body for this method if it has one.
161 std::optional
<StringRef
> Interface::getVerify() const {
162 // Only OpInterface supports the verify method.
163 if (!isa
<OpInterface
>(this))
165 auto value
= def
->getValueAsString("verify");
166 return value
.empty() ? std::optional
<StringRef
>() : value
;
169 bool Interface::verifyWithRegions() const {
170 return def
->getValueAsBit("verifyWithRegions");
173 //===----------------------------------------------------------------------===//
175 //===----------------------------------------------------------------------===//
177 bool AttrInterface::classof(const Interface
*interface
) {
178 return interface
->getDef().isSubClassOf("AttrInterface");
181 //===----------------------------------------------------------------------===//
183 //===----------------------------------------------------------------------===//
185 bool OpInterface::classof(const Interface
*interface
) {
186 return interface
->getDef().isSubClassOf("OpInterface");
189 //===----------------------------------------------------------------------===//
191 //===----------------------------------------------------------------------===//
193 bool TypeInterface::classof(const Interface
*interface
) {
194 return interface
->getDef().isSubClassOf("TypeInterface");