Index: mlir/include/mlir/IR/AttrTypeBase.td =================================================================== --- mlir/include/mlir/IR/AttrTypeBase.td +++ mlir/include/mlir/IR/AttrTypeBase.td @@ -215,6 +215,11 @@ // Extra code to include in the class declaration. code extraClassDeclaration = [{}]; + + // Additional code that will be added to the generated source file. The + // generated code is placed inside the attribute's C++ namespace. `$cppClass` is + // replaced by the attribute's class name. + code extraClassDefinition = [{}]; } // Define a new attribute, named `name`, belonging to `dialect` that inherits Index: mlir/include/mlir/TableGen/AttrOrTypeDef.h =================================================================== --- mlir/include/mlir/TableGen/AttrOrTypeDef.h +++ mlir/include/mlir/TableGen/AttrOrTypeDef.h @@ -198,6 +198,9 @@ /// Returns the def's extra class declaration code. Optional getExtraDecls() const; + /// Returns the def's extra class definition code. + Optional getExtraDefs() const; + /// Get the code location (for error printing). ArrayRef getLoc() const; Index: mlir/lib/TableGen/AttrOrTypeDef.cpp =================================================================== --- mlir/lib/TableGen/AttrOrTypeDef.cpp +++ mlir/lib/TableGen/AttrOrTypeDef.cpp @@ -175,6 +175,11 @@ return value.empty() ? Optional() : value; } +Optional AttrOrTypeDef::getExtraDefs() const { + auto value = def->getValueAsString("extraClassDefinition"); + return value.empty() ? Optional() : value; +} + ArrayRef AttrOrTypeDef::getLoc() const { return def->getLoc(); } bool AttrOrTypeDef::skipDefaultBuilders() const { Index: mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp =================================================================== --- mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp +++ mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp @@ -97,6 +97,8 @@ void emitAccessors(); /// Emit interface methods. void emitInterfaceMethods(); + /// Emit extra class definition, if specified. + void emitExtraClassDefinition(); //===--------------------------------------------------------------------===// // Builder Emission @@ -157,6 +159,8 @@ StringRef valueType; /// The prefix/suffix of the TableGen def name, either "Attr" or "Type". StringRef defType; + /// Hand-written extra class definitions. + std::string extraClassDefinition; }; } // namespace @@ -191,6 +195,8 @@ emitAccessors(); // Emit trait interface methods emitInterfaceMethods(); + // Emit hand written class definitions + emitExtraClassDefinition(); defCls.finalize(); // Emit a storage class if one is needed if (storageCls && def.genStorageClass()) @@ -214,6 +220,14 @@ defCls.addParent(std::move(defParent)); } +void DefGen::emitExtraClassDefinition() { + if (Optional extraDef = def.getExtraDefs()) { + FmtContext ctx = FmtContext().addSubst("cppClass", def.getCppClassName()); + extraClassDefinition = tgfmt(*extraDef, &ctx).str(); + defCls.declare("", extraClassDefinition); + } +} + void DefGen::emitTopLevelDeclarations() { // Inherit constructors from the attribute or type class. defCls.declare(Visibility::Public);