@@ -736,6 +736,78 @@ def TypeS : TestType<"TestS"> {
736736 let assemblyFormat = "$a";
737737}
738738
739+ /// Test that a `struct` with nested `custom` parser and printer are generated correctly.
740+
741+ // ATTR: ::mlir::Attribute TestTAttr::parse(::mlir::AsmParser &odsParser,
742+ // ATTR: ::mlir::Type odsType) {
743+ // ATTR: bool _seen_v0 = false;
744+ // ATTR: bool _seen_v1 = false;
745+ // ATTR: bool _seen_v2 = false;
746+ // ATTR: const auto _loop_body = [&](::llvm::StringRef _paramKey) -> bool {
747+ // ATTR: if (odsParser.parseEqual())
748+ // ATTR: return {};
749+ // ATTR: if (!_seen_v0 && _paramKey == "v0") {
750+ // ATTR: _seen_v0 = true;
751+ // ATTR: _result_v0 = ::parseAttrParamA(odsParser, odsType);
752+ // ATTR: if (::mlir::failed(_result_v0))
753+ // ATTR: return {};
754+ // ATTR: } else if (!_seen_v1 && _paramKey == "v1") {
755+ // ATTR: _seen_v1 = true;
756+ // ATTR: {
757+ // ATTR: auto odsCustomResult = parseNestedCustom(odsParser,
758+ // ATTR-NEXT: ::mlir::detail::unwrapForCustomParse(_result_v1));
759+ // ATTR: if (::mlir::failed(odsCustomResult)) return {};
760+ // ATTR: if (::mlir::failed(_result_v1)) {
761+ // ATTR: odsParser.emitError(odsCustomLoc, "custom parser failed to parse parameter 'v1'");
762+ // ATTR: return {};
763+ // ATTR: }
764+ // ATTR: }
765+ // ATTR: } else if (!_seen_v2 && _paramKey == "v2") {
766+ // ATTR: } else {
767+ // ATTR: return {};
768+ // ATTR: }
769+ // ATTR: return true;
770+ // ATTR: }
771+ // ATTR: do {
772+ // ATTR: ::llvm::StringRef _paramKey;
773+ // ATTR: if (odsParser.parseKeyword(&_paramKey)) {
774+ // ATTR: odsParser.emitError(odsParser.getCurrentLocation(),
775+ // ATTR-NEXT: "expected a parameter name in struct");
776+ // ATTR: return {};
777+ // ATTR: }
778+ // ATTR: if (!_loop_body(_paramKey)) return {};
779+ // ATTR: } while(!odsParser.parseOptionalComma());
780+ // ATTR: if (!_seen_v0)
781+ // ATTR: if (!_seen_v1)
782+ // ATTR: return TestTAttr::get(odsParser.getContext(),
783+ // ATTR: TestParamA((*_result_v0)),
784+ // ATTR: TestParamB((*_result_v1)),
785+ // ATTR: AttrParamB((_result_v2.value_or(AttrParamB()))));
786+ // ATTR: }
787+
788+ // ATTR: void TestTAttr::print(::mlir::AsmPrinter &odsPrinter) const {
789+ // ATTR: odsPrinter << "v0 = ";
790+ // ATTR: ::printAttrParamA(odsPrinter, getV0());
791+ // ATTR: odsPrinter << ", ";
792+ // ATTR: odsPrinter << "v1 = ";
793+ // ATTR: printNestedCustom(odsPrinter,
794+ // ATTR-NEXT: getV1());
795+ // ATTR: if (!(getV2() == AttrParamB())) {
796+ // ATTR: odsPrinter << "v2 = ";
797+ // ATTR: odsPrinter.printStrippedAttrOrType(getV2());
798+ // ATTR: }
799+
800+ def AttrT : TestAttr<"TestT"> {
801+ let parameters = (ins
802+ AttrParamA:$v0,
803+ AttrParamB:$v1,
804+ OptionalParameter<"AttrParamB">:$v2
805+ );
806+
807+ let mnemonic = "attr_t";
808+ let assemblyFormat = "`{` struct($v0, custom<NestedCustom>($v1), $v2) `}`";
809+ }
810+
739811// DEFAULT_TYPE_PARSER: TestDialect::parseType(::mlir::DialectAsmParser &parser)
740812// DEFAULT_TYPE_PARSER: auto parseResult = parseOptionalDynamicType(mnemonic, parser, genType);
741813// DEFAULT_TYPE_PARSER: if (parseResult.has_value()) {
0 commit comments