12e2cdd0aSRiver Riddle //===- Interfaces.cpp - Interface classes ---------------------------------===//
22e2cdd0aSRiver Riddle //
32e2cdd0aSRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42e2cdd0aSRiver Riddle // See https://llvm.org/LICENSE.txt for license information.
52e2cdd0aSRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62e2cdd0aSRiver Riddle //
72e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
82e2cdd0aSRiver Riddle 
92e2cdd0aSRiver Riddle #include "mlir/TableGen/Interfaces.h"
102e2cdd0aSRiver Riddle #include "llvm/ADT/StringExtras.h"
112e2cdd0aSRiver Riddle #include "llvm/Support/FormatVariadic.h"
122e2cdd0aSRiver Riddle #include "llvm/TableGen/Error.h"
132e2cdd0aSRiver Riddle #include "llvm/TableGen/Record.h"
142e2cdd0aSRiver Riddle 
152e2cdd0aSRiver Riddle using namespace mlir;
162e2cdd0aSRiver Riddle using namespace mlir::tblgen;
172e2cdd0aSRiver Riddle 
182e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
192e2cdd0aSRiver Riddle // InterfaceMethod
202e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
212e2cdd0aSRiver Riddle 
InterfaceMethod(const llvm::Record * def)222e2cdd0aSRiver Riddle InterfaceMethod::InterfaceMethod(const llvm::Record *def) : def(def) {
232e2cdd0aSRiver Riddle   llvm::DagInit *args = def->getValueAsDag("arguments");
242e2cdd0aSRiver Riddle   for (unsigned i = 0, e = args->getNumArgs(); i != e; ++i) {
252e2cdd0aSRiver Riddle     arguments.push_back(
262e2cdd0aSRiver Riddle         {llvm::cast<llvm::StringInit>(args->getArg(i))->getValue(),
272e2cdd0aSRiver Riddle          args->getArgNameStr(i)});
282e2cdd0aSRiver Riddle   }
292e2cdd0aSRiver Riddle }
302e2cdd0aSRiver Riddle 
getReturnType() const312e2cdd0aSRiver Riddle StringRef InterfaceMethod::getReturnType() const {
322e2cdd0aSRiver Riddle   return def->getValueAsString("returnType");
332e2cdd0aSRiver Riddle }
342e2cdd0aSRiver Riddle 
352e2cdd0aSRiver Riddle // Return the name of this method.
getName() const362e2cdd0aSRiver Riddle StringRef InterfaceMethod::getName() const {
372e2cdd0aSRiver Riddle   return def->getValueAsString("name");
382e2cdd0aSRiver Riddle }
392e2cdd0aSRiver Riddle 
402e2cdd0aSRiver Riddle // Return if this method is static.
isStatic() const412e2cdd0aSRiver Riddle bool InterfaceMethod::isStatic() const {
422e2cdd0aSRiver Riddle   return def->isSubClassOf("StaticInterfaceMethod");
432e2cdd0aSRiver Riddle }
442e2cdd0aSRiver Riddle 
452e2cdd0aSRiver Riddle // Return the body for this method if it has one.
getBody() const462e2cdd0aSRiver Riddle llvm::Optional<StringRef> InterfaceMethod::getBody() const {
472e2cdd0aSRiver Riddle   auto value = def->getValueAsString("body");
482e2cdd0aSRiver Riddle   return value.empty() ? llvm::Optional<StringRef>() : value;
492e2cdd0aSRiver Riddle }
502e2cdd0aSRiver Riddle 
512e2cdd0aSRiver Riddle // Return the default implementation for this method if it has one.
getDefaultImplementation() const522e2cdd0aSRiver Riddle llvm::Optional<StringRef> InterfaceMethod::getDefaultImplementation() const {
532e2cdd0aSRiver Riddle   auto value = def->getValueAsString("defaultBody");
542e2cdd0aSRiver Riddle   return value.empty() ? llvm::Optional<StringRef>() : value;
552e2cdd0aSRiver Riddle }
562e2cdd0aSRiver Riddle 
572e2cdd0aSRiver Riddle // Return the description of this method if it has one.
getDescription() const582e2cdd0aSRiver Riddle llvm::Optional<StringRef> InterfaceMethod::getDescription() const {
592e2cdd0aSRiver Riddle   auto value = def->getValueAsString("description");
602e2cdd0aSRiver Riddle   return value.empty() ? llvm::Optional<StringRef>() : value;
612e2cdd0aSRiver Riddle }
622e2cdd0aSRiver Riddle 
getArguments() const632e2cdd0aSRiver Riddle ArrayRef<InterfaceMethod::Argument> InterfaceMethod::getArguments() const {
642e2cdd0aSRiver Riddle   return arguments;
652e2cdd0aSRiver Riddle }
662e2cdd0aSRiver Riddle 
arg_empty() const672e2cdd0aSRiver Riddle bool InterfaceMethod::arg_empty() const { return arguments.empty(); }
682e2cdd0aSRiver Riddle 
692e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
702e2cdd0aSRiver Riddle // Interface
712e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
722e2cdd0aSRiver Riddle 
Interface(const llvm::Record * def)732e2cdd0aSRiver Riddle Interface::Interface(const llvm::Record *def) : def(def) {
742e2cdd0aSRiver Riddle   assert(def->isSubClassOf("Interface") &&
752e2cdd0aSRiver Riddle          "must be subclass of TableGen 'Interface' class");
762e2cdd0aSRiver Riddle 
772e2cdd0aSRiver Riddle   auto *listInit = dyn_cast<llvm::ListInit>(def->getValueInit("methods"));
782e2cdd0aSRiver Riddle   for (llvm::Init *init : listInit->getValues())
792e2cdd0aSRiver Riddle     methods.emplace_back(cast<llvm::DefInit>(init)->getDef());
802e2cdd0aSRiver Riddle }
812e2cdd0aSRiver Riddle 
822e2cdd0aSRiver Riddle // Return the name of this interface.
getName() const832e2cdd0aSRiver Riddle StringRef Interface::getName() const {
84*9f186bb1SMarkus Böck   return def->getValueAsString("cppInterfaceName");
852e2cdd0aSRiver Riddle }
862e2cdd0aSRiver Riddle 
87572c2905SRiver Riddle // Return the C++ namespace of this interface.
getCppNamespace() const88572c2905SRiver Riddle StringRef Interface::getCppNamespace() const {
89572c2905SRiver Riddle   return def->getValueAsString("cppNamespace");
90572c2905SRiver Riddle }
91572c2905SRiver Riddle 
922e2cdd0aSRiver Riddle // Return the methods of this interface.
getMethods() const932e2cdd0aSRiver Riddle ArrayRef<InterfaceMethod> Interface::getMethods() const { return methods; }
942e2cdd0aSRiver Riddle 
952e2cdd0aSRiver Riddle // Return the description of this method if it has one.
getDescription() const962e2cdd0aSRiver Riddle llvm::Optional<StringRef> Interface::getDescription() const {
972e2cdd0aSRiver Riddle   auto value = def->getValueAsString("description");
982e2cdd0aSRiver Riddle   return value.empty() ? llvm::Optional<StringRef>() : value;
992e2cdd0aSRiver Riddle }
1002e2cdd0aSRiver Riddle 
1012e2cdd0aSRiver Riddle // Return the interfaces extra class declaration code.
getExtraClassDeclaration() const1022e2cdd0aSRiver Riddle llvm::Optional<StringRef> Interface::getExtraClassDeclaration() const {
1032e2cdd0aSRiver Riddle   auto value = def->getValueAsString("extraClassDeclaration");
1042e2cdd0aSRiver Riddle   return value.empty() ? llvm::Optional<StringRef>() : value;
1052e2cdd0aSRiver Riddle }
1062e2cdd0aSRiver Riddle 
1072e2cdd0aSRiver Riddle // Return the traits extra class declaration code.
getExtraTraitClassDeclaration() const1082e2cdd0aSRiver Riddle llvm::Optional<StringRef> Interface::getExtraTraitClassDeclaration() const {
1092e2cdd0aSRiver Riddle   auto value = def->getValueAsString("extraTraitClassDeclaration");
1102e2cdd0aSRiver Riddle   return value.empty() ? llvm::Optional<StringRef>() : value;
1112e2cdd0aSRiver Riddle }
1122e2cdd0aSRiver Riddle 
113a60e83feSRiver Riddle // Return the shared extra class declaration code.
getExtraSharedClassDeclaration() const114a60e83feSRiver Riddle llvm::Optional<StringRef> Interface::getExtraSharedClassDeclaration() const {
115a60e83feSRiver Riddle   auto value = def->getValueAsString("extraSharedClassDeclaration");
116a60e83feSRiver Riddle   return value.empty() ? llvm::Optional<StringRef>() : value;
117a60e83feSRiver Riddle }
118a60e83feSRiver Riddle 
1192e2cdd0aSRiver Riddle // Return the body for this method if it has one.
getVerify() const1202e2cdd0aSRiver Riddle llvm::Optional<StringRef> Interface::getVerify() const {
1212e2cdd0aSRiver Riddle   // Only OpInterface supports the verify method.
1222e2cdd0aSRiver Riddle   if (!isa<OpInterface>(this))
1232e2cdd0aSRiver Riddle     return llvm::None;
1242e2cdd0aSRiver Riddle   auto value = def->getValueAsString("verify");
1252e2cdd0aSRiver Riddle   return value.empty() ? llvm::Optional<StringRef>() : value;
1262e2cdd0aSRiver Riddle }
1272e2cdd0aSRiver Riddle 
verifyWithRegions() const1289445b396SChia-hung Duan bool Interface::verifyWithRegions() const {
1299445b396SChia-hung Duan   return def->getValueAsBit("verifyWithRegions");
1309445b396SChia-hung Duan }
1319445b396SChia-hung Duan 
1322e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
1332e2cdd0aSRiver Riddle // AttrInterface
1342e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
1352e2cdd0aSRiver Riddle 
classof(const Interface * interface)1362e2cdd0aSRiver Riddle bool AttrInterface::classof(const Interface *interface) {
1372e2cdd0aSRiver Riddle   return interface->getDef().isSubClassOf("AttrInterface");
1382e2cdd0aSRiver Riddle }
1392e2cdd0aSRiver Riddle 
1402e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
1412e2cdd0aSRiver Riddle // OpInterface
1422e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
1432e2cdd0aSRiver Riddle 
classof(const Interface * interface)1442e2cdd0aSRiver Riddle bool OpInterface::classof(const Interface *interface) {
1452e2cdd0aSRiver Riddle   return interface->getDef().isSubClassOf("OpInterface");
1462e2cdd0aSRiver Riddle }
1472e2cdd0aSRiver Riddle 
1482e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
1492e2cdd0aSRiver Riddle // TypeInterface
1502e2cdd0aSRiver Riddle //===----------------------------------------------------------------------===//
1512e2cdd0aSRiver Riddle 
classof(const Interface * interface)1522e2cdd0aSRiver Riddle bool TypeInterface::classof(const Interface *interface) {
1532e2cdd0aSRiver Riddle   return interface->getDef().isSubClassOf("TypeInterface");
1542e2cdd0aSRiver Riddle }
155