diff --git a/mlir/test/lib/Dialect/Test/TestAttrDefs.td b/mlir/test/lib/Dialect/Test/TestAttrDefs.td index 5685004bbbd25..95717acb4acbe 100644 --- a/mlir/test/lib/Dialect/Test/TestAttrDefs.td +++ b/mlir/test/lib/Dialect/Test/TestAttrDefs.td @@ -57,6 +57,36 @@ def CompoundAttrNested : Test_Attr<"CompoundAttrNested"> { let assemblyFormat = "`<` `nested` `=` $nested `>`"; } +// Nested attributes for reproducing. +def InternalAttr : Test_Attr<"Internal"> { + let mnemonic = "internal"; + + let parameters = (ins + "int64_t":$key, + "int64_t":$value + ); + + let assemblyFormat = "`<` struct(params) `>`"; +} + +def ExternalAttr : Test_Attr<"External"> { + let mnemonic = "external"; + + let parameters = (ins InternalAttr:$internal); + + let assemblyFormat = "`<` struct(params) `>`"; +} + +def ExternalArrayAttr : Test_Attr<"ExternalArray"> { + let mnemonic = "external_array"; + + let parameters = (ins + ArrayRefParameter<"InternalAttr">:$internals + ); + + let assemblyFormat = "`<` `[` struct(params) `]` `>`"; +} + // An attribute testing AttributeSelfTypeParameter. def AttrWithSelfTypeParam : Test_Attr<"AttrWithSelfTypeParam", [TypedAttrInterface]> { diff --git a/mlir/test/mlir-tblgen/op-format.mlir b/mlir/test/mlir-tblgen/op-format.mlir index fa929c2df9d10..60f8f2badef12 100644 --- a/mlir/test/mlir-tblgen/op-format.mlir +++ b/mlir/test/mlir-tblgen/op-format.mlir @@ -345,6 +345,27 @@ module attributes {test.someAttr = #test.cmpnd_nested_outer} { +// CHECK-NEXT: } +module attributes {test.internal = #test.internal} { +} + +//----- + +// CHECK: module attributes {test.external = #test.external>} { +// CHECK-NEXT: } +module attributes {test.external = #test.external>} { +} + +//----- + +// CHECK: module attributes {test.external_array = #test.external_array<[internals = , ]>} { +// CHECK-NEXT: } +module attributes {test.external_array = #test.external_array<[internals = , ]>} { +} + +//----- + // CHECK: test.format_cpmd_nested_attr nested >> test.format_cpmd_nested_attr nested >> diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp index 34547e9fed062..73caeb2621e7b 100644 --- a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp +++ b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp @@ -141,6 +141,25 @@ class StructDirective } // namespace +/// Return true if the provided parameter should always be printed in qualified +/// form (i.e., with dialect/type prefixes). Attribute and type parameters fall +/// into this category to avoid ambiguity when nested within structured +/// properties. +static bool shouldPrintQualified(ParameterElement *param) { + const AttrOrTypeParameter ¶meter = param->getParam(); + StringRef cppType = parameter.getCppType(); + if (!cppType.contains("Attr") && !cppType.contains("Type")) + return false; + + if (parameter.getPrinter()) + return false; + + if (cppType.contains("mlir::Attribute") || cppType.contains("mlir::Type")) + return true; + + return false; +} + //===----------------------------------------------------------------------===// // Format Strings //===----------------------------------------------------------------------===// @@ -872,6 +891,8 @@ void DefFormat::genCommaSeparatedPrinter( } os << tgfmt("if (!_firstPrinted) $_printer << \", \";\n", &ctx); os << "_firstPrinted = false;\n"; + if (param && shouldPrintQualified(param)) + param->setShouldBeQualified(); extra(arg); shouldEmitSpace = false; lastWasPunctuation = true;