[clang] [CIR] Upstream Exception CXXTryStmt (PR #162528)

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 8 14:03:07 PDT 2025


================
@@ -64,3 +65,157 @@ void CIRGenFunction::emitAnyExprToExn(const Expr *e, Address addr) {
   // Deactivate the cleanup block.
   assert(!cir::MissingFeatures::ehCleanupScope());
 }
+
+mlir::LogicalResult CIRGenFunction::emitCXXTryStmt(const CXXTryStmt &s) {
+  auto loc = getLoc(s.getSourceRange());
+
+  // Create a scope to hold try local storage for catch params.
+  mlir::OpBuilder::InsertPoint scopeIP;
+  cir::ScopeOp::create(builder, loc, /*scopeBuilder=*/
+                       [&](mlir::OpBuilder &b, mlir::Location loc) {
+                         scopeIP = builder.saveInsertionPoint();
+                       });
+
+  mlir::LogicalResult result = mlir::success();
+  {
+    mlir::OpBuilder::InsertionGuard guard(builder);
+    builder.restoreInsertionPoint(scopeIP);
+    result = emitCXXTryStmtUnderScope(s);
+    cir::YieldOp::create(builder, loc);
+  }
+
+  return result;
+}
+
+mlir::LogicalResult
+CIRGenFunction::emitCXXTryStmtUnderScope(const CXXTryStmt &s) {
+  const llvm::Triple &t = getTarget().getTriple();
+  // If we encounter a try statement on in an OpenMP target region offloaded to
+  // a GPU, we treat it as a basic block.
+  const bool isTargetDevice =
+      (cgm.getLangOpts().OpenMPIsTargetDevice && (t.isNVPTX() || t.isAMDGCN()));
+  if (isTargetDevice) {
+    cgm.errorNYI(
+        "emitCXXTryStmtUnderScope: OpenMP target region offloaded to GPU");
+    return mlir::success();
+  }
+
+  auto hasCatchAll = [&]() {
+    if (!s.getNumHandlers())
+      return false;
+    unsigned lastHandler = s.getNumHandlers() - 1;
+    return s.getHandler(lastHandler)->getExceptionDecl() == nullptr;
+  };
+
+  unsigned numHandlers = s.getNumHandlers();
+  mlir::Location tryLoc = getLoc(s.getBeginLoc());
+
+  mlir::OpBuilder::InsertPoint beginInsertTryBody;
+
+  // Create the scope to represent only the C/C++ `try {}` part. However,
+  // don't populate right away. Reserve some space to store the exception
+  // info but don't emit the bulk right away, for now only make sure the
+  // scope returns the exception information.
+  auto tryOp = cir::TryOp::create(
+      builder, tryLoc,
+      /*tryBuilder=*/
+      [&](mlir::OpBuilder &b, mlir::Location loc) {
+        beginInsertTryBody = builder.saveInsertionPoint();
+      },
+      /*catchBuilder=*/
+      [&](mlir::OpBuilder &b, mlir::Location loc,
+          mlir::OperationState &result) {
+        mlir::OpBuilder::InsertionGuard guard(b);
+        unsigned numRegionsToCreate =
+            hasCatchAll() ? numHandlers : numHandlers + 1;
----------------
andykaylor wrote:

Oh, I see. It's creating an unwind region if there was no catch-all. Can you add a comment explaining that?

https://github.com/llvm/llvm-project/pull/162528


More information about the cfe-commits mailing list