| // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s |
| |
| namespace Test1 { |
| |
| // Check that we emit a non-virtual thunk for C::f. |
| |
| struct A { |
| virtual void f(); |
| }; |
| |
| struct B { |
| virtual void f(); |
| }; |
| |
| struct C : A, B { |
| virtual void c(); |
| |
| virtual void f(); |
| }; |
| |
| // CHECK: define void @_ZThn8_N5Test11C1fEv( |
| void C::f() { } |
| |
| } |
| |
| namespace Test2 { |
| |
| // Check that we emit a thunk for B::f since it's overriding a virtual base. |
| |
| struct A { |
| virtual void f(); |
| }; |
| |
| struct B : virtual A { |
| virtual void b(); |
| virtual void f(); |
| }; |
| |
| // CHECK: define void @_ZTv0_n24_N5Test21B1fEv( |
| void B::f() { } |
| |
| } |
| |
| namespace Test3 { |
| |
| // Check that we emit a covariant thunk for B::f. |
| |
| struct V1 { }; |
| struct V2 : virtual V1 { }; |
| |
| struct A { |
| virtual V1 *f(); |
| }; |
| |
| struct B : A { |
| virtual void b(); |
| |
| virtual V2 *f(); |
| }; |
| |
| // CHECK: define %{{.*}}* @_ZTch0_v0_n24_N5Test31B1fEv( |
| V2 *B::f() { return 0; } |
| |
| } |
| |
| namespace Test4 { |
| |
| // Check that the thunk for 'C::f' has the same visibility as the function itself. |
| |
| struct A { |
| virtual void f(); |
| }; |
| |
| struct B { |
| virtual void f(); |
| }; |
| |
| struct __attribute__((visibility("protected"))) C : A, B { |
| virtual void c(); |
| |
| virtual void f(); |
| }; |
| |
| // CHECK: define protected void @_ZThn8_N5Test41C1fEv( |
| void C::f() { } |
| |
| } |
| |
| // This is from Test5: |
| // CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv |
| |
| // Check that the thunk gets internal linkage. |
| namespace { |
| |
| struct A { |
| virtual void f(); |
| }; |
| |
| struct B { |
| virtual void f(); |
| }; |
| |
| struct C : A, B { |
| virtual void c(); |
| |
| virtual void f(); |
| }; |
| |
| // CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv( |
| void C::f() { } |
| |
| } |
| |
| // Force C::f to be used. |
| void f() { |
| C c; |
| |
| c.f(); |
| } |
| |
| namespace Test5 { |
| |
| // Check that the thunk for 'B::f' gets the same linkage as the function itself. |
| struct A { |
| virtual void f(); |
| }; |
| |
| struct B : virtual A { |
| virtual void f() { } |
| }; |
| |
| void f(B b) { |
| b.f(); |
| } |
| } |
| |
| |