• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
2 struct A {
3   A();
4   ~A();
5   void f();
6 };
7 
f1()8 void f1() {
9   // CHECK: call void @_ZN1AC1Ev
10   // CHECK: call void @_ZN1AD1Ev
11   (void)A();
12 
13   // CHECK: call void @_ZN1AC1Ev
14   // CHECK: call void @_ZN1AD1Ev
15   A().f();
16 }
17 
18 // Function calls
19 struct B {
20   B();
21   ~B();
22 };
23 
24 B g();
25 
f2()26 void f2() {
27   // CHECK-NOT: call void @_ZN1BC1Ev
28   // CHECK: call void @_ZN1BD1Ev
29   (void)g();
30 }
31 
32 // Member function calls
33 struct C {
34   C();
35   ~C();
36 
37   C f();
38 };
39 
f3()40 void f3() {
41   // CHECK: call void @_ZN1CC1Ev
42   // CHECK: call void @_ZN1CD1Ev
43   // CHECK: call void @_ZN1CD1Ev
44   C().f();
45 }
46 
47 // Function call operator
48 struct D {
49   D();
50   ~D();
51 
52   D operator()();
53 };
54 
f4()55 void f4() {
56   // CHECK: call void @_ZN1DC1Ev
57   // CHECK: call void @_ZN1DD1Ev
58   // CHECK: call void @_ZN1DD1Ev
59   D()();
60 }
61 
62 // Overloaded operators
63 struct E {
64   E();
65   ~E();
66   E operator+(const E&);
67   E operator!();
68 };
69 
f5()70 void f5() {
71   // CHECK: call void @_ZN1EC1Ev
72   // CHECK: call void @_ZN1EC1Ev
73   // CHECK: call void @_ZN1ED1Ev
74   // CHECK: call void @_ZN1ED1Ev
75   // CHECK: call void @_ZN1ED1Ev
76   E() + E();
77 
78   // CHECK: call void @_ZN1EC1Ev
79   // CHECK: call void @_ZN1ED1Ev
80   // CHECK: call void @_ZN1ED1Ev
81   !E();
82 }
83 
84 struct F {
85   F();
86   ~F();
87   F& f();
88 };
89 
f6()90 void f6() {
91   // CHECK: call void @_ZN1FC1Ev
92   // CHECK: call void @_ZN1FD1Ev
93   F().f();
94 }
95 
96 struct G {
97   G();
98   G(A);
99   ~G();
100   operator A();
101 };
102 
103 void a(const A&);
104 
f7()105 void f7() {
106   // CHECK: call void @_ZN1AC1Ev
107   // CHECK: call void @_Z1aRK1A
108   // CHECK: call void @_ZN1AD1Ev
109   a(A());
110 
111   // CHECK: call void @_ZN1GC1Ev
112   // CHECK: call void @_ZN1Gcv1AEv
113   // CHECK: call void @_Z1aRK1A
114   // CHECK: call void @_ZN1AD1Ev
115   // CHECK: call void @_ZN1GD1Ev
116   a(G());
117 }
118 
119 namespace PR5077 {
120 
121 struct A {
122   A();
123   ~A();
124   int f();
125 };
126 
127 void f();
128 int g(const A&);
129 
130 struct B {
131   int a1;
132   int a2;
133   B();
134   ~B();
135 };
136 
B()137 B::B()
138   // CHECK: call void @_ZN6PR50771AC1Ev
139   // CHECK: call i32 @_ZN6PR50771A1fEv
140   // CHECK: call void @_ZN6PR50771AD1Ev
141   : a1(A().f())
142   // CHECK: call void @_ZN6PR50771AC1Ev
143   // CHECK: call i32 @_ZN6PR50771gERKNS_1AE
144   // CHECK: call void @_ZN6PR50771AD1Ev
145   , a2(g(A()))
146 {
147   // CHECK: call void @_ZN6PR50771fEv
148   f();
149 }
150 
151 struct C {
152   C();
153 
154   const B& b;
155 };
156 
C()157 C::C()
158   // CHECK: call void @_ZN6PR50771BC1Ev
159   : b(B()) {
160   // CHECK: call void @_ZN6PR50771fEv
161   f();
162 
163   // CHECK: call void @_ZN6PR50771BD1Ev
164 }
165 }
166 
f8()167 A f8() {
168   // CHECK: call void @_ZN1AC1Ev
169   // CHECK-NOT: call void @_ZN1AD1Ev
170   return A();
171   // CHECK: ret void
172 }
173 
174 struct H {
175   H();
176   ~H();
177   H(const H&);
178 };
179 
f9(H h)180 void f9(H h) {
181   // CHECK: call void @_ZN1HC1Ev
182   // CHECK: call void @_Z2f91H
183   // CHECK: call void @_ZN1HD1Ev
184   f9(H());
185 
186   // CHECK: call void @_ZN1HC1ERKS_
187   // CHECK: call void @_Z2f91H
188   // CHECK: call void @_ZN1HD1Ev
189   f9(h);
190 }
191 
192 void f10(const H&);
193 
f11(H h)194 void f11(H h) {
195   // CHECK: call void @_ZN1HC1Ev
196   // CHECK: call void @_Z3f10RK1H
197   // CHECK: call void @_ZN1HD1Ev
198   f10(H());
199 
200   // CHECK: call void @_Z3f10RK1H
201   // CHECK-NOT: call void @_ZN1HD1Ev
202   // CHECK: ret void
203   f10(h);
204 }
205 
206 // PR5808
207 struct I {
208   I(const char *);
209   ~I();
210 };
211 
212 // CHECK: _Z3f12v
f12()213 I f12() {
214   // CHECK: call void @_ZN1IC1EPKc
215   // CHECK-NOT: call void @_ZN1ID1Ev
216   // CHECK: ret void
217   return "Hello";
218 }
219 
220 // PR5867
221 namespace PR5867 {
222   struct S {
223     S();
224     S(const S &);
225     ~S();
226   };
227 
228   void f(S, int);
229   // CHECK: define void @_ZN6PR58671gEv
g()230   void g() {
231     // CHECK: call void @_ZN6PR58671SC1Ev
232     // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
233     // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
234     // CHECK-NEXT: ret void
235     (f)(S(), 0);
236   }
237 
238   // CHECK: define linkonce_odr void @_ZN6PR58672g2IiEEvT_
239   template<typename T>
g2(T)240   void g2(T) {
241     // CHECK: call void @_ZN6PR58671SC1Ev
242     // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
243     // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
244     // CHECK-NEXT: ret void
245     (f)(S(), 0);
246   }
247 
h()248   void h() {
249     g2(17);
250   }
251 }
252 
253 // PR6199
254 namespace PR6199 {
255   struct A { ~A(); };
256 
257   struct B { operator A(); };
258 
259   // CHECK: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_
f2(T)260   template<typename T> A f2(T) {
261     B b;
262     // CHECK: call void @_ZN6PR61991BcvNS_1AEEv
263     // CHECK-NEXT: ret void
264     return b;
265   }
266 
267   template A f2<int>(int);
268 
269 }
270 
271 namespace T12 {
272 
273 struct A {
274   A();
275   ~A();
276   int f();
277 };
278 
279 int& f(int);
280 
281 // CHECK: define void @_ZN3T121gEv
g()282 void g() {
283   // CHECK: call void @_ZN3T121AC1Ev
284   // CHECK-NEXT: call i32 @_ZN3T121A1fEv(
285   // CHECK-NEXT: call i32* @_ZN3T121fEi(
286   // CHECK-NEXT: call void @_ZN3T121AD1Ev(
287   int& i = f(A().f());
288 }
289 
290 }
291 
292 namespace PR6648 {
293   struct B {
294     ~B();
295   };
296   B foo;
297   struct D;
298   D& zed(B);
foobar()299   void foobar() {
300     // CHECK: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
301     zed(foo);
302   }
303 }
304 
305 namespace UserConvertToValue {
306   struct X {
307     X(int);
308     X(const X&);
309     ~X();
310   };
311 
312   void f(X);
313 
314   // CHECK: void @_ZN18UserConvertToValue1gEv()
g()315   void g() {
316     // CHECK: call void @_ZN18UserConvertToValue1XC1Ei
317     // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE
318     // CHECK: call void @_ZN18UserConvertToValue1XD1Ev
319     // CHECK: ret void
320     f(1);
321   }
322 }
323 
324 namespace PR7556 {
325   struct A { ~A(); };
326   struct B { int i; ~B(); };
327   struct C { int C::*pm; ~C(); };
328   // CHECK: define void @_ZN6PR75563fooEv()
foo()329   void foo() {
330     // CHECK: call void @_ZN6PR75561AD1Ev
331     A();
332     // CHECK: call void @llvm.memset.p0i8.i64
333     // CHECK: call void @_ZN6PR75561BD1Ev
334     B();
335     // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
336     // CHECK: call void @_ZN6PR75561CD1Ev
337     C();
338     // CHECK-NEXT: ret void
339   }
340 }
341 
342 namespace Elision {
343   struct A {
344     A(); A(const A &); ~A();
345     void *p;
346     void foo() const;
347   };
348 
349   void foo();
350   A fooA();
351   void takeA(A a);
352 
353   // CHECK: define void @_ZN7Elision5test0Ev()
test0()354   void test0() {
355     // CHECK:      [[I:%.*]] = alloca [[A:%.*]], align 8
356     // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
357     // CHECK-NEXT: [[T0:%.*]] = alloca [[A]], align 8
358     // CHECK-NEXT: [[K:%.*]] = alloca [[A]], align 8
359     // CHECK-NEXT: [[T1:%.*]] = alloca [[A]], align 8
360 
361     // CHECK-NEXT: call void @_ZN7Elision3fooEv()
362     // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
363     A i = (foo(), A());
364 
365     // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]])
366     // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
367     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
368     A j = (fooA(), A());
369 
370     // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]])
371     // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]])
372     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]])
373     A k = (A(), fooA());
374 
375     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]])
376     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
377     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
378   }
379 
380 
381   // CHECK: define void @_ZN7Elision5test1EbNS_1AE(
test1(bool c,A x)382   void test1(bool c, A x) {
383     // CHECK:      [[I:%.*]] = alloca [[A]], align 8
384     // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
385 
386     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
387     // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* [[X:%.*]])
388     A i = (c ? A() : x);
389 
390     // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* [[X]])
391     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
392     A j = (c ? x : A());
393 
394     // CHECK:      call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
395     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
396   }
397 
398   // CHECK: define void @_ZN7Elision5test2Ev([[A]]* sret
test2()399   A test2() {
400     // CHECK:      call void @_ZN7Elision3fooEv()
401     // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
402     // CHECK-NEXT: ret void
403     return (foo(), A());
404   }
405 
406   // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* sret
test3(int v,A x)407   A test3(int v, A x) {
408     if (v < 5)
409     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
410     // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X:%.*]])
411       return (v < 0 ? A() : x);
412     else
413     // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X]])
414     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[RET]])
415       return (v > 10 ? x : A());
416 
417     // CHECK:      ret void
418   }
419 
420   // CHECK: define void @_ZN7Elision5test4Ev()
test4()421   void test4() {
422     // CHECK:      [[X:%.*]] = alloca [[A]], align 8
423     // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16
424 
425     // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]])
426     A x;
427 
428     // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i64 0, i64 0
429     // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
430     // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]]* [[XS0]], i64 1
431     // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* [[X]])
432     A xs[] = { A(), x };
433 
434     // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
435     // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 2
436     // CHECK-NEXT: br label
437     // CHECK:      [[AFTER:%.*]] = phi [[A]]*
438     // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
439     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]])
440     // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
441     // CHECK-NEXT: br i1 [[T0]],
442 
443     // CHECK:      call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
444   }
445 
446   // rdar://problem/8433352
447   // CHECK: define void @_ZN7Elision5test5Ev([[A]]* sret
448   struct B { A a; B(); };
test5()449   A test5() {
450     // CHECK:      [[AT0:%.*]] = alloca [[A]], align 8
451     // CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8
452     // CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8
453     // CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8
454     // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8
455 
456     // CHECK:      call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]])
457     // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT0]], i32 0, i32 0
458     // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* [[AM]])
459     // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]])
460     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]])
461     // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]])
462     takeA(B().a);
463 
464     // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]])
465     // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT1]], i32 0, i32 0
466     // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* [[AM]])
467     // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]])
468     A x = B().a;
469 
470     // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]])
471     // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT2]], i32 0, i32 0
472     // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* [[AM]])
473     // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]])
474     return B().a;
475 
476     // CHECK:      call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
477   }
478 
479   // Reduced from webkit.
480   // CHECK: define void @_ZN7Elision5test6EPKNS_1CE([[C:%.*]]*
481   struct C { operator A() const; };
test6(const C * x)482   void test6(const C *x) {
483     // CHECK:      [[T0:%.*]] = alloca [[A]], align 8
484     // CHECK:      [[X:%.*]] = load [[C]]** {{%.*}}, align 8
485     // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]])
486     // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]])
487     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
488     // CHECK-NEXT: ret void
489     A(*x).foo();
490   }
491 }
492 
493 namespace PR8623 {
494   struct A { A(int); ~A(); };
495 
496   // CHECK: define void @_ZN6PR86233fooEb(
foo(bool b)497   void foo(bool b) {
498     // CHECK:      [[TMP:%.*]] = alloca [[A:%.*]], align 1
499     // CHECK-NEXT: [[LCONS:%.*]] = alloca i1
500     // CHECK-NEXT: [[RCONS:%.*]] = alloca i1
501     // CHECK:      store i1 false, i1* [[LCONS]]
502     // CHECK-NEXT: store i1 false, i1* [[RCONS]]
503     // CHECK-NEXT: br i1
504     // CHECK:      call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2)
505     // CHECK-NEXT: store i1 true, i1* [[LCONS]]
506     // CHECK-NEXT: br label
507     // CHECK:      call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3)
508     // CHECK-NEXT: store i1 true, i1* [[RCONS]]
509     // CHECK-NEXT: br label
510     // CHECK:      load i1* [[RCONS]]
511     // CHECK-NEXT: br i1
512     // CHECK:      call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
513     // CHECK-NEXT: br label
514     // CHECK:      load i1* [[LCONS]]
515     // CHECK-NEXT: br i1
516     // CHECK:      call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
517     // CHECK-NEXT: br label
518     // CHECK:      ret void
519     b ? A(2) : A(3);
520   }
521 }
522