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
17using namespace mlir;
18using namespace mlir::tblgen;
19using llvm::DagInit;
20using llvm::DefInit;
21using llvm::Init;
22using llvm::ListInit;
23using llvm::Record;
24using llvm::StringInit;
25
26//===----------------------------------------------------------------------===//
27// InterfaceMethod
28//===----------------------------------------------------------------------===//
29
30InterfaceMethod::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
38StringRef InterfaceMethod::getReturnType() const {
39 return def->getValueAsString(FieldName: "returnType");
40}
41
42// Return the name of this method.
43StringRef InterfaceMethod::getName() const {
44 return def->getValueAsString(FieldName: "name");
45}
46
47// Return if this method is static.
48bool InterfaceMethod::isStatic() const {
49 return def->isSubClassOf(Name: "StaticInterfaceMethod");
50}
51
52// Return the body for this method if it has one.
53std::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.
60std::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.
67std::optional<StringRef> InterfaceMethod::getDescription() const {
68 auto value = def->getValueAsString(FieldName: "description");
69 return value.empty() ? std::optional<StringRef>() : value;
70}
71
72ArrayRef<InterfaceMethod::Argument> InterfaceMethod::getArguments() const {
73 return arguments;
74}
75
76bool InterfaceMethod::arg_empty() const { return arguments.empty(); }
77
78//===----------------------------------------------------------------------===//
79// Interface
80//===----------------------------------------------------------------------===//
81
82Interface::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.
112StringRef Interface::getName() const {
113 return def->getValueAsString(FieldName: "cppInterfaceName");
114}
115
116// Returns this interface's name prefixed with namespaces.
117std::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.
126StringRef Interface::getCppNamespace() const {
127 return def->getValueAsString(FieldName: "cppNamespace");
128}
129
130// Return the methods of this interface.
131ArrayRef<InterfaceMethod> Interface::getMethods() const { return methods; }
132
133// Return the description of this method if it has one.
134std::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.
140std::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.
146std::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.
152std::optional<StringRef> Interface::getExtraSharedClassDeclaration() const {
153 auto value = def->getValueAsString(FieldName: "extraSharedClassDeclaration");
154 return value.empty() ? std::optional<StringRef>() : value;
155}
156
157std::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.
163std::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
171bool Interface::verifyWithRegions() const {
172 return def->getValueAsBit(FieldName: "verifyWithRegions");
173}
174
175//===----------------------------------------------------------------------===//
176// AttrInterface
177//===----------------------------------------------------------------------===//
178
179bool AttrInterface::classof(const Interface *interface) {
180 return interface->getDef().isSubClassOf(Name: "AttrInterface");
181}
182
183//===----------------------------------------------------------------------===//
184// OpInterface
185//===----------------------------------------------------------------------===//
186
187bool OpInterface::classof(const Interface *interface) {
188 return interface->getDef().isSubClassOf(Name: "OpInterface");
189}
190
191//===----------------------------------------------------------------------===//
192// TypeInterface
193//===----------------------------------------------------------------------===//
194
195bool TypeInterface::classof(const Interface *interface) {
196 return interface->getDef().isSubClassOf(Name: "TypeInterface");
197}
198

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of mlir/lib/TableGen/Interfaces.cpp