xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc // For now, just make sure x86_64 doesn't crash.
4*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t
5f4a2713aSLionel Sambuc 
6f4a2713aSLionel Sambuc struct A {
7f4a2713aSLionel Sambuc   virtual void f();
8f4a2713aSLionel Sambuc };
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc struct B {
11f4a2713aSLionel Sambuc   virtual void f();
12f4a2713aSLionel Sambuc };
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc struct C : A, B {};
15f4a2713aSLionel Sambuc 
16f4a2713aSLionel Sambuc struct D : virtual C {
17f4a2713aSLionel Sambuc   D();
18f4a2713aSLionel Sambuc   ~D();
19f4a2713aSLionel Sambuc   virtual void f();
20f4a2713aSLionel Sambuc   void g();
21f4a2713aSLionel Sambuc   int xxx;
22f4a2713aSLionel Sambuc };
23f4a2713aSLionel Sambuc 
D()24f4a2713aSLionel Sambuc D::D() {}  // Forces vftable emission.
25f4a2713aSLionel Sambuc 
26*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPM@A@AEXXZ"
27f4a2713aSLionel Sambuc // CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}}
28f4a2713aSLionel Sambuc // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
29f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4
30f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32*
31f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP:.*]] = load i32* %[[VTORDISP_PTR]]
32f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
33f4a2713aSLionel Sambuc // CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
34f4a2713aSLionel Sambuc // CHECK: call x86_thiscallcc void @"\01?f@D@@UAEXXZ"(i8* %[[ADJUSTED_i8]])
35f4a2713aSLionel Sambuc // CHECK: ret void
36f4a2713aSLionel Sambuc 
37*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPI@3AEXXZ"
38f4a2713aSLionel Sambuc // CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}}
39f4a2713aSLionel Sambuc // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
40f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -8
41f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32*
42f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP:.*]] = load i32* %[[VTORDISP_PTR]]
43f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
44f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
45f4a2713aSLionel Sambuc // CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8* %[[VTORDISP_ADJUSTED_i8]], i32 -4
46f4a2713aSLionel Sambuc // CHECK: call x86_thiscallcc void @"\01?f@D@@UAEXXZ"(i8* %[[ADJUSTED_i8]])
47f4a2713aSLionel Sambuc // CHECK: ret void
48f4a2713aSLionel Sambuc 
49f4a2713aSLionel Sambuc struct E : virtual A {
50f4a2713aSLionel Sambuc   virtual void f();
51f4a2713aSLionel Sambuc   ~E();
52f4a2713aSLionel Sambuc };
53f4a2713aSLionel Sambuc 
54f4a2713aSLionel Sambuc struct F {
55f4a2713aSLionel Sambuc   virtual void z();
56f4a2713aSLionel Sambuc };
57f4a2713aSLionel Sambuc 
58f4a2713aSLionel Sambuc struct G : virtual F, virtual E {
59f4a2713aSLionel Sambuc   int ggg;
60f4a2713aSLionel Sambuc   G();
61f4a2713aSLionel Sambuc   ~G();
62f4a2713aSLionel Sambuc };
63f4a2713aSLionel Sambuc 
G()64f4a2713aSLionel Sambuc G::G() {}  // Forces vftable emission.
65f4a2713aSLionel Sambuc 
66*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@E@@$R4BA@M@PPPPPPPM@7AEXXZ"(i8*)
67f4a2713aSLionel Sambuc // CHECK: %[[ECX:.*]] = load %struct.E** %{{.*}}
68f4a2713aSLionel Sambuc // CHECK: %[[ECX_i8:.*]] = bitcast %struct.E* %[[ECX]] to i8*
69f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4
70f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32*
71f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP:.*]] = load i32* %[[VTORDISP_PTR]]
72f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]]
73f4a2713aSLionel Sambuc // CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]]
74f4a2713aSLionel Sambuc // CHECK: %[[VBPTR_i8:.*]] = getelementptr inbounds i8* %[[VTORDISP_ADJUSTED_i8]], i32 -16
75*0a6a1f1dSLionel Sambuc // CHECK: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i32**
76*0a6a1f1dSLionel Sambuc // CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR]]
77*0a6a1f1dSLionel Sambuc // CHECK: %[[VBOFFSET_PTR:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 3
78f4a2713aSLionel Sambuc // CHECK: %[[VBASE_OFFSET:.*]] = load i32* %[[VBOFFSET_PTR]]
79f4a2713aSLionel Sambuc // CHECK: %[[VBASE:.*]] = getelementptr inbounds i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]
80f4a2713aSLionel Sambuc // CHECK: %[[ARG_i8:.*]] = getelementptr i8* %[[VBASE]], i32 8
81f4a2713aSLionel Sambuc // CHECK: call x86_thiscallcc void @"\01?f@E@@UAEXXZ"(i8* %[[ARG_i8]])
82f4a2713aSLionel Sambuc // CHECK: ret void
83