@@ -2919,113 +2919,117 @@ LogicalResult cir::TypeInfoAttr::verify(
29192919// ===----------------------------------------------------------------------===//
29202920
29212921void cir::TryOp::getSuccessorRegions (
2922- mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ions) {
2923- // If any index all the underlying regions branch back to the parent
2924- // operation.
2922+ mlir::RegionBranchPoint point,
2923+ llvm::SmallVectorImpl<mlir::RegionSuccessor> & regions) {
2924+ // The `try` and the `catchers` region branch back to the parent operation.
29252925 if (!point.isParent ()) {
2926- regions.push_back (RegionSuccessor ());
2926+ regions.push_back (mlir:: RegionSuccessor ());
29272927 return ;
29282928 }
29292929
2930- // If the condition isn't constant, both regions may be executed.
2931- regions.push_back (RegionSuccessor (&getTryRegion ()));
2930+ regions.push_back (mlir::RegionSuccessor (&getTryRegion ()));
29322931
2933- // FIXME: optimize, ideas include:
2934- // - If we know a target function never throws a specific type, we can
2935- // remove the catch handler.
2936- for (mlir::Region &r : this ->getCatchRegions ())
2937- regions.push_back (RegionSuccessor (&r));
2932+ // TODO(CIR): If we know a target function never throws a specific type, we
2933+ // can remove the catch handler.
2934+ for (mlir::Region ®ion : this ->getCatchRegions ())
2935+ regions.push_back (mlir::RegionSuccessor (®ion));
29382936}
29392937
2940- static void printCatchRegions (OpAsmPrinter &printer, cir::TryOp op,
2941- mlir::MutableArrayRef<:: mlir::Region> regions,
2938+ static void printCatchRegions (mlir:: OpAsmPrinter &printer, cir::TryOp op,
2939+ mlir::MutableArrayRef<mlir::Region> regions,
29422940 mlir::ArrayAttr catchersAttr) {
29432941 if (!catchersAttr)
29442942 return ;
29452943
2946- int currCatchIdx = 0 ;
2947- printer << " catch [" ;
2948- llvm::interleaveComma (catchersAttr, printer, [&](const Attribute &a) {
2949- if (mlir::isa<cir::CatchUnwindAttr>(a)) {
2950- printer.printAttribute (a);
2944+ for (const auto [catcherIdx, catcherAttr] : llvm::enumerate (catchersAttr)) {
2945+ if (catcherIdx)
29512946 printer << " " ;
2952- } else if (!a) {
2953- printer << " all" ;
2947+
2948+ if (mlir::isa<cir::CatchAllAttr>(catcherAttr)) {
2949+ printer << " catch all " ;
2950+ } else if (mlir::isa<cir::UnwindAttr>(catcherAttr)) {
2951+ printer << " unwind " ;
29542952 } else {
2955- printer << " type " ;
2956- printer.printAttribute (a );
2957- printer << " " ;
2953+ printer << " catch [ type " ;
2954+ printer.printAttribute (catcherAttr );
2955+ printer << " ] " ;
29582956 }
2959- printer.printRegion (regions[currCatchIdx], /* printEntryBLockArgs=*/ false ,
2960- /* printBlockTerminators=*/ true );
2961- currCatchIdx++;
2962- });
29632957
2964- printer << " ]" ;
2958+ printer.printRegion (regions[catcherIdx], /* printEntryBLockArgs=*/ false ,
2959+ /* printBlockTerminators=*/ true );
2960+ }
29652961}
29662962
2967- static ParseResult parseCatchRegions (
2968- OpAsmParser &parser,
2969- llvm::SmallVectorImpl<std::unique_ptr<::mlir::Region>> ®ions,
2970- ::mlir::ArrayAttr &catchersAttr) {
2971- if (parser.parseKeyword (" catch" ).failed ())
2972- return parser.emitError (parser.getCurrentLocation (),
2973- " expected 'catch' keyword here" );
2963+ static mlir::ParseResult
2964+ parseCatchRegions (mlir::OpAsmParser &parser,
2965+ llvm::SmallVectorImpl<std::unique_ptr<mlir::Region>> ®ions,
2966+ mlir::ArrayAttr &catchersAttr) {
29742967
2975- auto parseAndCheckRegion = [&]() -> ParseResult {
2976- // Parse region attached to catch
2977- regions. emplace_back ( new Region);
2978- Region &currRegion = *regions.back ();
2979- SMLoc parserLoc = parser.getCurrentLocation ();
2968+ auto parseCheckedCatcherRegion = [&]() -> mlir:: ParseResult {
2969+ regions. emplace_back ( new mlir::Region);
2970+
2971+ mlir:: Region &currRegion = *regions.back ();
2972+ mlir:: SMLoc regionLoc = parser.getCurrentLocation ();
29802973 if (parser.parseRegion (currRegion)) {
29812974 regions.clear ();
29822975 return failure ();
29832976 }
29842977
2985- if (currRegion.empty ()) {
2986- return parser.emitError (parser.getCurrentLocation (),
2987- " catch region shall not be empty" );
2988- }
2989-
2990- if (!(currRegion.back ().mightHaveTerminator () &&
2991- currRegion.back ().getTerminator ()))
2978+ if (!currRegion.empty () && !(currRegion.back ().mightHaveTerminator () &&
2979+ currRegion.back ().getTerminator ()))
29922980 return parser.emitError (
2993- parserLoc , " blocks are expected to be explicitly terminated" );
2981+ regionLoc , " blocks are expected to be explicitly terminated" );
29942982
29952983 return success ();
29962984 };
29972985
2998- llvm::SmallVector<mlir::Attribute, 4 > catchList;
2999- auto parseCatchEntry = [&]() -> ParseResult {
3000- mlir::Attribute exceptionTypeInfo;
2986+ bool hasCatchAll = false ;
2987+ llvm::SmallVector<mlir::Attribute, 4 > catcherAttrs;
2988+ while (parser.parseOptionalKeyword (" catch" ).succeeded ()) {
2989+ bool hasLSquare = parser.parseOptionalLSquare ().succeeded ();
30012990
3002- if (parser.parseOptionalAttribute (exceptionTypeInfo).has_value ()) {
3003- catchList.push_back (exceptionTypeInfo);
3004- } else {
3005- ::llvm::StringRef attrStr;
3006- if (parser.parseOptionalKeyword (&attrStr, {" all" }).succeeded ()) {
3007- // "all" keyword found, exceptionTypeInfo remains null
3008- } else if (parser.parseOptionalKeyword (" type" ).succeeded ()) {
3009- if (parser.parseAttribute (exceptionTypeInfo).failed ())
3010- return parser.emitError (parser.getCurrentLocation (),
3011- " expected valid RTTI info attribute" );
3012- } else {
2991+ llvm::StringRef attrStr;
2992+ if (parser.parseOptionalKeyword (&attrStr, {" all" , " type" }).failed ())
2993+ return parser.emitError (parser.getCurrentLocation (),
2994+ " expected 'all' or 'type' keyword" );
2995+
2996+ bool isCatchAll = attrStr == " all" ;
2997+ if (isCatchAll) {
2998+ if (hasCatchAll)
30132999 return parser.emitError (parser.getCurrentLocation (),
3014- " expected attribute, 'all', or 'type' keyword" );
3015- }
3016- catchList.push_back (exceptionTypeInfo);
3000+ " can't have more than one catch all" );
3001+ hasCatchAll = true ;
30173002 }
3018- return parseAndCheckRegion ();
3019- };
30203003
3021- if (parser
3022- .parseCommaSeparatedList (OpAsmParser::Delimiter::Square,
3023- parseCatchEntry, " in catch list" )
3024- .failed ())
3025- return failure ();
3004+ mlir::Attribute exceptionRTTIAttr;
3005+ if (!isCatchAll && parser.parseAttribute (exceptionRTTIAttr).failed ())
3006+ return parser.emitError (parser.getCurrentLocation (),
3007+ " expected valid RTTI info attribute" );
30263008
3027- catchersAttr = parser.getBuilder ().getArrayAttr (catchList);
3028- return ::mlir::success ();
3009+ catcherAttrs.push_back (isCatchAll
3010+ ? cir::CatchAllAttr::get (parser.getContext ())
3011+ : exceptionRTTIAttr);
3012+
3013+ if (hasLSquare && isCatchAll)
3014+ return parser.emitError (parser.getCurrentLocation (),
3015+ " catch all dosen't need RTTI info attribute" );
3016+
3017+ if (hasLSquare && parser.parseRSquare ().failed ())
3018+ return parser.emitError (parser.getCurrentLocation (),
3019+ " expected `]` after RTTI info attribute" );
3020+
3021+ if (parseCheckedCatcherRegion ().failed ())
3022+ return mlir::failure ();
3023+ }
3024+
3025+ if (parser.parseOptionalKeyword (" unwind" ).succeeded ()) {
3026+ catcherAttrs.push_back (cir::UnwindAttr::get (parser.getContext ()));
3027+ if (parseCheckedCatcherRegion ().failed ())
3028+ return mlir::failure ();
3029+ }
3030+
3031+ catchersAttr = parser.getBuilder ().getArrayAttr (catcherAttrs);
3032+ return mlir::success ();
30293033}
30303034
30313035// ===----------------------------------------------------------------------===//
0 commit comments