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("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)}); 35 } 36 } 37 38 StringRef InterfaceMethod::getReturnType() const { 39 return def->getValueAsString("returnType"); 40 } 41 42 // Return the name of this method. 43 StringRef InterfaceMethod::getName() const { 44 return def->getValueAsString("name"); 45 } 46 47 // Return if this method is static. 48 bool InterfaceMethod::isStatic() const { 49 return def->isSubClassOf("StaticInterfaceMethod"); 50 } 51 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; 56 } 57 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; 62 } 63 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; 68 } 69 70 ArrayRef<InterfaceMethod::Argument> InterfaceMethod::getArguments() const { 71 return arguments; 72 } 73 74 bool InterfaceMethod::arg_empty() const { return arguments.empty(); } 75 76 //===----------------------------------------------------------------------===// 77 // Interface 78 //===----------------------------------------------------------------------===// 79 80 Interface::Interface(const Record *def) : def(def) { 81 assert(def->isSubClassOf("Interface") && 82 "must be subclass of TableGen 'Interface' class"); 83 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()); 88 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); 98 99 // Add the base interface. 100 if (basesAdded.contains(baseInterface.getName())) 101 return; 102 baseInterfaces.push_back(std::make_unique<Interface>(baseInterface)); 103 basesAdded.insert(baseInterface.getName()); 104 }; 105 for (const Init *init : basesInit->getValues()) 106 addBaseInterfaceFn(Interface(cast<DefInit>(init)->getDef())); 107 } 108 109 // Return the name of this interface. 110 StringRef Interface::getName() const { 111 return def->getValueAsString("cppInterfaceName"); 112 } 113 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()) 119 return name.str(); 120 return (cppNamespace + "::" + name).str(); 121 } 122 123 // Return the C++ namespace of this interface. 124 StringRef Interface::getCppNamespace() const { 125 return def->getValueAsString("cppNamespace"); 126 } 127 128 // Return the methods of this interface. 129 ArrayRef<InterfaceMethod> Interface::getMethods() const { return methods; } 130 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; 135 } 136 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; 141 } 142 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; 147 } 148 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; 153 } 154 155 std::optional<StringRef> Interface::getExtraClassOf() const { 156 auto value = def->getValueAsString("extraClassOf"); 157 return value.empty() ? std::optional<StringRef>() : value; 158 } 159 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)) 164 return std::nullopt; 165 auto value = def->getValueAsString("verify"); 166 return value.empty() ? std::optional<StringRef>() : value; 167 } 168 169 bool Interface::verifyWithRegions() const { 170 return def->getValueAsBit("verifyWithRegions"); 171 } 172 173 //===----------------------------------------------------------------------===// 174 // AttrInterface 175 //===----------------------------------------------------------------------===// 176 177 bool AttrInterface::classof(const Interface *interface) { 178 return interface->getDef().isSubClassOf("AttrInterface"); 179 } 180 181 //===----------------------------------------------------------------------===// 182 // OpInterface 183 //===----------------------------------------------------------------------===// 184 185 bool OpInterface::classof(const Interface *interface) { 186 return interface->getDef().isSubClassOf("OpInterface"); 187 } 188 189 //===----------------------------------------------------------------------===// 190 // TypeInterface 191 //===----------------------------------------------------------------------===// 192 193 bool TypeInterface::classof(const Interface *interface) { 194 return interface->getDef().isSubClassOf("TypeInterface"); 195 } 196