xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/vtable-linkage.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o %t
2*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o %t.hidden
3*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-optzns -O3 -emit-llvm -o %t.opt
4*f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=CHECK %s < %t
5*f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=CHECK-HIDDEN %s < %t.hidden
6*f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
7*f4a2713aSLionel Sambuc 
8*f4a2713aSLionel Sambuc namespace {
9*f4a2713aSLionel Sambuc   struct A {
10*f4a2713aSLionel Sambuc     virtual void f() { }
11*f4a2713aSLionel Sambuc   };
12*f4a2713aSLionel Sambuc }
13*f4a2713aSLionel Sambuc 
14*f4a2713aSLionel Sambuc void f() { A b; }
15*f4a2713aSLionel Sambuc 
16*f4a2713aSLionel Sambuc struct B {
17*f4a2713aSLionel Sambuc   B();
18*f4a2713aSLionel Sambuc   virtual void f();
19*f4a2713aSLionel Sambuc };
20*f4a2713aSLionel Sambuc 
21*f4a2713aSLionel Sambuc B::B() { }
22*f4a2713aSLionel Sambuc 
23*f4a2713aSLionel Sambuc struct C : virtual B {
24*f4a2713aSLionel Sambuc   C();
25*f4a2713aSLionel Sambuc   virtual void f() { }
26*f4a2713aSLionel Sambuc };
27*f4a2713aSLionel Sambuc 
28*f4a2713aSLionel Sambuc C::C() { }
29*f4a2713aSLionel Sambuc 
30*f4a2713aSLionel Sambuc struct D {
31*f4a2713aSLionel Sambuc   virtual void f();
32*f4a2713aSLionel Sambuc };
33*f4a2713aSLionel Sambuc 
34*f4a2713aSLionel Sambuc void D::f() { }
35*f4a2713aSLionel Sambuc 
36*f4a2713aSLionel Sambuc static struct : D { } e;
37*f4a2713aSLionel Sambuc 
38*f4a2713aSLionel Sambuc // The destructor is the key function.
39*f4a2713aSLionel Sambuc template<typename T>
40*f4a2713aSLionel Sambuc struct E {
41*f4a2713aSLionel Sambuc   virtual ~E();
42*f4a2713aSLionel Sambuc };
43*f4a2713aSLionel Sambuc 
44*f4a2713aSLionel Sambuc template<typename T> E<T>::~E() { }
45*f4a2713aSLionel Sambuc 
46*f4a2713aSLionel Sambuc // Anchor is the key function
47*f4a2713aSLionel Sambuc template<>
48*f4a2713aSLionel Sambuc struct E<char> {
49*f4a2713aSLionel Sambuc   virtual void anchor();
50*f4a2713aSLionel Sambuc };
51*f4a2713aSLionel Sambuc 
52*f4a2713aSLionel Sambuc void E<char>::anchor() { }
53*f4a2713aSLionel Sambuc 
54*f4a2713aSLionel Sambuc template struct E<short>;
55*f4a2713aSLionel Sambuc extern template struct E<int>;
56*f4a2713aSLionel Sambuc 
57*f4a2713aSLionel Sambuc void use_E() {
58*f4a2713aSLionel Sambuc   E<int> ei;
59*f4a2713aSLionel Sambuc   (void)ei;
60*f4a2713aSLionel Sambuc   E<long> el;
61*f4a2713aSLionel Sambuc   (void)el;
62*f4a2713aSLionel Sambuc }
63*f4a2713aSLionel Sambuc 
64*f4a2713aSLionel Sambuc // No key function
65*f4a2713aSLionel Sambuc template<typename T>
66*f4a2713aSLionel Sambuc struct F {
67*f4a2713aSLionel Sambuc   virtual void foo() { }
68*f4a2713aSLionel Sambuc };
69*f4a2713aSLionel Sambuc 
70*f4a2713aSLionel Sambuc // No key function
71*f4a2713aSLionel Sambuc template<>
72*f4a2713aSLionel Sambuc struct F<char> {
73*f4a2713aSLionel Sambuc   virtual void foo() { }
74*f4a2713aSLionel Sambuc };
75*f4a2713aSLionel Sambuc 
76*f4a2713aSLionel Sambuc template struct F<short>;
77*f4a2713aSLionel Sambuc extern template struct F<int>;
78*f4a2713aSLionel Sambuc 
79*f4a2713aSLionel Sambuc void use_F() {
80*f4a2713aSLionel Sambuc   F<char> fc;
81*f4a2713aSLionel Sambuc   fc.foo();
82*f4a2713aSLionel Sambuc   F<int> fi;
83*f4a2713aSLionel Sambuc   fi.foo();
84*f4a2713aSLionel Sambuc   F<long> fl;
85*f4a2713aSLionel Sambuc   (void)fl;
86*f4a2713aSLionel Sambuc }
87*f4a2713aSLionel Sambuc 
88*f4a2713aSLionel Sambuc // B has a key function that is not defined in this translation unit so its vtable
89*f4a2713aSLionel Sambuc // has external linkage.
90*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1B = external unnamed_addr constant
91*f4a2713aSLionel Sambuc 
92*f4a2713aSLionel Sambuc // C has no key function, so its vtable should have weak_odr linkage
93*f4a2713aSLionel Sambuc // and hidden visibility (rdar://problem/7523229).
94*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant
95*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1C = linkonce_odr constant
96*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1C = linkonce_odr unnamed_addr constant
97*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant
98*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTV1C = linkonce_odr hidden unnamed_addr constant
99*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTS1C = linkonce_odr constant
100*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTI1C = linkonce_odr hidden unnamed_addr constant
101*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTT1C = linkonce_odr hidden unnamed_addr constant
102*f4a2713aSLionel Sambuc 
103*f4a2713aSLionel Sambuc // D has a key function that is defined in this translation unit so its vtable is
104*f4a2713aSLionel Sambuc // defined in the translation unit.
105*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1D = unnamed_addr constant
106*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1D = constant
107*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1D = unnamed_addr constant
108*f4a2713aSLionel Sambuc 
109*f4a2713aSLionel Sambuc // E<char> is an explicit specialization with a key function defined
110*f4a2713aSLionel Sambuc // in this translation unit, so its vtable should have external
111*f4a2713aSLionel Sambuc // linkage.
112*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1EIcE = unnamed_addr constant
113*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1EIcE = constant
114*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1EIcE = unnamed_addr constant
115*f4a2713aSLionel Sambuc 
116*f4a2713aSLionel Sambuc // E<short> is an explicit template instantiation with a key function
117*f4a2713aSLionel Sambuc // defined in this translation unit, so its vtable should have
118*f4a2713aSLionel Sambuc // weak_odr linkage.
119*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant
120*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1EIsE = weak_odr constant
121*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1EIsE = weak_odr unnamed_addr constant
122*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant
123*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTS1EIsE = weak_odr constant
124*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTI1EIsE = weak_odr unnamed_addr constant
125*f4a2713aSLionel Sambuc 
126*f4a2713aSLionel Sambuc // F<short> is an explicit template instantiation without a key
127*f4a2713aSLionel Sambuc // function, so its vtable should have weak_odr linkage
128*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant
129*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1FIsE = weak_odr constant
130*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1FIsE = weak_odr unnamed_addr constant
131*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant
132*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTS1FIsE = weak_odr constant
133*f4a2713aSLionel Sambuc // CHECK-HIDDEN-DAG: @_ZTI1FIsE = weak_odr unnamed_addr constant
134*f4a2713aSLionel Sambuc 
135*f4a2713aSLionel Sambuc // E<long> is an implicit template instantiation with a key function
136*f4a2713aSLionel Sambuc // defined in this translation unit, so its vtable should have
137*f4a2713aSLionel Sambuc // linkonce_odr linkage.
138*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant
139*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant
140*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1EIlE = linkonce_odr unnamed_addr constant
141*f4a2713aSLionel Sambuc 
142*f4a2713aSLionel Sambuc // F<long> is an implicit template instantiation with no key function,
143*f4a2713aSLionel Sambuc // so its vtable should have linkonce_odr linkage.
144*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant
145*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant
146*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1FIlE = linkonce_odr unnamed_addr constant
147*f4a2713aSLionel Sambuc 
148*f4a2713aSLionel Sambuc // F<int> is an explicit template instantiation declaration without a
149*f4a2713aSLionel Sambuc // key function, so its vtable should have external linkage.
150*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1FIiE = external unnamed_addr constant
151*f4a2713aSLionel Sambuc // CHECK-OPT-DAG: @_ZTV1FIiE = external unnamed_addr constant
152*f4a2713aSLionel Sambuc 
153*f4a2713aSLionel Sambuc // E<int> is an explicit template instantiation declaration. It has a
154*f4a2713aSLionel Sambuc // key function that is not instantiated, so we should only reference
155*f4a2713aSLionel Sambuc // its vtable, not define it.
156*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1EIiE = external unnamed_addr constant
157*f4a2713aSLionel Sambuc // CHECK-OPT-DAG: @_ZTV1EIiE = external unnamed_addr constant
158*f4a2713aSLionel Sambuc 
159*f4a2713aSLionel Sambuc // The anonymous struct for e has no linkage, so the vtable should have
160*f4a2713aSLionel Sambuc // internal linkage.
161*f4a2713aSLionel Sambuc // CHECK-DAG: @"_ZTV3$_0" = internal unnamed_addr constant
162*f4a2713aSLionel Sambuc // CHECK-DAG: @"_ZTS3$_0" = internal constant
163*f4a2713aSLionel Sambuc // CHECK-DAG: @"_ZTI3$_0" = internal unnamed_addr constant
164*f4a2713aSLionel Sambuc 
165*f4a2713aSLionel Sambuc // The A vtable should have internal linkage since it is inside an anonymous
166*f4a2713aSLionel Sambuc // namespace.
167*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTVN12_GLOBAL__N_11AE = internal unnamed_addr constant
168*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTSN12_GLOBAL__N_11AE = internal constant
169*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTIN12_GLOBAL__N_11AE = internal unnamed_addr constant
170*f4a2713aSLionel Sambuc 
171*f4a2713aSLionel Sambuc // F<char> is an explicit specialization without a key function, so
172*f4a2713aSLionel Sambuc // its vtable should have linkonce_odr linkage.
173*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant
174*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant
175*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTI1FIcE = linkonce_odr unnamed_addr constant
176*f4a2713aSLionel Sambuc 
177*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant
178*f4a2713aSLionel Sambuc template <typename T>
179*f4a2713aSLionel Sambuc class G {
180*f4a2713aSLionel Sambuc public:
181*f4a2713aSLionel Sambuc   G() {}
182*f4a2713aSLionel Sambuc   virtual void f0();
183*f4a2713aSLionel Sambuc   virtual void f1();
184*f4a2713aSLionel Sambuc };
185*f4a2713aSLionel Sambuc template <>
186*f4a2713aSLionel Sambuc void G<int>::f1() {}
187*f4a2713aSLionel Sambuc template <typename T>
188*f4a2713aSLionel Sambuc void G<T>::f0() {}
189*f4a2713aSLionel Sambuc void G_f0()  { new G<int>(); }
190*f4a2713aSLionel Sambuc 
191*f4a2713aSLionel Sambuc // H<int> has a key function without a body but it's a template instantiation
192*f4a2713aSLionel Sambuc // so its VTable must be emitted.
193*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr constant
194*f4a2713aSLionel Sambuc template <typename T>
195*f4a2713aSLionel Sambuc class H {
196*f4a2713aSLionel Sambuc public:
197*f4a2713aSLionel Sambuc   virtual ~H();
198*f4a2713aSLionel Sambuc };
199*f4a2713aSLionel Sambuc 
200*f4a2713aSLionel Sambuc void use_H() {
201*f4a2713aSLionel Sambuc   H<int> h;
202*f4a2713aSLionel Sambuc }
203*f4a2713aSLionel Sambuc 
204*f4a2713aSLionel Sambuc // I<int> has an explicit instantiation declaration and needs a VTT and
205*f4a2713aSLionel Sambuc // construction vtables.
206*f4a2713aSLionel Sambuc 
207*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTV1IIiE = external unnamed_addr constant
208*f4a2713aSLionel Sambuc // CHECK-DAG: @_ZTT1IIiE = external unnamed_addr constant
209*f4a2713aSLionel Sambuc // CHECK-NOT: @_ZTC1IIiE
210*f4a2713aSLionel Sambuc //
211*f4a2713aSLionel Sambuc // CHECK-OPT-DAG: @_ZTV1IIiE = external unnamed_addr constant
212*f4a2713aSLionel Sambuc // CHECK-OPT-DAG: @_ZTT1IIiE = external unnamed_addr constant
213*f4a2713aSLionel Sambuc struct VBase1 { virtual void f(); }; struct VBase2 : virtual VBase1 {};
214*f4a2713aSLionel Sambuc template<typename T>
215*f4a2713aSLionel Sambuc struct I : VBase2 {};
216*f4a2713aSLionel Sambuc extern template struct I<int>;
217*f4a2713aSLionel Sambuc I<int> i;
218