thunks.cpp revision cb359df81b83dd4f938d05cb9cf5c34bd20068bd
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s 2 3namespace Test1 { 4 5// Check that we emit a non-virtual thunk for C::f. 6 7struct A { 8 virtual void f(); 9}; 10 11struct B { 12 virtual void f(); 13}; 14 15struct C : A, B { 16 virtual void c(); 17 18 virtual void f(); 19}; 20 21// CHECK: define void @_ZThn8_N5Test11C1fEv( 22void C::f() { } 23 24} 25 26namespace Test2 { 27 28// Check that we emit a thunk for B::f since it's overriding a virtual base. 29 30struct A { 31 virtual void f(); 32}; 33 34struct B : virtual A { 35 virtual void b(); 36 virtual void f(); 37}; 38 39// CHECK: define void @_ZTv0_n24_N5Test21B1fEv( 40void B::f() { } 41 42} 43 44namespace Test3 { 45 46// Check that we emit a covariant thunk for B::f. 47 48struct V1 { }; 49struct V2 : virtual V1 { }; 50 51struct A { 52 virtual V1 *f(); 53}; 54 55struct B : A { 56 virtual void b(); 57 58 virtual V2 *f(); 59}; 60 61// CHECK: define %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv( 62V2 *B::f() { return 0; } 63 64} 65 66namespace Test4 { 67 68// Check that the thunk for 'C::f' has the same visibility as the function itself. 69 70struct A { 71 virtual void f(); 72}; 73 74struct B { 75 virtual void f(); 76}; 77 78struct __attribute__((visibility("protected"))) C : A, B { 79 virtual void c(); 80 81 virtual void f(); 82}; 83 84// CHECK: define protected void @_ZThn8_N5Test41C1fEv( 85void C::f() { } 86 87} 88 89// Check that the thunk gets internal linkage. 90namespace { 91 92struct A { 93 virtual void f(); 94}; 95 96struct B { 97 virtual void f(); 98}; 99 100struct C : A, B { 101 virtual void c(); 102 103 virtual void f(); 104}; 105 106void C::f() { } 107 108} 109 110// Force C::f to be used. 111void f() { 112 C c; 113 114 c.f(); 115} 116 117namespace Test5 { 118 119// Check that the thunk for 'B::f' gets the same linkage as the function itself. 120struct A { 121 virtual void f(); 122}; 123 124struct B : virtual A { 125 virtual void f() { } 126}; 127 128void f(B b) { 129 b.f(); 130} 131} 132 133namespace Test6 { 134 struct X { 135 X(); 136 X(const X&); 137 X &operator=(const X&); 138 ~X(); 139 }; 140 141 struct P { 142 P(); 143 P(const P&); 144 ~P(); 145 X first; 146 X second; 147 }; 148 149 P getP(); 150 151 struct Base1 { 152 int i; 153 154 virtual X f() { return X(); } 155 }; 156 157 struct Base2 { 158 float real; 159 160 virtual X f() { return X(); } 161 }; 162 163 struct Thunks : Base1, Base2 { 164 long l; 165 166 virtual X f(); 167 }; 168 169 // CHECK: define void @_ZThn16_N5Test66Thunks1fEv 170 // CHECK-NOT: memcpy 171 // CHECK: {{call void @_ZN5Test66Thunks1fEv.*sret}} 172 // CHECK: ret void 173 X Thunks::f() { return X(); } 174} 175 176// This is from Test5: 177// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv 178// CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv( 179