This field allows for defining a code block that is placed in both the interface and trait declarations. This is very useful when defining a set of utilities to expose on both the Interface class and the derived attribute/operation/type. In non-static methods, `$_attr`/`$_op`/`$_type` (depending on the type of interface) may be used to refer to an instance of the IR entity. In the interface declaration, this is an instance of the interface class. In the trait declaration, this is an instance of the concrete entity class (e.g. `IntegerAttr`, `FuncOp`, etc.). Differential Revision: https://reviews.llvm.org/D116961
151 lines
5.4 KiB
C++
151 lines
5.4 KiB
C++
//===- Interfaces.cpp - Interface classes ---------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/TableGen/Interfaces.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/Support/FormatVariadic.h"
|
|
#include "llvm/TableGen/Error.h"
|
|
#include "llvm/TableGen/Record.h"
|
|
|
|
using namespace mlir;
|
|
using namespace mlir::tblgen;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// InterfaceMethod
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
InterfaceMethod::InterfaceMethod(const llvm::Record *def) : def(def) {
|
|
llvm::DagInit *args = def->getValueAsDag("arguments");
|
|
for (unsigned i = 0, e = args->getNumArgs(); i != e; ++i) {
|
|
arguments.push_back(
|
|
{llvm::cast<llvm::StringInit>(args->getArg(i))->getValue(),
|
|
args->getArgNameStr(i)});
|
|
}
|
|
}
|
|
|
|
StringRef InterfaceMethod::getReturnType() const {
|
|
return def->getValueAsString("returnType");
|
|
}
|
|
|
|
// Return the name of this method.
|
|
StringRef InterfaceMethod::getName() const {
|
|
return def->getValueAsString("name");
|
|
}
|
|
|
|
// Return if this method is static.
|
|
bool InterfaceMethod::isStatic() const {
|
|
return def->isSubClassOf("StaticInterfaceMethod");
|
|
}
|
|
|
|
// Return the body for this method if it has one.
|
|
llvm::Optional<StringRef> InterfaceMethod::getBody() const {
|
|
auto value = def->getValueAsString("body");
|
|
return value.empty() ? llvm::Optional<StringRef>() : value;
|
|
}
|
|
|
|
// Return the default implementation for this method if it has one.
|
|
llvm::Optional<StringRef> InterfaceMethod::getDefaultImplementation() const {
|
|
auto value = def->getValueAsString("defaultBody");
|
|
return value.empty() ? llvm::Optional<StringRef>() : value;
|
|
}
|
|
|
|
// Return the description of this method if it has one.
|
|
llvm::Optional<StringRef> InterfaceMethod::getDescription() const {
|
|
auto value = def->getValueAsString("description");
|
|
return value.empty() ? llvm::Optional<StringRef>() : value;
|
|
}
|
|
|
|
ArrayRef<InterfaceMethod::Argument> InterfaceMethod::getArguments() const {
|
|
return arguments;
|
|
}
|
|
|
|
bool InterfaceMethod::arg_empty() const { return arguments.empty(); }
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Interface
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
Interface::Interface(const llvm::Record *def) : def(def) {
|
|
assert(def->isSubClassOf("Interface") &&
|
|
"must be subclass of TableGen 'Interface' class");
|
|
|
|
auto *listInit = dyn_cast<llvm::ListInit>(def->getValueInit("methods"));
|
|
for (llvm::Init *init : listInit->getValues())
|
|
methods.emplace_back(cast<llvm::DefInit>(init)->getDef());
|
|
}
|
|
|
|
// Return the name of this interface.
|
|
StringRef Interface::getName() const {
|
|
return def->getValueAsString("cppClassName");
|
|
}
|
|
|
|
// Return the C++ namespace of this interface.
|
|
StringRef Interface::getCppNamespace() const {
|
|
return def->getValueAsString("cppNamespace");
|
|
}
|
|
|
|
// Return the methods of this interface.
|
|
ArrayRef<InterfaceMethod> Interface::getMethods() const { return methods; }
|
|
|
|
// Return the description of this method if it has one.
|
|
llvm::Optional<StringRef> Interface::getDescription() const {
|
|
auto value = def->getValueAsString("description");
|
|
return value.empty() ? llvm::Optional<StringRef>() : value;
|
|
}
|
|
|
|
// Return the interfaces extra class declaration code.
|
|
llvm::Optional<StringRef> Interface::getExtraClassDeclaration() const {
|
|
auto value = def->getValueAsString("extraClassDeclaration");
|
|
return value.empty() ? llvm::Optional<StringRef>() : value;
|
|
}
|
|
|
|
// Return the traits extra class declaration code.
|
|
llvm::Optional<StringRef> Interface::getExtraTraitClassDeclaration() const {
|
|
auto value = def->getValueAsString("extraTraitClassDeclaration");
|
|
return value.empty() ? llvm::Optional<StringRef>() : value;
|
|
}
|
|
|
|
// Return the shared extra class declaration code.
|
|
llvm::Optional<StringRef> Interface::getExtraSharedClassDeclaration() const {
|
|
auto value = def->getValueAsString("extraSharedClassDeclaration");
|
|
return value.empty() ? llvm::Optional<StringRef>() : value;
|
|
}
|
|
|
|
// Return the body for this method if it has one.
|
|
llvm::Optional<StringRef> Interface::getVerify() const {
|
|
// Only OpInterface supports the verify method.
|
|
if (!isa<OpInterface>(this))
|
|
return llvm::None;
|
|
auto value = def->getValueAsString("verify");
|
|
return value.empty() ? llvm::Optional<StringRef>() : value;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// AttrInterface
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
bool AttrInterface::classof(const Interface *interface) {
|
|
return interface->getDef().isSubClassOf("AttrInterface");
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// OpInterface
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
bool OpInterface::classof(const Interface *interface) {
|
|
return interface->getDef().isSubClassOf("OpInterface");
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// TypeInterface
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
bool TypeInterface::classof(const Interface *interface) {
|
|
return interface->getDef().isSubClassOf("TypeInterface");
|
|
}
|