@@ -736,6 +736,84 @@ 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: _seen_v2 = true;
767+ // ATTR: _result_v2 = ::mlir::FieldParser<AttrParamB>::parse(odsParser);
768+ // ATTR: if (::mlir::failed(_result_v2)) {
769+ // ATTR: odsParser.emitError(odsParser.getCurrentLocation(), "failed to parse AttrT parameter 'v2' which is to be a `AttrParamB`");
770+ // ATTR: return {};
771+ // ATTR: }
772+ // ATTR: } else {
773+ // ATTR: return {};
774+ // ATTR: }
775+ // ATTR: return true;
776+ // ATTR: }
777+ // ATTR: do {
778+ // ATTR: ::llvm::StringRef _paramKey;
779+ // ATTR: if (odsParser.parseKeyword(&_paramKey)) {
780+ // ATTR: odsParser.emitError(odsParser.getCurrentLocation(),
781+ // ATTR-NEXT: "expected a parameter name in struct");
782+ // ATTR: return {};
783+ // ATTR: }
784+ // ATTR: if (!_loop_body(_paramKey)) return {};
785+ // ATTR: } while(!odsParser.parseOptionalComma());
786+ // ATTR: if (!_seen_v0)
787+ // ATTR: if (!_seen_v1)
788+ // ATTR: return TestTAttr::get(odsParser.getContext(),
789+ // ATTR: TestParamA((*_result_v0)),
790+ // ATTR: TestParamB((*_result_v1)),
791+ // ATTR: AttrParamB((_result_v2.value_or(AttrParamB()))));
792+ // ATTR: }
793+
794+ // ATTR: void TestTAttr::print(::mlir::AsmPrinter &odsPrinter) const {
795+ // ATTR: odsPrinter << "v0 = ";
796+ // ATTR: ::printAttrParamA(odsPrinter, getV0());
797+ // ATTR: odsPrinter << ", ";
798+ // ATTR: odsPrinter << "v1 = ";
799+ // ATTR: printNestedCustom(odsPrinter,
800+ // ATTR-NEXT: getV1());
801+ // ATTR: if (!(getV2() == AttrParamB())) {
802+ // ATTR: odsPrinter << "v2 = ";
803+ // ATTR: odsPrinter.printStrippedAttrOrType(getV2());
804+ // ATTR: }
805+
806+ def AttrT : TestAttr<"TestT"> {
807+ let parameters = (ins
808+ AttrParamA:$v0,
809+ AttrParamB:$v1,
810+ OptionalParameter<"AttrParamB">:$v2
811+ );
812+
813+ let mnemonic = "attr_t";
814+ let assemblyFormat = "`{` struct($v0, custom<NestedCustom>($v1), $v2) `}`";
815+ }
816+
739817// DEFAULT_TYPE_PARSER: TestDialect::parseType(::mlir::DialectAsmParser &parser)
740818// DEFAULT_TYPE_PARSER: auto parseResult = parseOptionalDynamicType(mnemonic, parser, genType);
741819// DEFAULT_TYPE_PARSER: if (parseResult.has_value()) {
0 commit comments