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