diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-03-05 00:46:22 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-03-05 00:46:22 +0000 |
commit | 75f2e3e4eabce0720e00979a62e1e2e21ae79e86 (patch) | |
tree | d5ce0895d4300fd9f9808f3f662afc99df1b0638 /test/CodeGenCXX/microsoft-abi-throw.cpp | |
parent | 07402d207eedd23ea03d2be684f35e3811429fe2 (diff) |
MS ABI: Implement support for throwing a C++ exception
Throwing a C++ exception, under the MS ABI, is implemented using three
components:
- ThrowInfo structure which contains information like CV qualifiers,
what destructor to call and a pointer to the CatchableTypeArray.
- In a significant departure from the Itanium ABI, copying by-value
occurs in the runtime and not at the catch site. This means we need
to enumerate all possible types that this exception could be caught as
and encode the necessary information to convert from the exception
object's type to the catch handler's type. This includes complicated
derived to base conversions and the execution of copy-constructors.
N.B. This implementation doesn't support the execution of a
copy-constructor from within the runtime for now. Adding support for
that functionality is quite difficult due to things like default
argument expressions which may evaluate arbitrary code hiding in the
copy-constructor's parameters.
Differential Revision: http://reviews.llvm.org/D8066
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231328 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/microsoft-abi-throw.cpp')
-rw-r--r-- | test/CodeGenCXX/microsoft-abi-throw.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/test/CodeGenCXX/microsoft-abi-throw.cpp b/test/CodeGenCXX/microsoft-abi-throw.cpp new file mode 100644 index 0000000000..93d051e8eb --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-throw.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 %s -fcxx-exceptions | FileCheck %s + +// CHECK-DAG: @"\01??_R0?AUY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUY@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUY@@@88" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUY@@@8" to i8*), i32 0, i32 -1, i32 0, i32 8, i8* null }, comdat +// CHECK-DAG: @"\01??_R0?AUZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUZ@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUZ@@@81" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUZ@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* null }, comdat +// CHECK-DAG: @"\01??_R0?AUW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUW@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUW@@@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUW@@@8" to i8*), i32 4, i32 -1, i32 0, i32 4, i8* null }, comdat +// CHECK-DAG: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUM@@@81" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 8, i32 -1, i32 0, i32 1, i8* null }, comdat +// CHECK-DAG: @"\01??_R0?AUV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUV@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUV@@@81" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUV@@@8" to i8*), i32 0, i32 4, i32 4, i32 1, i8* null }, comdat +// CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@88", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@84", %eh.CatchableType* @"_CT??_R0?AUM@@@81", %eh.CatchableType* @"_CT??_R0?AUV@@@81"] }, comdat +// CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAE@XZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, comdat + + +struct N { ~N(); }; +struct M : private N {}; +struct X {}; +struct Z {}; +struct V : private X {}; +struct W : M, virtual V {}; +struct Y : Z, W, virtual V {}; + +void f(const Y &y) { + // CHECK-LABEL: @"\01?f@@YAXABUY@@@Z" + // CHECK: call x86_thiscallcc %struct.Y* @"\01??0Y@@QAE@ABU0@@Z"(%struct.Y* %[[mem:.*]], %struct.Y* + // CHECK: %[[cast:.*]] = bitcast %struct.Y* %[[mem]] to i8* + // CHECK: call void @_CxxThrowException(i8* %[[cast]], %eh.ThrowInfo* @"_TI5?AUY@@") #4 + throw y; +} |