Home | History | Annotate | Download | only in CodeGenCXX
      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 
      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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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
    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
    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>
    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 
    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_
    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
    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);
    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()
    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()
    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()
    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(
    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]]* noalias sret
    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]]* noalias sret
    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()
    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]]* noalias sret
    448   struct B { A a; B(); };
    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; };
    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(
    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 
    523 namespace PR11365 {
    524   struct A { A(); ~A(); };
    525 
    526   // CHECK: define void @_ZN7PR113653fooEv(
    527   void foo() {
    528     // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0
    529     // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 3
    530     // CHECK-NEXT: br label
    531 
    532     // CHECK: [[PHI:%.*]] = phi
    533     // CHECK-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]]* [[PHI]], i64 -1
    534     // CHECK-NEXT: call void @_ZN7PR113651AD1Ev([[A]]* [[ELEM]])
    535     // CHECK-NEXT: icmp eq [[A]]* [[ELEM]], [[BEGIN]]
    536     // CHECK-NEXT: br i1
    537     (void) (A [3]) {};
    538   }
    539 }
    540