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   };
     57 
     58   struct B final : A {
     59     virtual void f();
     60   };
     61 
     62   // CHECK-LABEL: define void @_ZN5Test41fEPNS_1BE
     63   void f(B* d) {
     64     // CHECK: call void @_ZN5Test41B1fEv
     65     static_cast<A*>(d)->f();
     66   }
     67 }
     68 
     69 namespace Test5 {
     70   struct A {
     71     virtual void f();
     72   };
     73 
     74   struct B : A {
     75     virtual void f();
     76   };
     77 
     78   struct C final : B {
     79   };
     80 
     81   // CHECK-LABEL: define void @_ZN5Test51fEPNS_1CE
     82   void f(C* d) {
     83     // FIXME: It should be possible to devirtualize this case, but that is
     84     // not implemented yet.
     85     // CHECK: getelementptr
     86     // CHECK-NEXT: %[[FUNC:.*]] = load
     87     // CHECK-NEXT: call void %[[FUNC]]
     88     static_cast<A*>(d)->f();
     89   }
     90 }
     91 
     92 namespace Test6 {
     93   struct A {
     94     virtual ~A();
     95   };
     96 
     97   struct B : public A {
     98     virtual ~B();
     99   };
    100 
    101   struct C {
    102     virtual ~C();
    103   };
    104 
    105   struct D final : public C, public B {
    106   };
    107 
    108   // CHECK-LABEL: define void @_ZN5Test61fEPNS_1DE
    109   void f(D* d) {
    110     // CHECK: call void @_ZN5Test61DD1Ev
    111     static_cast<A*>(d)->~A();
    112   }
    113 }
    114 
    115 namespace Test7 {
    116   struct foo {
    117     virtual void g() {}
    118   };
    119 
    120   struct bar {
    121     virtual int f() { return 0; }
    122   };
    123 
    124   struct zed final : public foo, public bar {
    125     int z;
    126     virtual int f() {return z;}
    127   };
    128 
    129   // CHECK-LABEL: define i32 @_ZN5Test71fEPNS_3zedE
    130   int f(zed *z) {
    131     // CHECK: alloca
    132     // CHECK-NEXT: store
    133     // CHECK-NEXT: load
    134     // CHECK-NEXT: call i32 @_ZN5Test73zed1fEv
    135     // CHECK-NEXT: ret
    136     return static_cast<bar*>(z)->f();
    137   }
    138 }
    139 
    140 namespace Test8 {
    141   struct A { virtual ~A() {} };
    142   struct B {
    143     int b;
    144     virtual int foo() { return b; }
    145   };
    146   struct C final : A, B {  };
    147   // CHECK-LABEL: define i32 @_ZN5Test84testEPNS_1CE
    148   int test(C *c) {
    149     // CHECK: %[[THIS:.*]] = phi
    150     // CHECK-NEXT: call i32 @_ZN5Test81B3fooEv(%"struct.Test8::B"* %[[THIS]])
    151     return static_cast<B*>(c)->foo();
    152   }
    153 }
    154 
    155 namespace Test9 {
    156   struct A {
    157     int a;
    158   };
    159   struct B {
    160     int b;
    161   };
    162   struct C : public B, public A {
    163   };
    164   struct RA {
    165     virtual A *f() {
    166       return 0;
    167     }
    168   };
    169   struct RC final : public RA {
    170     virtual C *f() {
    171       C *x = new C();
    172       x->a = 1;
    173       x->b = 2;
    174       return x;
    175     }
    176   };
    177   // CHECK: define {{.*}} @_ZN5Test91fEPNS_2RCE
    178   A *f(RC *x) {
    179     // FIXME: It should be possible to devirtualize this case, but that is
    180     // not implemented yet.
    181     // CHECK: getelementptr
    182     // CHECK-NEXT: %[[FUNC:.*]] = load
    183     // CHECK-NEXT: bitcast
    184     // CHECK-NEXT: = call {{.*}} %[[FUNC]]
    185     return static_cast<RA*>(x)->f();
    186   }
    187 }
    188