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