brintos

brintos / llvm-project-archived public Read only

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