xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/class-layout.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc // An extra byte should be allocated for an empty class.
4f4a2713aSLionel Sambuc namespace Test1 {
5f4a2713aSLionel Sambuc   // CHECK: %"struct.Test1::A" = type { i8 }
6f4a2713aSLionel Sambuc   struct A { } *a;
7f4a2713aSLionel Sambuc }
8f4a2713aSLionel Sambuc 
9f4a2713aSLionel Sambuc namespace Test2 {
10f4a2713aSLionel Sambuc   // No need to add tail padding here.
11f4a2713aSLionel Sambuc   // CHECK: %"struct.Test2::A" = type { i8*, i32 }
12f4a2713aSLionel Sambuc   struct A { void *a; int b; } *a;
13f4a2713aSLionel Sambuc }
14f4a2713aSLionel Sambuc 
15f4a2713aSLionel Sambuc namespace Test3 {
16f4a2713aSLionel Sambuc   // C should have a vtable pointer.
17*0a6a1f1dSLionel Sambuc   // CHECK: %"struct.Test3::A" = type <{ i32 (...)**, i32, [4 x i8] }>
18f4a2713aSLionel Sambuc   struct A { virtual void f(); int a; } *a;
19f4a2713aSLionel Sambuc }
20f4a2713aSLionel Sambuc 
21f4a2713aSLionel Sambuc namespace Test4 {
22f4a2713aSLionel Sambuc   // Test from PR5589.
23f4a2713aSLionel Sambuc   // CHECK: %"struct.Test4::B" = type { %"struct.Test4::A", i16, double }
24f4a2713aSLionel Sambuc   // CHECK: %"struct.Test4::A" = type { i32, i8, float }
25f4a2713aSLionel Sambuc   struct A {
26f4a2713aSLionel Sambuc     int a;
27f4a2713aSLionel Sambuc     char c;
28f4a2713aSLionel Sambuc     float b;
29f4a2713aSLionel Sambuc   };
30f4a2713aSLionel Sambuc   struct B : public A {
31f4a2713aSLionel Sambuc     short d;
32f4a2713aSLionel Sambuc     double e;
33f4a2713aSLionel Sambuc   } *b;
34f4a2713aSLionel Sambuc }
35f4a2713aSLionel Sambuc 
36f4a2713aSLionel Sambuc namespace Test5 {
37f4a2713aSLionel Sambuc   struct A {
38f4a2713aSLionel Sambuc     virtual void f();
39f4a2713aSLionel Sambuc     char a;
40f4a2713aSLionel Sambuc   };
41f4a2713aSLionel Sambuc 
42*0a6a1f1dSLionel Sambuc   // CHECK: %"struct.Test5::B" = type {  %"struct.Test5::A.base", i8, i8, [5 x i8] }
43f4a2713aSLionel Sambuc   struct B : A {
44f4a2713aSLionel Sambuc     char b : 1;
45f4a2713aSLionel Sambuc     char c;
46f4a2713aSLionel Sambuc   } *b;
47f4a2713aSLionel Sambuc }
48f4a2713aSLionel Sambuc 
49f4a2713aSLionel Sambuc // PR10912: don't crash
50f4a2713aSLionel Sambuc namespace Test6 {
51f4a2713aSLionel Sambuc   template <typename T> class A {
52f4a2713aSLionel Sambuc     // If T is complete, IR-gen will want to translate it recursively
53f4a2713aSLionel Sambuc     // when translating T*.
54f4a2713aSLionel Sambuc     T *foo;
55f4a2713aSLionel Sambuc   };
56f4a2713aSLionel Sambuc 
57f4a2713aSLionel Sambuc   class B;
58f4a2713aSLionel Sambuc 
59f4a2713aSLionel Sambuc   // This causes IR-gen to have an incomplete translation of A<B>
60f4a2713aSLionel Sambuc   // sitting around.
61f4a2713aSLionel Sambuc   A<B> *a;
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc   class C {};
64f4a2713aSLionel Sambuc   class B : public C {
65f4a2713aSLionel Sambuc     // This forces Sema to instantiate A<B>, which triggers a callback
66f4a2713aSLionel Sambuc     // to IR-gen.  Because of the previous, incomplete translation,
67f4a2713aSLionel Sambuc     // IR-gen actually cares, and it immediately tries to complete
68f4a2713aSLionel Sambuc     // A<B>'s IR type.  That, in turn, causes the translation of B*.
69f4a2713aSLionel Sambuc     // B isn't complete yet, but it has a definition, and if we try to
70f4a2713aSLionel Sambuc     // compute a record layout for that definition then we'll really
71f4a2713aSLionel Sambuc     // regret it later.
72f4a2713aSLionel Sambuc     A<B> a;
73f4a2713aSLionel Sambuc   };
74f4a2713aSLionel Sambuc 
75f4a2713aSLionel Sambuc   // The derived class E and empty base class C are required to
76f4a2713aSLionel Sambuc   // provoke the original assertion.
77f4a2713aSLionel Sambuc   class E : public B {};
78f4a2713aSLionel Sambuc   E *e;
79f4a2713aSLionel Sambuc }
80f4a2713aSLionel Sambuc 
81f4a2713aSLionel Sambuc // <rdar://problem/11324125>: Make sure this doesn't crash.  (It's okay
82f4a2713aSLionel Sambuc // if we start rejecting it at some point.)
83f4a2713aSLionel Sambuc namespace Test7 {
84f4a2713aSLionel Sambuc   #pragma pack (1)
85f4a2713aSLionel Sambuc   class A {};
86f4a2713aSLionel Sambuc   // CHECK: %"class.Test7::B" = type <{ i32 (...)**, %"class.Test7::A" }>
87f4a2713aSLionel Sambuc   class B {
88f4a2713aSLionel Sambuc      virtual ~B();
89f4a2713aSLionel Sambuc      A a;
90f4a2713aSLionel Sambuc   };
91f4a2713aSLionel Sambuc   B* b;
92f4a2713aSLionel Sambuc   #pragma pack ()
93f4a2713aSLionel Sambuc }
94*0a6a1f1dSLionel Sambuc 
95*0a6a1f1dSLionel Sambuc // Shouldn't crash.
96*0a6a1f1dSLionel Sambuc namespace Test8 {
97*0a6a1f1dSLionel Sambuc   struct A {};
98*0a6a1f1dSLionel Sambuc   struct D { int a; };
99*0a6a1f1dSLionel Sambuc   struct B : virtual D, A { };
fTest8::C100*0a6a1f1dSLionel Sambuc   struct C : B, A { void f() {} };
101*0a6a1f1dSLionel Sambuc   C c;
102*0a6a1f1dSLionel Sambuc }
103