1 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s 2 3 namespace Test1 { 4 5 // Check that we emit a non-virtual thunk for C::f. 6 7 struct A { 8 virtual void f(); 9 }; 10 11 struct B { 12 virtual void f(); 13 }; 14 15 struct C : A, B { 16 virtual void c(); 17 18 virtual void f(); 19 }; 20 21 // CHECK: define void @_ZThn8_N5Test11C1fEv( 22 void C::f() { } 23 24 } 25 26 namespace Test2 { 27 28 // Check that we emit a thunk for B::f since it's overriding a virtual base. 29 30 struct A { 31 virtual void f(); 32 }; 33 34 struct B : virtual A { 35 virtual void b(); 36 virtual void f(); 37 }; 38 39 // CHECK: define void @_ZTv0_n24_N5Test21B1fEv( 40 void B::f() { } 41 42 } 43 44 namespace Test3 { 45 46 // Check that we emit a covariant thunk for B::f. 47 48 struct V1 { }; 49 struct V2 : virtual V1 { }; 50 51 struct A { 52 virtual V1 *f(); 53 }; 54 55 struct B : A { 56 virtual void b(); 57 58 virtual V2 *f(); 59 }; 60 61 // CHECK: define %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv( 62 V2 *B::f() { return 0; } 63 64 } 65 66 namespace Test4 { 67 68 // Check that the thunk for 'C::f' has the same visibility as the function itself. 69 70 struct A { 71 virtual void f(); 72 }; 73 74 struct B { 75 virtual void f(); 76 }; 77 78 struct __attribute__((visibility("protected"))) C : A, B { 79 virtual void c(); 80 81 virtual void f(); 82 }; 83 84 // CHECK: define protected void @_ZThn8_N5Test41C1fEv( 85 void C::f() { } 86 87 } 88 89 // This is from Test5: 90 // CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv 91 92 // Check that the thunk gets internal linkage. 93 namespace { 94 95 struct A { 96 virtual void f(); 97 }; 98 99 struct B { 100 virtual void f(); 101 }; 102 103 struct C : A, B { 104 virtual void c(); 105 106 virtual void f(); 107 }; 108 109 // CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv( 110 void C::f() { } 111 112 } 113 114 // Force C::f to be used. 115 void f() { 116 C c; 117 118 c.f(); 119 } 120 121 namespace Test5 { 122 123 // Check that the thunk for 'B::f' gets the same linkage as the function itself. 124 struct A { 125 virtual void f(); 126 }; 127 128 struct B : virtual A { 129 virtual void f() { } 130 }; 131 132 void f(B b) { 133 b.f(); 134 } 135 } 136 137 138