Author: Andy Kaylor Date: 2026-02-13T09:22:36-08:00 New Revision: 2b5eb2dde2cdc98b4265d3b9940f235b51d38638
URL: https://github.com/llvm/llvm-project/commit/2b5eb2dde2cdc98b4265d3b9940f235b51d38638 DIFF: https://github.com/llvm/llvm-project/commit/2b5eb2dde2cdc98b4265d3b9940f235b51d38638.diff LOG: [CIR][docs] Add cir.catch_param to ClangIR cleanup and EH design doc (#181284) This updates the ClangIR cleanup and exception handling design document to describe the requirement to use cir.catch_param operations to begin the catch regions of a cir.try operation in the structured form of CIR. This also includes minor changes to the descriptions in the CIROps.td definitions of cir.try and cir.catch_param Added: Modified: clang/docs/ClangIRCleanupAndEHDesign.md clang/include/clang/CIR/Dialect/IR/CIROps.td Removed: ################################################################################ diff --git a/clang/docs/ClangIRCleanupAndEHDesign.md b/clang/docs/ClangIRCleanupAndEHDesign.md index 324cf51aa526b..84c9dbc4e897d 100644 --- a/clang/docs/ClangIRCleanupAndEHDesign.md +++ b/clang/docs/ClangIRCleanupAndEHDesign.md @@ -350,11 +350,22 @@ the destructor. Therefore, this cleanup handler is marked as eh_only. Try-catch blocks will be represented, as they are in the ClangIR incubator project, using a `cir.try` operation. +The `cir.catch_param` operation is used to represent the capturing of the +exception object in an ABI-independent way. When the catch handler includes +a source variable representing the exception object, the result of the +`cir.catch_param` operation will be stored to an alloca object for the +source variable. If the handler is a catch-all, the `cir.catch_param` operation +will return a pointer to void, but this cannot be captured by a source variable. + +The first operation in a catch handler region must be a `cir.catch_param` +operation. + ``` cir.try { cir.call exception @function() : () -> () cir.yield } catch [type #cir.global_view<@_ZTIPf> : !cir.ptr<!u8i>] { + %1 = cir.catch_param : !cir.ptr<!cir.float> ... cir.yield } unwind { @@ -385,11 +396,15 @@ void someFunc() { ``` cir.func @someFunc(){ + %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"] cir.scope { cir.try { cir.call exception @_Z1fv() : () -> () cir.yield } catch [type #cir.global_view<@_ZTISt9exception> : !cir.ptr<!u8i>] { + %1 = cir.catch_param : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>> + %2 = cir.load align(8) %1 : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, !cir.ptr<!rec_std3A3Aexception> + cir.store align(8) %2, %0 : !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>> cir.yield } unwind { cir.resume @@ -429,13 +444,18 @@ void someFunc() { ``` cir.func @someFunc(){ + %0 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"] cir.scope { cir.try { cir.call exception @_Z1fv() : () -> () cir.yield } catch [type #cir.global_view<@_ZTISt9exception> : !cir.ptr<!u8i>] { + %1 = cir.catch_param : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>> + %2 = cir.load align(8) %1 : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, !cir.ptr<!rec_std3A3Aexception> + cir.store align(8) %2, %0 : !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>> cir.yield } catch all { + %3 = cir.catch_param : !cir.ptr<!void> cir.yield } } @@ -484,6 +504,7 @@ cir.func @someFunc(){ cir.yield } } catch all { + %1 = cir.catch_param : !cir.ptr<!void> cir.yield } } @@ -516,12 +537,17 @@ void someFunc() { ``` cir.func @someFunc(){ %0 = cir.alloca !rec_SomeClass, !cir.ptr<!rec_SomeClass>, ["c", init] + %1 = cir.alloca !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, ["e"] cir.call @_ZN9SomeClassC1Ev(%0) : (!cir.ptr<!rec_SomeClass>) -> () cir.cleanup.scope { cir.scope { cir.try { cir.call @_ZN9SomeClass11doSomethingEv(%0) : (!cir.ptr<!rec_SomeClass>) -> () + cir.yield } catch [type #cir.global_view<@_ZTISt9exception> : !cir.ptr<!u8i>] { + %2 = cir.catch_param : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>> + %3 = cir.load align(8) %2 : !cir.ptr<!cir.ptr<!rec_std3A3Aexception>>, !cir.ptr<!rec_std3A3Aexception> + cir.store align(8) %3, %1 : !cir.ptr<!rec_std3A3Aexception>, !cir.ptr<!cir.ptr<!rec_std3A3Aexception>> cir.yield } unwind { cir.resume @@ -731,7 +757,11 @@ of the catch handling block must be a `cir.begin_catch` operation. The `cir.begin_catch` operation returns two values: a new token that uniquely identify this catch handler, and a pointer to the exception object. All paths through the catch handler must converge on a single -`cir.end_catch` operation, which marks the end of the handler. +`cir.end_catch` operation, which marks the end of the handler. The +`cir.begin_catch` replaces the `cir.catch_param` in the structured +form, and the exception object extracted from its return value should +be stored to the same alloca location as the return value of +`cir.catch_param` was in the structured representation. `cir.end_catch %catch_token` @@ -769,6 +799,7 @@ cir.func @someFunc(){ cir.yield } } catch all { + %1 = cir.catch_param : !cir.ptr<!void> cir.yield } } diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 2ce6d22c654f0..7085580d99718 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -6228,6 +6228,7 @@ def CIR_TryOp : CIR_Op<"try",[ cir.call exception @function() : () -> () cir.yield } catch [type #cir.global_view<@_ZTIPf> : !cir.ptr<!u8i>] { + %1 = cir.catch_param : !cir.ptr<!cir.float> ... cir.yield } unwind { @@ -6288,7 +6289,7 @@ def CIR_TryOp : CIR_Op<"try",[ def CIR_CatchParamOp : CIR_Op<"catch_param", [HasParent<"cir::TryOp">]> { let summary = "Represents the catch clause formal parameter"; let description = [{ - The `cir.catch_param` is used to retrieves the exception object inside + The `cir.catch_param` is used to retrieve the exception object inside the handler regions of `cir.try`. This operation is used only before the CFG flatterning pass. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
