diff --git a/mlir/test/mlir-tblgen/attrdefs.td b/mlir/test/mlir-tblgen/attrdefs.td --- a/mlir/test/mlir-tblgen/attrdefs.td +++ b/mlir/test/mlir-tblgen/attrdefs.td @@ -141,3 +141,13 @@ // DEF: ParamWithAccessorTypeAttrStorage // DEF: ParamWithAccessorTypeAttrStorage(std::string param) // DEF: StringRef ParamWithAccessorTypeAttr::getParam() + + +def G_OptionalAndDefaultValuedParams + : TestAttr<"OptionalAndDefaultValuedParams"> { + let parameters = (ins OptionalParameter<"int *">:$a, + DefaultValuedParameter<"int", "5">:$b); +} + +// DECL-LABEL: class OptionalAndDefaultValuedParamsAttr +// DECL: get(::mlir::MLIRContext *context, int *a = {}, int b = 5); diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp --- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp +++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp @@ -319,8 +319,22 @@ DefGen::getBuilderParams(std::initializer_list prefix) const { SmallVector builderParams; builderParams.append(prefix.begin(), prefix.end()); - for (auto ¶m : params) + // Optional/default-valued parameters at the end of the parameter list can be + // given default arguments in C++. + auto paramsReverse = llvm::reverse(params); + auto lastOptional = + llvm::find_if(paramsReverse, [](const AttrOrTypeParameter ¶m) { + return !param.isOptional(); + }); + for (const AttrOrTypeParameter ¶m : + llvm::reverse(llvm::make_range(lastOptional, paramsReverse.end()))) builderParams.emplace_back(param.getCppType(), param.getName()); + for (const AttrOrTypeParameter ¶m : + llvm::reverse(llvm::make_range(paramsReverse.begin(), lastOptional))) { + Optional defaultValue = param.getDefaultValue(); + builderParams.emplace_back(param.getCppType(), param.getName(), + defaultValue ? *defaultValue : "{}"); + } return builderParams; }