[Mlir-commits] [mlir] [MLIR][TableGen] Add inheritableExtraClassDeclaration/Definition for Op and AttrOrTypeDef (PR #182265)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Feb 19 06:59:00 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Henrich Lauko (xlauko)
<details>
<summary>Changes</summary>
Add new `inheritableExtraClassDeclaration` and `inheritableExtraClassDefinition` fields to `Op` and `AttrOrTypeDef` in TableGen.
Motivation: The existing `extraClassDeclaration`/`extraClassDefinition` fields follow standard TableGen override semantics: when a derived class sets them, the base class value is lost. This means a base op class like `MyDialectOp` cannot provide shared declarations that are automatically inherited by all concrete ops without the concrete ops manually concatenating them. Concatenation can get quickly out of hand if you inherit multiple classes.
Desing: The backend concatenates `inheritableExtraClassDeclaration`/`inheritableExtraClassDefinition` with the existing `extraClassDeclaration`/`extraClassDefinition` automatically, so both appear in the generated code.
A derived class can discard inherited declarations by setting these fields to empty `[{}]`.
---
Patch is 20.93 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/182265.diff
11 Files Affected:
- (modified) mlir/include/mlir/IR/AttrTypeBase.td (+9)
- (modified) mlir/include/mlir/IR/OpBase.td (+9)
- (modified) mlir/include/mlir/TableGen/AttrOrTypeDef.h (+14)
- (modified) mlir/include/mlir/TableGen/Operator.h (+10)
- (modified) mlir/lib/TableGen/AttrOrTypeDef.cpp (+42)
- (modified) mlir/lib/TableGen/Operator.cpp (+11)
- (modified) mlir/test/mlir-tblgen/attrdefs.td (+82)
- (modified) mlir/test/mlir-tblgen/op-decl-and-defs.td (+98)
- (modified) mlir/test/mlir-tblgen/typedefs.td (+82)
- (modified) mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp (+6-2)
- (modified) mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp (+6-2)
``````````diff
diff --git a/mlir/include/mlir/IR/AttrTypeBase.td b/mlir/include/mlir/IR/AttrTypeBase.td
index 16f7f8b532521..eee78eb8c2a94 100644
--- a/mlir/include/mlir/IR/AttrTypeBase.td
+++ b/mlir/include/mlir/IR/AttrTypeBase.td
@@ -250,6 +250,15 @@ class AttrOrTypeDef<string valueType, string name, list<Trait> defTraits,
// replaced by the class name.
code extraClassDefinition = [{}];
+ // Extra class declarations/definitions that are inherited by all derived
+ // classes. These can be set at any level in the class hierarchy. Unlike
+ // extraClassDeclaration/extraClassDefinition, the inheritable values carry
+ // over to all derived classes — both the inheritable and the regular extra
+ // declarations are concatenated in the generated code. A derived class can
+ // discard inherited declarations by setting these to empty [{}].
+ code inheritableExtraClassDeclaration = [{}];
+ code inheritableExtraClassDefinition = [{}];
+
// Generate a default 'getAlias' method for OpAsm{Type,Attr}Interface.
bit genMnemonicAlias = 0;
}
diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td
index 7a667d701ab71..4d288c6fc09f4 100644
--- a/mlir/include/mlir/IR/OpBase.td
+++ b/mlir/include/mlir/IR/OpBase.td
@@ -440,6 +440,15 @@ class Op<Dialect dialect, string mnemonic, list<Trait> props = []> {
// generated code is placed inside the op's C++ namespace. `$cppClass` is
// replaced by the op's C++ class name.
code extraClassDefinition = ?;
+
+ // Extra class declarations/definitions that are inherited by all derived op
+ // classes. These can be set at any level in the class hierarchy. Unlike
+ // extraClassDeclaration/extraClassDefinition, the inheritable values carry
+ // over to all derived ops — both the inheritable and the regular extra
+ // declarations are concatenated in the generated code. A derived class can
+ // discard inherited declarations by setting these to empty [{}].
+ code inheritableExtraClassDeclaration = [{}];
+ code inheritableExtraClassDefinition = [{}];
}
// The arguments of an op.
diff --git a/mlir/include/mlir/TableGen/AttrOrTypeDef.h b/mlir/include/mlir/TableGen/AttrOrTypeDef.h
index 65992f9fef5e9..cd0b066297320 100644
--- a/mlir/include/mlir/TableGen/AttrOrTypeDef.h
+++ b/mlir/include/mlir/TableGen/AttrOrTypeDef.h
@@ -216,6 +216,14 @@ class AttrOrTypeDef {
/// Returns the def's extra class definition code.
std::optional<StringRef> getExtraDefs() const;
+ /// Collects inheritable extra class declarations accumulated across the
+ /// class hierarchy into `result`.
+ void getInheritableExtraDecls(SmallVectorImpl<StringRef> &result) const;
+
+ /// Collects inheritable extra class definitions accumulated across the
+ /// class hierarchy into `result`.
+ void getInheritableExtraDefs(SmallVectorImpl<StringRef> &result) const;
+
/// Returns true if we need to generate a default 'getAlias' implementation
/// using the mnemonic.
bool genMnemonicAlias() const;
@@ -293,6 +301,12 @@ class TypeDef : public AttrOrTypeDef {
StringRef getTypeName() const;
};
+/// Walk the superclass chain of `def` and accumulate distinct values of
+/// `fieldName` into `result`. Used to collect inheritable extra class
+/// declarations/definitions across the TableGen class hierarchy.
+void accumulateInheritableField(const llvm::Record &def, StringRef fieldName,
+ SmallVectorImpl<StringRef> &result);
+
} // namespace tblgen
} // namespace mlir
diff --git a/mlir/include/mlir/TableGen/Operator.h b/mlir/include/mlir/TableGen/Operator.h
index f0514d8e61748..42c5c7a0c9d8f 100644
--- a/mlir/include/mlir/TableGen/Operator.h
+++ b/mlir/include/mlir/TableGen/Operator.h
@@ -303,6 +303,16 @@ class Operator {
/// Returns this op's extra class definition code.
StringRef getExtraClassDefinition() const;
+ /// Collects inheritable extra class declarations accumulated across the
+ /// class hierarchy into `result`.
+ void getInheritableExtraClassDeclarations(
+ SmallVectorImpl<StringRef> &result) const;
+
+ /// Collects inheritable extra class definitions accumulated across the
+ /// class hierarchy into `result`.
+ void
+ getInheritableExtraClassDefinitions(SmallVectorImpl<StringRef> &result) const;
+
/// Returns the Tablegen definition this operator was constructed from.
/// TODO: do not expose the TableGen record, this is a temporary solution to
/// OpEmitter requiring a Record because Operator does not provide enough
diff --git a/mlir/lib/TableGen/AttrOrTypeDef.cpp b/mlir/lib/TableGen/AttrOrTypeDef.cpp
index bf835a860cd5b..380dea745e105 100644
--- a/mlir/lib/TableGen/AttrOrTypeDef.cpp
+++ b/mlir/lib/TableGen/AttrOrTypeDef.cpp
@@ -207,6 +207,48 @@ std::optional<StringRef> AttrOrTypeDef::getExtraDefs() const {
return value.empty() ? std::optional<StringRef>() : value;
}
+void mlir::tblgen::accumulateInheritableField(
+ const Record &def, StringRef fieldName,
+ SmallVectorImpl<StringRef> &result) {
+ auto getFieldValue = [&](const Record *rec) -> StringRef {
+ const auto *val = rec->getValue(fieldName);
+ if (!val)
+ return {};
+ const auto *si = dyn_cast<StringInit>(val->getValue());
+ return si ? si->getValue() : StringRef();
+ };
+
+ // Track the previous value to detect when a class explicitly sets the field
+ // vs. merely inheriting it unchanged from a parent.
+ StringRef prev;
+ auto accumulate = [&](StringRef value) {
+ if (value == prev)
+ return;
+ // An empty value means the class opted out of inherited declarations,
+ // so discard everything accumulated so far.
+ if (value.empty())
+ result.clear();
+ else
+ result.push_back(value);
+ prev = value;
+ };
+
+ for (const Record *rec : def.getSuperClasses())
+ accumulate(getFieldValue(rec));
+ // The concrete def itself may also override the field.
+ accumulate(def.getValueAsString(fieldName));
+}
+
+void AttrOrTypeDef::getInheritableExtraDecls(
+ SmallVectorImpl<StringRef> &result) const {
+ accumulateInheritableField(*def, "inheritableExtraClassDeclaration", result);
+}
+
+void AttrOrTypeDef::getInheritableExtraDefs(
+ SmallVectorImpl<StringRef> &result) const {
+ accumulateInheritableField(*def, "inheritableExtraClassDefinition", result);
+}
+
bool AttrOrTypeDef::genMnemonicAlias() const {
return def->getValueAsBit("genMnemonicAlias");
}
diff --git a/mlir/lib/TableGen/Operator.cpp b/mlir/lib/TableGen/Operator.cpp
index 82dfbcbfa4d4f..c14d374c889ed 100644
--- a/mlir/lib/TableGen/Operator.cpp
+++ b/mlir/lib/TableGen/Operator.cpp
@@ -12,6 +12,7 @@
#include "mlir/TableGen/Operator.h"
#include "mlir/TableGen/Argument.h"
+#include "mlir/TableGen/AttrOrTypeDef.h"
#include "mlir/TableGen/Predicate.h"
#include "mlir/TableGen/Trait.h"
#include "mlir/TableGen/Type.h"
@@ -180,6 +181,16 @@ StringRef Operator::getExtraClassDefinition() const {
return def.getValueAsString(attr);
}
+void Operator::getInheritableExtraClassDeclarations(
+ SmallVectorImpl<StringRef> &result) const {
+ accumulateInheritableField(def, "inheritableExtraClassDeclaration", result);
+}
+
+void Operator::getInheritableExtraClassDefinitions(
+ SmallVectorImpl<StringRef> &result) const {
+ accumulateInheritableField(def, "inheritableExtraClassDefinition", result);
+}
+
const Record &Operator::getDef() const { return def; }
bool Operator::skipDefaultBuilders() const {
diff --git a/mlir/test/mlir-tblgen/attrdefs.td b/mlir/test/mlir-tblgen/attrdefs.td
index a809611fd0aec..25b009f5ec14b 100644
--- a/mlir/test/mlir-tblgen/attrdefs.td
+++ b/mlir/test/mlir-tblgen/attrdefs.td
@@ -204,3 +204,85 @@ def J_CustomStorageCtorAttr : AttrDef<Test_Dialect, "CustomStorageCtorAttr"> {
// DEF-LABEL: struct CustomStorageCtorAttrAttrStorage : public ::mlir::AttributeStorage
// DEF: static CustomStorageCtorAttrAttrStorage *construct
// DEF-SAME: (::mlir::AttributeStorageAllocator &allocator, KeyTy &&tblgenKey);
+
+// Test inheritable extra class declarations/definitions for attributes.
+
+class InheritableTestAttr<string name> : AttrDef<Test_Dialect, name> {
+ let inheritableExtraClassDeclaration = [{
+ int getInheritedHelper();
+ }];
+ let inheritableExtraClassDefinition = [{
+ int $cppClass::getInheritedHelper() { return 42; }
+ }];
+}
+
+// Both inheritable and regular extra declarations should appear.
+def K_InheritableAttrA : InheritableTestAttr<"InheritableA"> {
+ let attrName = "test.inheritable_a";
+ let extraClassDeclaration = [{
+ void doA();
+ }];
+ let extraClassDefinition = [{
+ void $cppClass::doA() {}
+ }];
+}
+
+// DECL-LABEL: class InheritableAAttr
+// DECL: int getInheritedHelper();
+// DECL: void doA();
+
+// DEF-LABEL: int InheritableAAttr::getInheritedHelper()
+// DEF: return 42;
+// DEF-LABEL: void InheritableAAttr::doA()
+
+// Only inheritable declarations (no extraClassDeclaration).
+def L_InheritableAttrB : InheritableTestAttr<"InheritableB"> {
+ let attrName = "test.inheritable_b";
+}
+
+// DECL-LABEL: class InheritableBAttr
+// DECL: int getInheritedHelper();
+
+// Discard inheritable declarations by setting to empty.
+def M_InheritableAttrC : InheritableTestAttr<"InheritableC"> {
+ let attrName = "test.inheritable_c";
+ let inheritableExtraClassDeclaration = [{}];
+ let inheritableExtraClassDefinition = [{}];
+}
+
+// DECL-LABEL: class InheritableCAttr
+// DECL-NOT: int getInheritedHelper();
+
+// Middle-of-stack: accumulates with base inheritable declarations.
+class InheritableMiddleAttr<string name> : InheritableTestAttr<name> {
+ let inheritableExtraClassDeclaration = [{
+ int getMiddleHelper();
+ }];
+ let inheritableExtraClassDefinition = [{
+ int $cppClass::getMiddleHelper() { return 1; }
+ }];
+}
+
+// Concrete attr inheriting from middle gets both base and middle.
+def N_InheritableAttrD : InheritableMiddleAttr<"InheritableD"> {
+ let attrName = "test.inheritable_d";
+}
+
+// DECL-LABEL: class InheritableDAttr
+// DECL: int getInheritedHelper();
+// DECL: int getMiddleHelper();
+
+// DEF-LABEL: int InheritableDAttr::getInheritedHelper()
+// DEF: return 42;
+// DEF-LABEL: int InheritableDAttr::getMiddleHelper()
+// DEF: return 1;
+
+// Passthrough: middle class doesn't set inheritable, base value passes through.
+class InheritablePassthroughAttr<string name> : InheritableTestAttr<name> {}
+
+def O_InheritableAttrE : InheritablePassthroughAttr<"InheritableE"> {
+ let attrName = "test.inheritable_e";
+}
+
+// DECL-LABEL: class InheritableEAttr
+// DECL: int getInheritedHelper();
diff --git a/mlir/test/mlir-tblgen/op-decl-and-defs.td b/mlir/test/mlir-tblgen/op-decl-and-defs.td
index 80dedb8475b9e..d9bda6adb7dbb 100644
--- a/mlir/test/mlir-tblgen/op-decl-and-defs.td
+++ b/mlir/test/mlir-tblgen/op-decl-and-defs.td
@@ -360,6 +360,43 @@ def NS_IOp : NS_Op<"op_with_same_operands_and_result_types_trait", [SameOperands
// CHECK: static IOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {});
// CHECK: static IOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {});
+// CHECK-LABEL: NS::InheritableOpA declarations
+// CHECK: int getInheritedHelper();
+// CHECK: void doA();
+
+// CHECK-LABEL: NS::InheritableOpB declarations
+// CHECK: int getInheritedHelper();
+
+// Discard: no inheritable declarations.
+// CHECK-LABEL: NS::InheritableOpC declarations
+// CHECK-NOT: int getInheritedHelper();
+
+// Middle-of-stack: gets both base and middle inheritable declarations.
+// CHECK-LABEL: NS::InheritableOpD declarations
+// CHECK: int getInheritedHelper();
+// CHECK: int getMiddleHelper();
+
+// Middle-of-stack with own extraClassDeclaration.
+// CHECK-LABEL: NS::InheritableOpE declarations
+// CHECK: int getInheritedHelper();
+// CHECK: int getMiddleHelper();
+// CHECK: void doE();
+
+// Passthrough: middle class doesn't set inheritable, base value passes through.
+// CHECK-LABEL: NS::InheritableOpF declarations
+// CHECK: int getInheritedHelper();
+
+// DEFS-LABEL: NS::InheritableOpA definitions
+// DEFS: int InheritableOpA::getInheritedHelper() { return 42; }
+// DEFS: void InheritableOpA::doA() {}
+
+// DEFS-LABEL: NS::InheritableOpD definitions
+// DEFS: int InheritableOpD::getInheritedHelper() { return 42; }
+// DEFS: int InheritableOpD::getMiddleHelper() { return 1; }
+
+// DEFS-LABEL: NS::InheritableOpF definitions
+// DEFS: int InheritableOpF::getInheritedHelper() { return 42; }
+
// Check default value of `attributes` for the `genInferredTypeCollectiveParamBuilder` builder
def NS_JOp : NS_Op<"op_with_InferTypeOpInterface_interface", [DeclareOpInterfaceMethods<InferTypeOpInterface>]> {
let arguments = (ins AnyType:$a, AnyType:$b);
@@ -551,3 +588,64 @@ def _TypeInferredPropOp : NS_Op<"type_inferred_prop_op_with_properties", [
let results = (outs AnyType:$result);
let hasCustomAssemblyFormat = 1;
}
+
+// Test inheritable extra class declarations/definitions.
+class NS_InheritableOp<string mnemonic, list<Trait> traits = []>
+ : NS_Op<mnemonic, traits> {
+ let inheritableExtraClassDeclaration = [{
+ int getInheritedHelper();
+ }];
+ let inheritableExtraClassDefinition = [{
+ int $cppClass::getInheritedHelper() { return 42; }
+ }];
+}
+
+// Both inheritable and regular extra declarations should appear.
+def NS_InheritableOpA : NS_InheritableOp<"inheritable_op_a"> {
+ let extraClassDeclaration = [{
+ void doA();
+ }];
+ let extraClassDefinition = [{
+ void $cppClass::doA() {}
+ }];
+}
+
+// Only inheritable declarations (no extraClassDeclaration).
+def NS_InheritableOpB : NS_InheritableOp<"inheritable_op_b"> {}
+
+// Discard inheritable declarations by setting to empty.
+def NS_InheritableOpC : NS_InheritableOp<"inheritable_op_c"> {
+ let inheritableExtraClassDeclaration = [{}];
+ let inheritableExtraClassDefinition = [{}];
+}
+
+// Middle-of-stack: NS_Op -> NS_InheritableOp -> NS_InheritableMiddleOp
+// The middle class adds its own inheritableExtraClassDeclaration. Concrete ops
+// get both the base and middle inheritable declarations (accumulated).
+class NS_InheritableMiddleOp<string mnemonic, list<Trait> traits = []>
+ : NS_InheritableOp<mnemonic, traits> {
+ let inheritableExtraClassDeclaration = [{
+ int getMiddleHelper();
+ }];
+ let inheritableExtraClassDefinition = [{
+ int $cppClass::getMiddleHelper() { return 1; }
+ }];
+}
+
+// Concrete op inheriting from middle class gets the middle class's value.
+def NS_InheritableOpD : NS_InheritableMiddleOp<"inheritable_op_d"> {}
+
+// Concrete op inheriting from middle class with its own extraClassDeclaration.
+def NS_InheritableOpE : NS_InheritableMiddleOp<"inheritable_op_e"> {
+ let extraClassDeclaration = [{
+ void doE();
+ }];
+}
+
+// Middle class that does NOT set inheritableExtraClassDeclaration — inherits
+// the base class value and passes it through to concrete ops.
+class NS_InheritablePassthroughOp<string mnemonic, list<Trait> traits = []>
+ : NS_InheritableOp<mnemonic, traits> {}
+
+// Concrete op gets the original base class inheritable declarations.
+def NS_InheritableOpF : NS_InheritablePassthroughOp<"inheritable_op_f"> {}
diff --git a/mlir/test/mlir-tblgen/typedefs.td b/mlir/test/mlir-tblgen/typedefs.td
index b9e3a7954e361..74524e192493f 100644
--- a/mlir/test/mlir-tblgen/typedefs.td
+++ b/mlir/test/mlir-tblgen/typedefs.td
@@ -153,3 +153,85 @@ def E_IntegerType : TestType<"Integer"> {
// DECL-NEXT: /// Return true if this is an unsigned integer type.
// DECL-NEXT: bool isUnsigned() const { return getSignedness() == Unsigned; }
}
+
+// Test inheritable extra class declarations/definitions for types.
+
+class InheritableTestType<string name> : TypeDef<Test_Dialect, name> {
+ let inheritableExtraClassDeclaration = [{
+ int getInheritedHelper();
+ }];
+ let inheritableExtraClassDefinition = [{
+ int $cppClass::getInheritedHelper() { return 42; }
+ }];
+}
+
+// Both inheritable and regular extra declarations should appear.
+def F_InheritableTypeA : InheritableTestType<"InheritableA"> {
+ let typeName = "test.inheritable_a";
+ let extraClassDeclaration = [{
+ void doA();
+ }];
+ let extraClassDefinition = [{
+ void $cppClass::doA() {}
+ }];
+}
+
+// DECL-LABEL: class InheritableAType
+// DECL: int getInheritedHelper();
+// DECL: void doA();
+
+// DEF-LABEL: int InheritableAType::getInheritedHelper()
+// DEF: return 42;
+// DEF-LABEL: void InheritableAType::doA()
+
+// Only inheritable declarations (no extraClassDeclaration).
+def G_InheritableTypeB : InheritableTestType<"InheritableB"> {
+ let typeName = "test.inheritable_b";
+}
+
+// DECL-LABEL: class InheritableBType
+// DECL: int getInheritedHelper();
+
+// Discard inheritable declarations by setting to empty.
+def H_InheritableTypeC : InheritableTestType<"InheritableC"> {
+ let typeName = "test.inheritable_c";
+ let inheritableExtraClassDeclaration = [{}];
+ let inheritableExtraClassDefinition = [{}];
+}
+
+// DECL-LABEL: class InheritableCType
+// DECL-NOT: int getInheritedHelper();
+
+// Middle-of-stack: accumulates with base inheritable declarations.
+class InheritableMiddleType<string name> : InheritableTestType<name> {
+ let inheritableExtraClassDeclaration = [{
+ int getMiddleHelper();
+ }];
+ let inheritableExtraClassDefinition = [{
+ int $cppClass::getMiddleHelper() { return 1; }
+ }];
+}
+
+// Concrete type inheriting from middle gets both base and middle.
+def I_InheritableTypeD : InheritableMiddleType<"InheritableD"> {
+ let typeName = "test.inheritable_d";
+}
+
+// DECL-LABEL: class InheritableDType
+// DECL: int getInheritedHelper();
+// DECL: int getMiddleHelper();
+
+// DEF-LABEL: int InheritableDType::getInheritedHelper()
+// DEF: return 42;
+// DEF-LABEL: int InheritableDType::getMiddleHelper()
+// DEF: return 1;
+
+// Passthrough: middle class doesn't set inheritable, base value passes through.
+class InheritablePassthroughType<string name> : InheritableTestType<name> {}
+
+def J_InheritableTypeE : InheritablePassthroughType<"InheritableE"> {
+ let typeName = "test.inheritable_e";
+}
+
+// DECL-LABEL: class InheritableEType
+// DECL: int getInheritedHelper();
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index 031e03071842f..de4c3be8f2377 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -273,7 +273,9 @@ void DefGen::createParentWithTraits() {
/// Include declarations specified on NativeTrait
static std::string formatExtraDeclarations(const AttrOrTypeDef &def) {
SmallVector<StringRef> extraDeclarations;
- // Include extra class declarations from NativeTrait
+ // Include inheritable extra class declarations.
+ def.getInheritableExtraDecls(extraDeclarations);
+ // Include extra class declarations from NativeTrait.
for (const auto &trait : def.getTraits()) {
if (auto *attrOrTypeTrait = dyn_cast<tblgen::NativeTrait>(&trait)) {
StringRef value = attrOrTypeTrait->getExtraConcreteClassDeclaration();
@@ -292,7 +294,9 @@ static std::string formatExtraDeclarations(const AttrOrTypeDef &def) {
/// replaced by the C++ class name.
static std::string formatExtraDefinitions(const AttrOrTypeDef &def) {
SmallVector<StringRef> extraDefinitions;
- // Include extra class definitions from NativeTrait
+ // Include inheritable extra class definitions.
+ def.getInheritableExtraDefs(extraDefinitions);
+ // Include extra class definitions from NativeTrait.
for (const auto &trait : def.getTraits()) {
if (auto *attrOrTypeTrait = dyn_cast<tblgen::NativeTrait>(&trait)) {
StringRef value = attrOrTypeTrait->getExtraConcreteClassDefinition();
diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index d1f1e85371133..6c1b4d6cf3137 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -1164,7 +1164,9 @@ static void genPropertyVerifier(
/// Include declarations specified on NativeTrait
static std::string formatExtraDeclarations(const Operator &op) {
SmallVector<StringRef> extraDeclarations;
- // Include extra class declarations from NativeTrait
+ // Include inheritable extra class declaratio...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/182265
More information about the Mlir-commits
mailing list