================
@@ -382,5 +410,279 @@ void CIRGenFunction::exitCXXTryStmt(const CXXTryStmt &s, 
bool isFnTryBlock) {
     return;
   }
 
-  cgm.errorNYI("exitCXXTryStmt: Required catch");
+  // Emit the structure of the EH dispatch for this catch.
+  emitCatchDispatchBlock(*this, catchScope, tryOp);
+
+  // Copy the handler blocks off before we pop the EH stack.  Emitting
+  // the handlers might scribble on this memory.
+  SmallVector<EHCatchScope::Handler, 8> handlers(
+      catchScope.begin(), catchScope.begin() + numHandlers);
+
+  ehStack.popCatch();
+
+  // Determine if we need an implicit rethrow for all these catch handlers;
+  // see the comment below.
+  bool doImplicitRethrow =
+      isFnTryBlock && isa<CXXDestructorDecl, CXXConstructorDecl>(curCodeDecl);
+
+  // Wasm uses Windows-style EH instructions, but merges all catch clauses into
+  // one big catchpad. So we save the old funclet pad here before we traverse
+  // each catch handler.
+  if (EHPersonality::get(*this).isWasmPersonality()) {
+    cgm.errorNYI("exitCXXTryStmt: WASM personality");
+    return;
+  }
+
+  bool hasCatchAll = false;
+  for (unsigned i = numHandlers; i != 0; --i) {
+    hasCatchAll |= handlers[i - 1].isCatchAll();
+    mlir::Region *catchRegion = handlers[i - 1].region;
+
+    mlir::OpBuilder::InsertionGuard guard(builder);
+    builder.setInsertionPointToStart(&catchRegion->front());
+
+    const CXXCatchStmt *catchStmt = s.getHandler(i - 1);
+
+    // Enter a cleanup scope, including the catch variable and the
+    // end-catch.
+    RunCleanupsScope catchScope(*this);
+
+    // Initialize the catch variable and set up the cleanups.
+    // TODO: emitBeginCatch
+
+    // Emit the PGO counter increment.
+    assert(!cir::MissingFeatures::incrementProfileCounter());
+
+    // Perform the body of the catch.
+    mlir::LogicalResult emitResult =
+        emitStmt(catchStmt->getHandlerBlock(), /*useCurrentScope=*/true);
+    assert(emitResult.succeeded() && "failed to emit catch handler block");
+
+    // TODO(cir): This yeild should replaced by CatchParamOp once it upstreamed
+    cir::YieldOp::create(builder, tryOp->getLoc());
+
+    // [except.handle]p11:
+    //   The currently handled exception is rethrown if control
+    //   reaches the end of a handler of the function-try-block of a
+    //   constructor or destructor.
+
+    // It is important that we only do this on fallthrough and not on
+    // return.  Note that it's illegal to put a return in a
+    // constructor function-try-block's catch handler (p14), so this
+    // really only applies to destructors.
+    if (doImplicitRethrow) {
+      cgm.errorNYI("exitCXXTryStmt: doImplicitRethrow");
+      return;
+    }
+
+    // Fall out through the catch cleanups.
+    catchScope.forceCleanup();
+  }
+
+  // Because in wasm we merge all catch clauses into one big catchpad, in case
+  // none of the types in catch handlers matches after we test against each of
+  // them, we should unwind to the next EH enclosing scope. We generate a call
+  // to rethrow function here to do that.
+  if (EHPersonality::get(*this).isWasmPersonality() && !hasCatchAll) {
+    cgm.errorNYI("exitCXXTryStmt: WASM personality without catch all");
+  }
+
+  assert(!cir::MissingFeatures::incrementProfileCounter());
+}
+
+mlir::Operation *CIRGenFunction::emitLandingPad(cir::TryOp tryOp) {
----------------
AmrDeveloper wrote:

In CIR, it's populating the catch handler attrs

https://github.com/llvm/llvm-project/pull/165158
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to