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