Files
clang-p2996/mlir/lib/TableGen/Interfaces.cpp
Markus Böck 9f186bb125 [mlir][ods] Make Type- and AttrInterfaces also Types and Attrs
By making TypeInterfaces and AttrInterfaces, Types and Attrs respectively it'd then be possible to use them anywhere where a Type or Attr may go. That is within the arguments and results of an Op definition, in a RewritePattern etc.

Prior to this change users had to separately define a Type or Attr, with a predicate to check whether a type or attribute implements a given interface. Such code will be redundant now.
Removing such occurrences in upstream dialects will be part of a separate patch.

As part of implementing this patch, slight refactoring had to be done. In particular, Interfaces cppClassName field was renamed to cppInterfaceName as it "clashed" with TypeConstraints cppClassName. In particular Interfaces cppClassName expected just the class name, without any namespaces, while TypeConstraints cppClassName expected a fully qualified class name.

Differential Revision: https://reviews.llvm.org/D129209
2022-07-07 11:54:47 +02:00

155 lines
5.5 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("cppInterfaceName");
}
// 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;
}
bool Interface::verifyWithRegions() const {
return def->getValueAsBit("verifyWithRegions");
}
//===----------------------------------------------------------------------===//
// 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");
}