Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 %s -emit-llvm -o - | FileCheck %s
      2 
      3 namespace Test1 {
      4   struct A {
      5     virtual int f() final;
      6   };
      7 
      8   // CHECK-LABEL: define i32 @_ZN5Test11fEPNS_1AE
      9   int f(A *a) {
     10     // CHECK: call i32 @_ZN5Test11A1fEv
     11     return a->f();
     12   }
     13 }
     14 
     15 namespace Test2 {
     16   struct A final {
     17     virtual int f();
     18   };
     19 
     20   // CHECK-LABEL: define i32 @_ZN5Test21fEPNS_1AE
     21   int f(A *a) {
     22     // CHECK: call i32 @_ZN5Test21A1fEv
     23     return a->f();
     24   }
     25 }
     26 
     27 namespace Test3 {
     28   struct A {
     29     virtual int f();
     30   };
     31 
     32   struct B final : A { };
     33 
     34   // CHECK-LABEL: define i32 @_ZN5Test31fEPNS_1BE
     35   int f(B *b) {
     36     // CHECK: call i32 @_ZN5Test31A1fEv
     37     return b->f();
     38   }
     39 
     40   // CHECK-LABEL: define i32 @_ZN5Test31fERNS_1BE
     41   int f(B &b) {
     42     // CHECK: call i32 @_ZN5Test31A1fEv
     43     return b.f();
     44   }
     45 
     46   // CHECK-LABEL: define i32 @_ZN5Test31fEPv
     47   int f(void *v) {
     48     // CHECK: call i32 @_ZN5Test31A1fEv
     49     return static_cast<B*>(v)->f();
     50   }
     51 }
     52 
     53 namespace Test4 {
     54   struct A {
     55     virtual void f();
     56     virtual int operator-();
     57   };
     58 
     59   struct B final : A {
     60     virtual void f();
     61     virtual int operator-();
     62   };
     63 
     64   // CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE
     65   void f(B* d) {
     66     // CHECK: call void @_ZN5Test41B1fEv
     67     static_cast<A*>(d)->f();
     68     // CHECK: call i32 @_ZN5Test41BngEv
     69     -static_cast<A&>(*d);
     70   }
     71 }
     72 
     73 namespace Test5 {
     74   struct A {
     75     virtual void f();
     76     virtual int operator-();
     77   };
     78 
     79   struct B : A {
     80     virtual void f();
     81     virtual int operator-();
     82   };
     83 
     84   struct C final : B {
     85   };
     86 
     87   // CHECK-LABEL: define void @_ZN5Test51fEPNS_1CE
     88   void f(C* d) {
     89     // FIXME: It should be possible to devirtualize this case, but that is
     90     // not implemented yet.
     91     // CHECK: getelementptr
     92     // CHECK-NEXT: %[[FUNC:.*]] = load
     93     // CHECK-NEXT: call void %[[FUNC]]
     94     static_cast<A*>(d)->f();
     95   }
     96   // CHECK-LABEL: define void @_ZN5Test53fopEPNS_1CE
     97   void fop(C* d) {
     98     // FIXME: It should be possible to devirtualize this case, but that is
     99     // not implemented yet.
    100     // CHECK: getelementptr
    101     // CHECK-NEXT: %[[FUNC:.*]] = load
    102     // CHECK-NEXT: call i32 %[[FUNC]]
    103     -static_cast<A&>(*d);
    104   }
    105 }
    106 
    107 namespace Test6 {
    108   struct A {
    109     virtual ~A();
    110   };
    111 
    112   struct B : public A {
    113     virtual ~B();
    114   };
    115 
    116   struct C {
    117     virtual ~C();
    118   };
    119 
    120   struct D final : public C, public B {
    121   };
    122 
    123   // CHECK-LABEL: define void @_ZN5Test61fEPNS_1DE
    124   void f(D* d) {
    125     // CHECK: call void @_ZN5Test61DD1Ev
    126     static_cast<A*>(d)->~A();
    127   }
    128 }
    129 
    130 namespace Test7 {
    131   struct foo {
    132     virtual void g() {}
    133   };
    134 
    135   struct bar {
    136     virtual int f() { return 0; }
    137   };
    138 
    139   struct zed final : public foo, public bar {
    140     int z;
    141     virtual int f() {return z;}
    142   };
    143 
    144   // CHECK-LABEL: define i32 @_ZN5Test71fEPNS_3zedE
    145   int f(zed *z) {
    146     // CHECK: alloca
    147     // CHECK-NEXT: store
    148     // CHECK-NEXT: load
    149     // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv
    150     // CHECK-NEXT: ret
    151     return static_cast<bar*>(z)->f();
    152   }
    153 }
    154 
    155 namespace Test8 {
    156   struct A { virtual ~A() {} };
    157   struct B {
    158     int b;
    159     virtual int foo() { return b; }
    160   };
    161   struct C final : A, B {  };
    162   // CHECK-LABEL: define i32 @_ZN5Test84testEPNS_1CE
    163   int test(C *c) {
    164     // CHECK: %[[THIS:.*]] = phi
    165     // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]])
    166     return static_cast<B*>(c)->foo();
    167   }
    168 }
    169 
    170 namespace Test9 {
    171   struct A {
    172     int a;
    173   };
    174   struct B {
    175     int b;
    176   };
    177   struct C : public B, public A {
    178   };
    179   struct RA {
    180     virtual A *f() {
    181       return 0;
    182     }
    183     virtual A *operator-() {
    184       return 0;
    185     }
    186   };
    187   struct RC final : public RA {
    188     virtual C *f() {
    189       C *x = new C();
    190       x->a = 1;
    191       x->b = 2;
    192       return x;
    193     }
    194     virtual C *operator-() {
    195       C *x = new C();
    196       x->a = 1;
    197       x->b = 2;
    198       return x;
    199     }
    200   };
    201   // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
    202   A *f(RC *x) {
    203     // FIXME: It should be possible to devirtualize this case, but that is
    204     // not implemented yet.
    205     // CHECK: load
    206     // CHECK: bitcast
    207     // CHECK: [[F_PTR_RA:%.+]] = bitcast
    208     // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
    209     // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 0
    210     // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
    211     // CHECK-NEXT: = call {{.*}} %[[FUNC]]
    212     return static_cast<RA*>(x)->f();
    213   }
    214   // CHECK: define {{.*}} @_ZN5Test93fopEPNS_2RCE
    215   A *fop(RC *x) {
    216     // FIXME: It should be possible to devirtualize this case, but that is
    217     // not implemented yet.
    218     // CHECK: load
    219     // CHECK: bitcast
    220     // CHECK: [[F_PTR_RA:%.+]] = bitcast
    221     // CHECK: [[VTABLE:%.+]] = load {{.+}} [[F_PTR_RA]]
    222     // CHECK: [[VFN:%.+]] = getelementptr inbounds {{.+}} [[VTABLE]], i{{[0-9]+}} 1
    223     // CHECK-NEXT: %[[FUNC:.*]] = load {{.+}} [[VFN]]
    224     // CHECK-NEXT: = call {{.*}} %[[FUNC]]
    225     return -static_cast<RA&>(*x);
    226   }
    227 }
    228