1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc struct Member { int x; Member(); Member(int); Member(const Member &); };
4f4a2713aSLionel Sambuc struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); };
5f4a2713aSLionel Sambuc 
6f4a2713aSLionel Sambuc struct ValueClass {
ValueClassValueClass7f4a2713aSLionel Sambuc   ValueClass(int x, int y) : x(x), y(y) {}
8f4a2713aSLionel Sambuc   int x;
9f4a2713aSLionel Sambuc   int y;
10f4a2713aSLionel Sambuc }; // subject to ABI trickery
11f4a2713aSLionel Sambuc 
12f4a2713aSLionel Sambuc 
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc /* Test basic functionality. */
15f4a2713aSLionel Sambuc struct A {
16f4a2713aSLionel Sambuc   A(struct Undeclared &);
17f4a2713aSLionel Sambuc   A(ValueClass);
18f4a2713aSLionel Sambuc   Member mem;
19f4a2713aSLionel Sambuc };
20f4a2713aSLionel Sambuc 
A(struct Undeclared & ref)21f4a2713aSLionel Sambuc A::A(struct Undeclared &ref) : mem(0) {}
22f4a2713aSLionel Sambuc 
23f4a2713aSLionel Sambuc // Check that delegation works.
24*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
25f4a2713aSLionel Sambuc // CHECK: call void @_ZN6MemberC1Ei(
26f4a2713aSLionel Sambuc 
27*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
28*0a6a1f1dSLionel Sambuc // CHECK: call void @_ZN1AC2ER10Undeclared(
29f4a2713aSLionel Sambuc 
A(ValueClass v)30*0a6a1f1dSLionel Sambuc A::A(ValueClass v) : mem(v.y - v.x) {}
31f4a2713aSLionel Sambuc 
32f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN1AC2E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
33f4a2713aSLionel Sambuc // CHECK: call void @_ZN6MemberC1Ei(
34f4a2713aSLionel Sambuc 
35*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
36*0a6a1f1dSLionel Sambuc // CHECK: call void @_ZN1AC2E10ValueClass(
37f4a2713aSLionel Sambuc 
38f4a2713aSLionel Sambuc /* Test that things work for inheritance. */
39f4a2713aSLionel Sambuc struct B : A {
40f4a2713aSLionel Sambuc   B(struct Undeclared &);
41f4a2713aSLionel Sambuc   Member mem;
42f4a2713aSLionel Sambuc };
43f4a2713aSLionel Sambuc 
B(struct Undeclared & ref)44f4a2713aSLionel Sambuc B::B(struct Undeclared &ref) : A(ref), mem(1) {}
45f4a2713aSLionel Sambuc 
46*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
47f4a2713aSLionel Sambuc // CHECK: call void @_ZN1AC2ER10Undeclared(
48f4a2713aSLionel Sambuc // CHECK: call void @_ZN6MemberC1Ei(
49f4a2713aSLionel Sambuc 
50*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
51*0a6a1f1dSLionel Sambuc // CHECK: call void @_ZN1BC2ER10Undeclared(
52f4a2713aSLionel Sambuc 
53f4a2713aSLionel Sambuc 
54f4a2713aSLionel Sambuc /* Test that the delegation optimization is disabled for classes with
55f4a2713aSLionel Sambuc    virtual bases (for now).  This is necessary because a vbase
56f4a2713aSLionel Sambuc    initializer could access one of the parameter variables by
57f4a2713aSLionel Sambuc    reference.  That's a solvable problem, but let's not solve it right
58f4a2713aSLionel Sambuc    now. */
59f4a2713aSLionel Sambuc struct C : virtual A {
60f4a2713aSLionel Sambuc   C(int);
61f4a2713aSLionel Sambuc   Member mem;
62f4a2713aSLionel Sambuc };
C(int x)63f4a2713aSLionel Sambuc C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {}
64f4a2713aSLionel Sambuc 
65*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr
66*0a6a1f1dSLionel Sambuc // CHECK: call void @_ZN6MemberC1Ei(
67*0a6a1f1dSLionel Sambuc 
68f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN1CC1Ei(%struct.C* %this, i32 %x) unnamed_addr
69f4a2713aSLionel Sambuc // CHECK: call void @_ZN10ValueClassC1Eii(
70f4a2713aSLionel Sambuc // CHECK: call void @_ZN1AC2E10ValueClass(
71f4a2713aSLionel Sambuc // CHECK: call void @_ZN6MemberC1Ei(
72f4a2713aSLionel Sambuc 
73f4a2713aSLionel Sambuc 
74f4a2713aSLionel Sambuc /* Test that the delegation optimization is disabled for varargs
75f4a2713aSLionel Sambuc    constructors. */
76f4a2713aSLionel Sambuc struct D : A {
77f4a2713aSLionel Sambuc   D(int, ...);
78f4a2713aSLionel Sambuc   Member mem;
79f4a2713aSLionel Sambuc };
80f4a2713aSLionel Sambuc 
D(int x,...)81f4a2713aSLionel Sambuc D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
82f4a2713aSLionel Sambuc 
83f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
84f4a2713aSLionel Sambuc // CHECK: call void @_ZN10ValueClassC1Eii(
85f4a2713aSLionel Sambuc // CHECK: call void @_ZN1AC2E10ValueClass(
86f4a2713aSLionel Sambuc // CHECK: call void @_ZN6MemberC1Ei(
87f4a2713aSLionel Sambuc 
88*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
89*0a6a1f1dSLionel Sambuc // CHECK: call void @_ZN10ValueClassC1Eii(
90*0a6a1f1dSLionel Sambuc // CHECK: call void @_ZN1AC2E10ValueClass(
91*0a6a1f1dSLionel Sambuc // CHECK: call void @_ZN6MemberC1Ei(
92f4a2713aSLionel Sambuc 
93f4a2713aSLionel Sambuc // PR6622:  this shouldn't crash
94f4a2713aSLionel Sambuc namespace test0 {
95f4a2713aSLionel Sambuc   struct A {};
96f4a2713aSLionel Sambuc   struct B : virtual A { int x; };
97f4a2713aSLionel Sambuc   struct C : B {};
98f4a2713aSLionel Sambuc 
test(C & in)99f4a2713aSLionel Sambuc   void test(C &in) {
100f4a2713aSLionel Sambuc     C tmp = in;
101f4a2713aSLionel Sambuc   }
102f4a2713aSLionel Sambuc }
103f4a2713aSLionel Sambuc 
104f4a2713aSLionel Sambuc namespace test1 {
105f4a2713aSLionel Sambuc   struct A { A(); void *ptr; };
106f4a2713aSLionel Sambuc   struct B { B(); int x; A a[0]; };
B()107f4a2713aSLionel Sambuc   B::B() {}
108f4a2713aSLionel Sambuc   // CHECK-LABEL:    define void @_ZN5test11BC2Ev(
109f4a2713aSLionel Sambuc   // CHECK:      [[THIS:%.*]] = load [[B:%.*]]**
110f4a2713aSLionel Sambuc   // CHECK-NEXT: ret void
111f4a2713aSLionel Sambuc }
112