Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s
      2 
      3 // CHECK: @_ZTV1A = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null]
      4 // CHECK: @_ZTV4Base = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null]
      5 // CHECK: @_ZTV8Derived2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null]
      6 // CHECK: @_ZTV2D2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_ZNK2D23abcEv to i8*), i8* null]
      7 
      8 struct A {
      9   virtual const char* abc(void) const;
     10 };
     11 
     12 const char* A::abc(void) const {return "A"; };
     13 
     14 struct B : virtual A {
     15   virtual void VF();
     16 };
     17 
     18 void B::VF() {}
     19 
     20 void FUNC(B* p) {
     21 // CHECK: [[T1:%.*]] = load i8* (%struct.A*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV1A to i8* (%struct.A*)**), i64 2)
     22 // CHECK-NEXT:  [[T2:%.*]] = call i8* [[T1]]
     23   const char* c = p->A::abc();
     24 }
     25 
     26 
     27 // Test2
     28 struct Base { virtual char* abc(void) const; };
     29 
     30 char* Base::abc() const { return 0; }
     31 
     32 struct Derived : public Base {
     33 };
     34 
     35 void FUNC1(Derived* p) {
     36 // CHECK: [[U1:%.*]] = load i8* (%struct.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to i8* (%struct.Base*)**), i64 2)
     37 // CHECK-NEXT:  [[U2:%.*]] = call i8* [[U1]]
     38   char* c = p->Base::abc();
     39 }
     40 
     41 
     42 // Test3
     43 struct Base2 { };
     44 
     45 struct Derived2 : virtual Base2 {
     46   virtual char* efg(void) const;
     47 };
     48 
     49 char* Derived2::efg(void) const { return 0; }
     50 
     51 void FUNC2(Derived2* p) {
     52 // CHECK: [[V1:%.*]] = load i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ([5 x i8*]* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), i64 3)
     53 // CHECK-NEXT:  [[V2:%.*]] = call i8* [[V1]]
     54   char* c = p->Derived2::efg();
     55 }
     56 
     57 // Test4
     58 struct Base3 { };
     59 
     60 struct D1 : virtual Base3 {
     61 };
     62 
     63 struct D2 : virtual Base3 {
     64  virtual char *abc(void) const;
     65 };
     66 
     67 struct Sub : D1, D2 {
     68 };
     69 
     70 char* D2::abc(void) const { return 0; }
     71 
     72 void FUNC3(Sub* p) {
     73 // CHECK: [[W1:%.*]] = load i8* (%struct.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ([5 x i8*]* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3)
     74 // CHECK-NEXT:  [[W2:%.*]] = call i8* [[W1]]
     75   char* c = p->D2::abc();
     76 }
     77 
     78