1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
2f4a2713aSLionel Sambuc
3f4a2713aSLionel Sambuc extern "C" int printf(...);
4f4a2713aSLionel Sambuc
5f4a2713aSLionel Sambuc int init = 100;
6f4a2713aSLionel Sambuc
7f4a2713aSLionel Sambuc struct M {
8f4a2713aSLionel Sambuc int iM;
MM9f4a2713aSLionel Sambuc M() : iM(init++) {}
10f4a2713aSLionel Sambuc };
11f4a2713aSLionel Sambuc
12f4a2713aSLionel Sambuc struct N {
13f4a2713aSLionel Sambuc int iN;
NN14f4a2713aSLionel Sambuc N() : iN(200) {}
NN15f4a2713aSLionel Sambuc N(N const & arg){this->iN = arg.iN; }
16f4a2713aSLionel Sambuc };
17f4a2713aSLionel Sambuc
18f4a2713aSLionel Sambuc struct P {
19f4a2713aSLionel Sambuc int iP;
PP20f4a2713aSLionel Sambuc P() : iP(init++) {}
21f4a2713aSLionel Sambuc };
22f4a2713aSLionel Sambuc
23f4a2713aSLionel Sambuc
24*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN1XC1ERKS_(%struct.X* %this, %struct.X* dereferenceable({{[0-9]+}})) unnamed_addr
25f4a2713aSLionel Sambuc struct X : M, N, P { // ...
XX26f4a2713aSLionel Sambuc X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd),
27f4a2713aSLionel Sambuc au_i1(1234), au1_4("MASKED") {}
28f4a2713aSLionel Sambuc P p0;
prX29f4a2713aSLionel Sambuc void pr() {
30f4a2713aSLionel Sambuc printf("iM = %d iN = %d, m1.iM = %d\n", iM, iN, m1.iM);
31f4a2713aSLionel Sambuc printf("im = %d p0.iP = %d, p1.iP = %d\n", iP, p0.iP, p1.iP);
32f4a2713aSLionel Sambuc printf("f1 = %f d1 = %f i1 = %d name(%s) \n", f1, d1, i1, name);
33f4a2713aSLionel Sambuc printf("bf1 = %x bf2 = %x\n", bf1, bf2);
34f4a2713aSLionel Sambuc printf("au_i2 = %d\n", au_i2);
35f4a2713aSLionel Sambuc printf("au1_1 = %s\n", au1_1);
36f4a2713aSLionel Sambuc }
37f4a2713aSLionel Sambuc M m1;
38f4a2713aSLionel Sambuc P p1;
39f4a2713aSLionel Sambuc float f1;
40f4a2713aSLionel Sambuc double d1;
41f4a2713aSLionel Sambuc int i1;
42f4a2713aSLionel Sambuc const char *name;
43f4a2713aSLionel Sambuc unsigned bf1 : 8;
44f4a2713aSLionel Sambuc unsigned bf2 : 16;
45f4a2713aSLionel Sambuc int arr[2];
46f4a2713aSLionel Sambuc _Complex float complex;
47f4a2713aSLionel Sambuc
48f4a2713aSLionel Sambuc union {
49f4a2713aSLionel Sambuc int au_i1;
50f4a2713aSLionel Sambuc int au_i2;
51f4a2713aSLionel Sambuc };
52f4a2713aSLionel Sambuc union {
53f4a2713aSLionel Sambuc const char * au1_1;
54f4a2713aSLionel Sambuc float au1_2;
55f4a2713aSLionel Sambuc int au1_3;
56f4a2713aSLionel Sambuc const char * au1_4;
57f4a2713aSLionel Sambuc };
58f4a2713aSLionel Sambuc };
59f4a2713aSLionel Sambuc
60f4a2713aSLionel Sambuc static int ix = 1;
61f4a2713aSLionel Sambuc // class with user-defined copy constructor.
62f4a2713aSLionel Sambuc struct S {
SS63f4a2713aSLionel Sambuc S() : iS(ix++) { }
SS64f4a2713aSLionel Sambuc S(const S& arg) { *this = arg; }
65f4a2713aSLionel Sambuc int iS;
66f4a2713aSLionel Sambuc };
67f4a2713aSLionel Sambuc
68f4a2713aSLionel Sambuc // class with trivial copy constructor.
69f4a2713aSLionel Sambuc struct I {
II70f4a2713aSLionel Sambuc I() : iI(ix++) { }
71f4a2713aSLionel Sambuc int iI;
72f4a2713aSLionel Sambuc };
73f4a2713aSLionel Sambuc
74f4a2713aSLionel Sambuc struct XM {
XMXM75f4a2713aSLionel Sambuc XM() { }
76f4a2713aSLionel Sambuc double dXM;
77f4a2713aSLionel Sambuc S ARR_S[3][4][2];
prXM78f4a2713aSLionel Sambuc void pr() {
79f4a2713aSLionel Sambuc for (unsigned i = 0; i < 3; i++)
80f4a2713aSLionel Sambuc for (unsigned j = 0; j < 4; j++)
81f4a2713aSLionel Sambuc for (unsigned k = 0; k < 2; k++)
82f4a2713aSLionel Sambuc printf("ARR_S[%d][%d][%d] = %d\n", i,j,k, ARR_S[i][j][k].iS);
83f4a2713aSLionel Sambuc for (unsigned i = 0; i < 3; i++)
84f4a2713aSLionel Sambuc for (unsigned k = 0; k < 2; k++)
85f4a2713aSLionel Sambuc printf("ARR_I[%d][%d] = %d\n", i,k, ARR_I[i][k].iI);
86f4a2713aSLionel Sambuc }
87f4a2713aSLionel Sambuc I ARR_I[3][2];
88f4a2713aSLionel Sambuc };
89f4a2713aSLionel Sambuc
main()90f4a2713aSLionel Sambuc int main() {
91f4a2713aSLionel Sambuc X a;
92f4a2713aSLionel Sambuc X b(a);
93f4a2713aSLionel Sambuc b.pr();
94f4a2713aSLionel Sambuc X x;
95f4a2713aSLionel Sambuc X c(x);
96f4a2713aSLionel Sambuc c.pr();
97f4a2713aSLionel Sambuc
98f4a2713aSLionel Sambuc XM m0;
99f4a2713aSLionel Sambuc XM m1 = m0;
100f4a2713aSLionel Sambuc m1.pr();
101f4a2713aSLionel Sambuc }
102f4a2713aSLionel Sambuc
103f4a2713aSLionel Sambuc struct A {
104f4a2713aSLionel Sambuc };
105f4a2713aSLionel Sambuc
106f4a2713aSLionel Sambuc struct B : A {
107f4a2713aSLionel Sambuc A &a;
108f4a2713aSLionel Sambuc };
109f4a2713aSLionel Sambuc
f(const B & b1)110f4a2713aSLionel Sambuc void f(const B &b1) {
111f4a2713aSLionel Sambuc B b2(b1);
112f4a2713aSLionel Sambuc }
113f4a2713aSLionel Sambuc
114f4a2713aSLionel Sambuc // PR6628
115f4a2713aSLionel Sambuc namespace PR6628 {
116f4a2713aSLionel Sambuc
117f4a2713aSLionel Sambuc struct T {
118f4a2713aSLionel Sambuc T();
119f4a2713aSLionel Sambuc ~T();
120f4a2713aSLionel Sambuc
121f4a2713aSLionel Sambuc double d;
122f4a2713aSLionel Sambuc };
123f4a2713aSLionel Sambuc
124f4a2713aSLionel Sambuc struct A {
125f4a2713aSLionel Sambuc A(const A &other, const T &t = T(), const T& t2 = T());
126f4a2713aSLionel Sambuc };
127f4a2713aSLionel Sambuc
128f4a2713aSLionel Sambuc struct B : A {
129f4a2713aSLionel Sambuc A a1;
130f4a2713aSLionel Sambuc A a2;
131f4a2713aSLionel Sambuc A a[10];
132f4a2713aSLionel Sambuc };
133f4a2713aSLionel Sambuc
134f4a2713aSLionel Sambuc // Force the copy constructor to be synthesized.
f(B b1)135f4a2713aSLionel Sambuc void f(B b1) {
136f4a2713aSLionel Sambuc B b2 = b1;
137f4a2713aSLionel Sambuc }
138f4a2713aSLionel Sambuc
139*0a6a1f1dSLionel Sambuc // CHECK: define linkonce_odr dereferenceable({{[0-9]+}}) [[A:%.*]]* @_ZN12rdar138169401AaSERKS0_(
140f4a2713aSLionel Sambuc // CHECK: [[THIS:%.*]] = load [[A]]**
141f4a2713aSLionel Sambuc // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
142f4a2713aSLionel Sambuc // CHECK-NEXT: [[OTHER:%.*]] = load [[A]]**
143f4a2713aSLionel Sambuc // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* [[OTHER]], i32 0, i32 1
144*0a6a1f1dSLionel Sambuc // CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8*
145*0a6a1f1dSLionel Sambuc // CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8*
146f4a2713aSLionel Sambuc // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false)
147f4a2713aSLionel Sambuc // CHECK-NEXT: ret [[A]]* [[THIS]]
148f4a2713aSLionel Sambuc
149f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_(
150f4a2713aSLionel Sambuc // CHECK: [[THIS:%.*]] = load [[A]]**
151*0a6a1f1dSLionel Sambuc // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i32 (...)***
152*0a6a1f1dSLionel Sambuc // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN12rdar138169401AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]]
153f4a2713aSLionel Sambuc // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
154f4a2713aSLionel Sambuc // CHECK-NEXT: [[OTHER:%.*]] = load [[A]]**
155f4a2713aSLionel Sambuc // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* [[OTHER]], i32 0, i32 1
156*0a6a1f1dSLionel Sambuc // CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8*
157*0a6a1f1dSLionel Sambuc // CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8*
158f4a2713aSLionel Sambuc // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false)
159f4a2713aSLionel Sambuc // CHECK-NEXT: ret void
160f4a2713aSLionel Sambuc
161*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"* dereferenceable({{[0-9]+}})) unnamed_addr
162f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TC1Ev
163f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TC1Ev
164f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281AC2ERKS0_RKNS_1TES5_
165f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TD1Ev
166f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TD1Ev
167f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TC1Ev
168f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TC1Ev
169f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_
170f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TD1Ev
171f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TD1Ev
172f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TC1Ev
173f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TC1Ev
174f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_
175f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TD1Ev
176f4a2713aSLionel Sambuc // CHECK: call void @_ZN6PR66281TD1Ev
177f4a2713aSLionel Sambuc }
178f4a2713aSLionel Sambuc
179f4a2713aSLionel Sambuc // rdar://13816940
180f4a2713aSLionel Sambuc // Test above because things get weirdly re-ordered.
181f4a2713aSLionel Sambuc namespace rdar13816940 {
182f4a2713aSLionel Sambuc struct A {
183f4a2713aSLionel Sambuc virtual ~A();
184f4a2713aSLionel Sambuc unsigned short a : 1;
185f4a2713aSLionel Sambuc unsigned short : 15;
186f4a2713aSLionel Sambuc unsigned other;
187f4a2713aSLionel Sambuc };
188f4a2713aSLionel Sambuc
test(A & a)189f4a2713aSLionel Sambuc void test(A &a) {
190f4a2713aSLionel Sambuc A x = a; // force copy constructor into existence
191f4a2713aSLionel Sambuc x = a; // also force the copy assignment operator
192f4a2713aSLionel Sambuc }
193f4a2713aSLionel Sambuc }
194