@@ -2883,113 +2883,117 @@ LogicalResult cir::TypeInfoAttr::verify(
28832883// ===----------------------------------------------------------------------===//
28842884
28852885void cir::TryOp::getSuccessorRegions (
2886- mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ions) {
2887- // If any index all the underlying regions branch back to the parent
2888- // operation.
2886+ mlir::RegionBranchPoint point,
2887+ llvm::SmallVectorImpl<mlir::RegionSuccessor> & regions) {
2888+ // The `try` and the `catchers` region branch back to the parent operation.
28892889 if (!point.isParent ()) {
2890- regions.push_back (RegionSuccessor ());
2890+ regions.push_back (mlir:: RegionSuccessor ());
28912891 return ;
28922892 }
28932893
2894- // If the condition isn't constant, both regions may be executed.
2895- regions.push_back (RegionSuccessor (&getTryRegion ()));
2894+ regions.push_back (mlir::RegionSuccessor (&getTryRegion ()));
28962895
2897- // FIXME: optimize, ideas include:
2898- // - If we know a target function never throws a specific type, we can
2899- // remove the catch handler.
2900- for (mlir::Region &r : this ->getCatchRegions ())
2901- regions.push_back (RegionSuccessor (&r));
2896+ // TODO(CIR): If we know a target function never throws a specific type, we
2897+ // can remove the catch handler.
2898+ for (mlir::Region ®ion : this ->getCatchRegions ())
2899+ regions.push_back (mlir::RegionSuccessor (®ion));
29022900}
29032901
2904- static void printCatchRegions (OpAsmPrinter &printer, cir::TryOp op,
2905- mlir::MutableArrayRef<:: mlir::Region> regions,
2902+ static void printCatchRegions (mlir:: OpAsmPrinter &printer, cir::TryOp op,
2903+ mlir::MutableArrayRef<mlir::Region> regions,
29062904 mlir::ArrayAttr catchersAttr) {
29072905 if (!catchersAttr)
29082906 return ;
29092907
2910- int currCatchIdx = 0 ;
2911- printer << " catch [" ;
2912- llvm::interleaveComma (catchersAttr, printer, [&](const Attribute &a) {
2913- if (mlir::isa<cir::CatchUnwindAttr>(a)) {
2914- printer.printAttribute (a);
2908+ for (const auto [catcherIdx, catcherAttr] : llvm::enumerate (catchersAttr)) {
2909+ if (catcherIdx)
29152910 printer << " " ;
2916- } else if (!a) {
2917- printer << " all" ;
2911+
2912+ if (mlir::isa<cir::CatchAllAttr>(catcherAttr)) {
2913+ printer << " catch all " ;
2914+ } else if (mlir::isa<cir::UnwindAttr>(catcherAttr)) {
2915+ printer << " unwind " ;
29182916 } else {
2919- printer << " type " ;
2920- printer.printAttribute (a );
2921- printer << " " ;
2917+ printer << " catch [ type " ;
2918+ printer.printAttribute (catcherAttr );
2919+ printer << " ] " ;
29222920 }
2923- printer.printRegion (regions[currCatchIdx], /* printEntryBLockArgs=*/ false ,
2924- /* printBlockTerminators=*/ true );
2925- currCatchIdx++;
2926- });
29272921
2928- printer << " ]" ;
2922+ printer.printRegion (regions[catcherIdx], /* printEntryBLockArgs=*/ false ,
2923+ /* printBlockTerminators=*/ true );
2924+ }
29292925}
29302926
2931- static ParseResult parseCatchRegions (
2932- OpAsmParser &parser,
2933- llvm::SmallVectorImpl<std::unique_ptr<::mlir::Region>> ®ions,
2934- ::mlir::ArrayAttr &catchersAttr) {
2935- if (parser.parseKeyword (" catch" ).failed ())
2936- return parser.emitError (parser.getCurrentLocation (),
2937- " expected 'catch' keyword here" );
2927+ static mlir::ParseResult
2928+ parseCatchRegions (mlir::OpAsmParser &parser,
2929+ llvm::SmallVectorImpl<std::unique_ptr<mlir::Region>> ®ions,
2930+ mlir::ArrayAttr &catchersAttr) {
29382931
2939- auto parseAndCheckRegion = [&]() -> ParseResult {
2940- // Parse region attached to catch
2941- regions. emplace_back ( new Region);
2942- Region &currRegion = *regions.back ();
2943- SMLoc parserLoc = parser.getCurrentLocation ();
2932+ auto parseCheckedCatcherRegion = [&]() -> mlir:: ParseResult {
2933+ regions. emplace_back ( new mlir::Region);
2934+
2935+ mlir:: Region &currRegion = *regions.back ();
2936+ mlir:: SMLoc regionLoc = parser.getCurrentLocation ();
29442937 if (parser.parseRegion (currRegion)) {
29452938 regions.clear ();
29462939 return failure ();
29472940 }
29482941
2949- if (currRegion.empty ()) {
2950- return parser.emitError (parser.getCurrentLocation (),
2951- " catch region shall not be empty" );
2952- }
2953-
2954- if (!(currRegion.back ().mightHaveTerminator () &&
2955- currRegion.back ().getTerminator ()))
2942+ if (!currRegion.empty () && !(currRegion.back ().mightHaveTerminator () &&
2943+ currRegion.back ().getTerminator ()))
29562944 return parser.emitError (
2957- parserLoc , " blocks are expected to be explicitly terminated" );
2945+ regionLoc , " blocks are expected to be explicitly terminated" );
29582946
29592947 return success ();
29602948 };
29612949
2962- llvm::SmallVector<mlir::Attribute, 4 > catchList;
2963- auto parseCatchEntry = [&]() -> ParseResult {
2964- mlir::Attribute exceptionTypeInfo;
2950+ bool hasCatchAll = false ;
2951+ llvm::SmallVector<mlir::Attribute, 4 > catcherAttrs;
2952+ while (parser.parseOptionalKeyword (" catch" ).succeeded ()) {
2953+ bool hasLSquare = parser.parseOptionalLSquare ().succeeded ();
29652954
2966- if (parser.parseOptionalAttribute (exceptionTypeInfo).has_value ()) {
2967- catchList.push_back (exceptionTypeInfo);
2968- } else {
2969- ::llvm::StringRef attrStr;
2970- if (parser.parseOptionalKeyword (&attrStr, {" all" }).succeeded ()) {
2971- // "all" keyword found, exceptionTypeInfo remains null
2972- } else if (parser.parseOptionalKeyword (" type" ).succeeded ()) {
2973- if (parser.parseAttribute (exceptionTypeInfo).failed ())
2974- return parser.emitError (parser.getCurrentLocation (),
2975- " expected valid RTTI info attribute" );
2976- } else {
2955+ llvm::StringRef attrStr;
2956+ if (parser.parseOptionalKeyword (&attrStr, {" all" , " type" }).failed ())
2957+ return parser.emitError (parser.getCurrentLocation (),
2958+ " expected 'all' or 'type' keyword" );
2959+
2960+ bool isCatchAll = attrStr == " all" ;
2961+ if (isCatchAll) {
2962+ if (hasCatchAll)
29772963 return parser.emitError (parser.getCurrentLocation (),
2978- " expected attribute, 'all', or 'type' keyword" );
2979- }
2980- catchList.push_back (exceptionTypeInfo);
2964+ " can't have more than one catch all" );
2965+ hasCatchAll = true ;
29812966 }
2982- return parseAndCheckRegion ();
2983- };
29842967
2985- if (parser
2986- .parseCommaSeparatedList (OpAsmParser::Delimiter::Square,
2987- parseCatchEntry, " in catch list" )
2988- .failed ())
2989- return failure ();
2968+ mlir::Attribute exceptionRTTIAttr;
2969+ if (!isCatchAll && parser.parseAttribute (exceptionRTTIAttr).failed ())
2970+ return parser.emitError (parser.getCurrentLocation (),
2971+ " expected valid RTTI info attribute" );
2972+
2973+ catcherAttrs.push_back (isCatchAll
2974+ ? cir::CatchAllAttr::get (parser.getContext ())
2975+ : exceptionRTTIAttr);
2976+
2977+ if (hasLSquare && isCatchAll)
2978+ return parser.emitError (parser.getCurrentLocation (),
2979+ " catch all dosen't need RTTI info attribute" );
2980+
2981+ if (hasLSquare && parser.parseRSquare ().failed ())
2982+ return parser.emitError (parser.getCurrentLocation (),
2983+ " expected `]` after RTTI info attribute" );
2984+
2985+ if (parseCheckedCatcherRegion ().failed ())
2986+ return mlir::failure ();
2987+ }
29902988
2991- catchersAttr = parser.getBuilder ().getArrayAttr (catchList);
2992- return ::mlir::success ();
2989+ if (parser.parseOptionalKeyword (" unwind" ).succeeded ()) {
2990+ catcherAttrs.push_back (cir::UnwindAttr::get (parser.getContext ()));
2991+ if (parseCheckedCatcherRegion ().failed ())
2992+ return mlir::failure ();
2993+ }
2994+
2995+ catchersAttr = parser.getBuilder ().getArrayAttr (catcherAttrs);
2996+ return mlir::success ();
29932997}
29942998
29952999// ===----------------------------------------------------------------------===//
0 commit comments