1*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions | FileCheck %s
2*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions -DSTD | FileCheck %s
3*67e74705SXin Li
4*67e74705SXin Li // 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
5*67e74705SXin Li // CHECK-DAG: @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8" = 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* bitcast (%struct.Y* (%struct.Y*, %struct.Y*, i32)* @"\01??0Y@@QAE@ABU0@@Z" to i8*) }, section ".xdata", comdat
6*67e74705SXin Li // 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
7*67e74705SXin Li // 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 }, section ".xdata", comdat
8*67e74705SXin Li // 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
9*67e74705SXin Li // CHECK-DAG: @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44" = 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* bitcast (%struct.W* (%struct.W*, %struct.W*, i32)* @"\01??0W@@QAE@ABU0@@Z" to i8*) }, section ".xdata", comdat
10*67e74705SXin Li // 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
11*67e74705SXin Li // CHECK-DAG: @"_CT??_R0?AUM@@@818" = 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 }, section ".xdata", comdat
12*67e74705SXin Li // 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
13*67e74705SXin Li // CHECK-DAG: @"_CT??_R0?AUV@@@81044" = 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 }, section ".xdata", comdat
14*67e74705SXin Li // CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44", %eh.CatchableType* @"_CT??_R0?AUM@@@818", %eh.CatchableType* @"_CT??_R0?AUV@@@81044"] }, section ".xdata", comdat
15*67e74705SXin Li // 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*) }, section ".xdata", comdat
16*67e74705SXin Li // CHECK-DAG: @"_CT??_R0?AUDefault@@@8??_ODefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor13* @"\01??_R0?AUDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Default*, %struct.Default*)* @"\01??_ODefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
17*67e74705SXin Li // CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"\01??_R0?AUVariadic@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Variadic*, %struct.Variadic*)* @"\01??_OVariadic@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
18*67e74705SXin Li // CHECK-DAG: @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor25* @"\01??_R0?AUTemplateWithDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.TemplateWithDefault*, %struct.TemplateWithDefault*)* @"\01??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat
19*67e74705SXin Li // CHECK-DAG: @"_CTA2$$T" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0$$T@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat
20*67e74705SXin Li // CHECK-DAG: @"_CT??_R0P6AXXZ@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0P6AXXZ@8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat
21*67e74705SXin Li // CHECK-DAG: @_CTA1P6AXXZ = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0P6AXXZ@84"] }, section ".xdata", comdat
22*67e74705SXin Li // CHECK-DAG: @_TI1P6AXXZ = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1P6AXXZ to i8*) }, section ".xdata", comdat
23*67e74705SXin Li // CHECK-DAG: @_TIU2PAPFAH = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 4, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.2* @_CTA2PAPFAH to i8*) }, section ".xdata", comdat
24*67e74705SXin Li // CHECK-DAG: @_CTA2PAPFAH = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0PAPFAH@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat
25*67e74705SXin Li
26*67e74705SXin Li
27*67e74705SXin Li struct N { ~N(); };
28*67e74705SXin Li struct M : private N {};
29*67e74705SXin Li struct X {};
30*67e74705SXin Li struct Z {};
31*67e74705SXin Li struct V : private X {};
32*67e74705SXin Li struct W : M, virtual V {};
33*67e74705SXin Li struct Y : Z, W, virtual V {};
34*67e74705SXin Li
f(const Y & y)35*67e74705SXin Li void f(const Y &y) {
36*67e74705SXin Li // CHECK-LABEL: @"\01?f@@YAXABUY@@@Z"
37*67e74705SXin Li // CHECK: call x86_thiscallcc %struct.Y* @"\01??0Y@@QAE@ABU0@@Z"(%struct.Y* %[[mem:.*]], %struct.Y*
38*67e74705SXin Li // CHECK: %[[cast:.*]] = bitcast %struct.Y* %[[mem]] to i8*
39*67e74705SXin Li // CHECK: call void @_CxxThrowException(i8* %[[cast]], %eh.ThrowInfo* @"_TI5?AUY@@")
40*67e74705SXin Li throw y;
41*67e74705SXin Li }
42*67e74705SXin Li
g(const int * const * y)43*67e74705SXin Li void g(const int *const *y) {
44*67e74705SXin Li // CHECK-LABEL: @"\01?g@@YAXPBQBH@Z"
45*67e74705SXin Li // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIC2PAPBH)
46*67e74705SXin Li throw y;
47*67e74705SXin Li }
48*67e74705SXin Li
h(__unaligned int * __unaligned * y)49*67e74705SXin Li void h(__unaligned int * __unaligned *y) {
50*67e74705SXin Li // CHECK-LABEL: @"\01?h@@YAXPFAPFAH@Z"
51*67e74705SXin Li // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIU2PAPFAH)
52*67e74705SXin Li throw y;
53*67e74705SXin Li }
54*67e74705SXin Li
55*67e74705SXin Li struct Default {
56*67e74705SXin Li Default(Default &, int = 42);
57*67e74705SXin Li };
58*67e74705SXin Li
59*67e74705SXin Li // CHECK-LABEL: @"\01??_ODefault@@QAEXAAU0@@Z"
60*67e74705SXin Li // CHECK: %[[src_addr:.*]] = alloca
61*67e74705SXin Li // CHECK: %[[this_addr:.*]] = alloca
62*67e74705SXin Li // CHECK: store {{.*}} %src, {{.*}} %[[src_addr]], align 4
63*67e74705SXin Li // CHECK: store {{.*}} %this, {{.*}} %[[this_addr]], align 4
64*67e74705SXin Li // CHECK: %[[this:.*]] = load {{.*}} %[[this_addr]]
65*67e74705SXin Li // CHECK: %[[src:.*]] = load {{.*}} %[[src_addr]]
66*67e74705SXin Li // CHECK: call x86_thiscallcc {{.*}} @"\01??0Default@@QAE@AAU0@H@Z"({{.*}} %[[this]], {{.*}} %[[src]], i32 42)
67*67e74705SXin Li // CHECK: ret void
68*67e74705SXin Li
h(Default & d)69*67e74705SXin Li void h(Default &d) {
70*67e74705SXin Li throw d;
71*67e74705SXin Li }
72*67e74705SXin Li
73*67e74705SXin Li struct Variadic {
74*67e74705SXin Li Variadic(Variadic &, ...);
75*67e74705SXin Li };
76*67e74705SXin Li
i(Variadic & v)77*67e74705SXin Li void i(Variadic &v) {
78*67e74705SXin Li throw v;
79*67e74705SXin Li }
80*67e74705SXin Li
81*67e74705SXin Li // CHECK-LABEL: @"\01??_OVariadic@@QAEXAAU0@@Z"
82*67e74705SXin Li // CHECK: %[[src_addr:.*]] = alloca
83*67e74705SXin Li // CHECK: %[[this_addr:.*]] = alloca
84*67e74705SXin Li // CHECK: store {{.*}} %src, {{.*}} %[[src_addr:.*]], align
85*67e74705SXin Li // CHECK: store {{.*}} %this, {{.*}} %[[this_addr:.*]], align
86*67e74705SXin Li // CHECK: %[[this:.*]] = load {{.*}} %[[this_addr]]
87*67e74705SXin Li // CHECK: %[[src:.*]] = load {{.*}} %[[src_addr]]
88*67e74705SXin Li // CHECK: call {{.*}} @"\01??0Variadic@@QAA@AAU0@ZZ"({{.*}} %[[this]], {{.*}} %[[src]])
89*67e74705SXin Li // CHECK: ret void
90*67e74705SXin Li
91*67e74705SXin Li struct TemplateWithDefault {
92*67e74705SXin Li template <typename T>
fTemplateWithDefault93*67e74705SXin Li static int f() {
94*67e74705SXin Li return 0;
95*67e74705SXin Li }
96*67e74705SXin Li template <typename T = int>
97*67e74705SXin Li TemplateWithDefault(TemplateWithDefault &, T = f<T>());
98*67e74705SXin Li };
99*67e74705SXin Li
j(TemplateWithDefault & twd)100*67e74705SXin Li void j(TemplateWithDefault &twd) {
101*67e74705SXin Li throw twd;
102*67e74705SXin Li }
103*67e74705SXin Li
104*67e74705SXin Li
h()105*67e74705SXin Li void h() {
106*67e74705SXin Li throw nullptr;
107*67e74705SXin Li }
108*67e74705SXin Li
109*67e74705SXin Li #ifdef STD
110*67e74705SXin Li namespace std {
111*67e74705SXin Li template <typename T>
112*67e74705SXin Li void *__GetExceptionInfo(T);
113*67e74705SXin Li }
114*67e74705SXin Li #else
115*67e74705SXin Li template <typename T>
116*67e74705SXin Li void *__GetExceptionInfo(T);
117*67e74705SXin Li #endif
118*67e74705SXin Li using namespace std;
119*67e74705SXin Li
GetExceptionInfo_test0()120*67e74705SXin Li void *GetExceptionInfo_test0() {
121*67e74705SXin Li // CHECK-LABEL: @"\01?GetExceptionInfo_test0@@YAPAXXZ"
122*67e74705SXin Li // CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1H to i8*)
123*67e74705SXin Li return __GetExceptionInfo(0);
124*67e74705SXin Li }
125*67e74705SXin Li
GetExceptionInfo_test1()126*67e74705SXin Li void *GetExceptionInfo_test1() {
127*67e74705SXin Li // CHECK-LABEL: @"\01?GetExceptionInfo_test1@@YAPAXXZ"
128*67e74705SXin Li // CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1P6AXXZ to i8*)
129*67e74705SXin Li return __GetExceptionInfo<void (*)()>(&h);
130*67e74705SXin Li }
131