Index: mlir/include/mlir/IR/OpBase.td =================================================================== --- mlir/include/mlir/IR/OpBase.td +++ mlir/include/mlir/IR/OpBase.td @@ -2207,9 +2207,14 @@ // If an empty string is passed in for `body`, then *only* the builder // declaration will be generated; this provides a way to define complicated // builders entirely in C++. -class OpBuilder { +// +// Optionally, a deprecation message can be passed as third parameter, marking +// the generated 'build' method as deprecated using the specified message if +// the message is not empty. +class OpBuilder { dag dagParams = p; code body = b; + string deprecated_message = d; } // A base decorator class that may optionally be added to OpVariables. Index: mlir/include/mlir/TableGen/Builder.h =================================================================== --- mlir/include/mlir/TableGen/Builder.h +++ mlir/include/mlir/TableGen/Builder.h @@ -70,6 +70,10 @@ /// Return an optional string containing the body of the builder. std::optional getBody() const; + /// Return the deprecation message of the builder. + /// Empty optional if the builder is not deprecated. + std::optional getDeprecatedMessage() const; + protected: /// The TableGen definition of this builder. const llvm::Record *def; Index: mlir/include/mlir/TableGen/Class.h =================================================================== --- mlir/include/mlir/TableGen/Class.h +++ mlir/include/mlir/TableGen/Class.h @@ -329,6 +329,11 @@ /// Get the method body. MethodBody &body() { return methodBody; } + /// Sets or removes the deprecation message of the method. + void setDeprecated(std::optional message) { + this->deprecationMessage = message; + } + /// Returns true if this is a static method. bool isStatic() const { return properties & Static; } @@ -369,6 +374,8 @@ MethodSignature methodSignature; /// The body of the method, if it has one. MethodBody methodBody; + /// Deprecation message if the method is deprecated. + std::optional deprecationMessage; }; /// This enum describes C++ inheritance visibility. Index: mlir/lib/TableGen/Builder.cpp =================================================================== --- mlir/lib/TableGen/Builder.cpp +++ mlir/lib/TableGen/Builder.cpp @@ -81,3 +81,9 @@ std::optional body = def->getValueAsOptionalString("body"); return body && !body->empty() ? body : std::nullopt; } + +std::optional Builder::getDeprecatedMessage() const { + std::optional message = + def->getValueAsOptionalString("deprecated_message"); + return message && !message->empty() ? message : std::nullopt; +} Index: mlir/lib/TableGen/Class.cpp =================================================================== --- mlir/lib/TableGen/Class.cpp +++ mlir/lib/TableGen/Class.cpp @@ -114,6 +114,11 @@ //===----------------------------------------------------------------------===// void Method::writeDeclTo(raw_indented_ostream &os) const { + if (deprecationMessage) { + os << "[[deprecated(\""; + os.write_escaped(*deprecationMessage); + os << "\")]]\n"; + } if (isStatic()) os << "static "; if (properties & ConstexprValue) Index: mlir/test/mlir-tblgen/op-decl-and-defs.td =================================================================== --- mlir/test/mlir-tblgen/op-decl-and-defs.td +++ mlir/test/mlir-tblgen/op-decl-and-defs.td @@ -37,7 +37,9 @@ VariadicRegion:$someRegions ); let builders = [OpBuilder<(ins "Value":$val)>, - OpBuilder<(ins CArg<"int", "0">:$integer)>]; + OpBuilder<(ins CArg<"int", "0">:$integer)>, + OpBuilder<(ins "float":$something), "", + "the deprecation message">]; let hasCustomAssemblyFormat = 1; let hasCanonicalizer = 1; @@ -106,6 +108,8 @@ // CHECK: ::mlir::Attribute removeSomeAttr2Attr(); // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, Value val); // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, int integer = 0); +// CHECK{LITERAL}: [[deprecated("the deprecation message")]] +// CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, float something); // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type r, ::mlir::TypeRange s, ::mlir::Value a, ::mlir::ValueRange b, ::mlir::IntegerAttr attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount) // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::ValueRange b, ::mlir::IntegerAttr attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount); // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type r, ::mlir::TypeRange s, ::mlir::Value a, ::mlir::ValueRange b, uint32_t attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount) Index: mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp =================================================================== --- mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -1965,6 +1965,9 @@ if (body) ERROR_IF_PRUNED(method, "build", op); + if (method) + method->setDeprecated(builder.getDeprecatedMessage()); + FmtContext fctx; fctx.withBuilder(odsBuilder); fctx.addSubst("_state", builderOpState);