xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/template-instantiation.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -O1 -disable-llvm-optzns -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc // CHECK: @_ZN7PR100011xE = global
4f4a2713aSLionel Sambuc // CHECK-NOT: @_ZN7PR100014kBarE = external global i32
5f4a2713aSLionel Sambuc //
6f4a2713aSLionel Sambuc // CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
7f4a2713aSLionel Sambuc // CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
8*0a6a1f1dSLionel Sambuc // CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE
9*0a6a1f1dSLionel Sambuc // CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE
10*0a6a1f1dSLionel Sambuc // CHECK:     @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant
11f4a2713aSLionel Sambuc 
12*0a6a1f1dSLionel Sambuc // CHECK: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32]
13*0a6a1f1dSLionel Sambuc // CHECK-NOT: @_ZN7PR100011SIiE3arr2E = linkonce_odr global [3 x i32]A
14*0a6a1f1dSLionel Sambuc 
15*0a6a1f1dSLionel Sambuc // CHECK:     @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant
16f4a2713aSLionel Sambuc 
17f4a2713aSLionel Sambuc // CHECK-NOT: _ZTVN5test31SIiEE
18f4a2713aSLionel Sambuc // CHECK-NOT: _ZTSN5test31SIiEE
19f4a2713aSLionel Sambuc 
20f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiEC1Ev(%"class.test2::C"* %this) unnamed_addr
21f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_(
22f4a2713aSLionel Sambuc // CHECK-LABEL: define available_externally void @_ZN5test21CIiE6zedbarEd(
23f4a2713aSLionel Sambuc 
24f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi1EEE()
25f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi2EEE()
26f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi3EEE()
27f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi1EEE()
28f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi2EEE()
29f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi3EEE()
30f4a2713aSLionel Sambuc // CHECK: declare void @_ZN7PR106662h1ENS_1SILi1EEE()
31f4a2713aSLionel Sambuc // CHECK: declare void @_ZN7PR106662h1ENS_1SILi2EEE()
32f4a2713aSLionel Sambuc // CHECK: declare void @_ZN7PR106662h1ENS_1SILi3EEE()
33f4a2713aSLionel Sambuc // CHECK: declare void @_ZN7PR106662h2ENS_1SILi1EEE()
34f4a2713aSLionel Sambuc // CHECK: declare void @_ZN7PR106662h2ENS_1SILi2EEE()
35f4a2713aSLionel Sambuc // CHECK: declare void @_ZN7PR106662h2ENS_1SILi3EEE()
36f4a2713aSLionel Sambuc 
37f4a2713aSLionel Sambuc namespace test0 {
38f4a2713aSLionel Sambuc   struct  basic_streambuf   {
39f4a2713aSLionel Sambuc     virtual       ~basic_streambuf();
40f4a2713aSLionel Sambuc   };
41f4a2713aSLionel Sambuc   template<typename _CharT >
42f4a2713aSLionel Sambuc   struct stdio_sync_filebuf : public basic_streambuf {
43f4a2713aSLionel Sambuc     virtual void      xsgetn();
44f4a2713aSLionel Sambuc   };
45f4a2713aSLionel Sambuc 
46*0a6a1f1dSLionel Sambuc   // This specialization is not a key function, so doesn't cause the vtable to
47*0a6a1f1dSLionel Sambuc   // be instantiated unless we're instantiating a class definition anyway.
xsgetn()48*0a6a1f1dSLionel Sambuc   template<> void stdio_sync_filebuf<int[1]>::xsgetn()  {
49f4a2713aSLionel Sambuc   }
xsgetn()50*0a6a1f1dSLionel Sambuc   template<> void stdio_sync_filebuf<int[2]>::xsgetn()  {
51*0a6a1f1dSLionel Sambuc   }
xsgetn()52*0a6a1f1dSLionel Sambuc   template<> void stdio_sync_filebuf<int[3]>::xsgetn()  {
53*0a6a1f1dSLionel Sambuc   }
xsgetn()54*0a6a1f1dSLionel Sambuc   template<> void stdio_sync_filebuf<int[4]>::xsgetn()  {
55*0a6a1f1dSLionel Sambuc   }
56*0a6a1f1dSLionel Sambuc   extern template class stdio_sync_filebuf<int[2]>;
57*0a6a1f1dSLionel Sambuc 
58*0a6a1f1dSLionel Sambuc   // These two both cause vtables to be emitted.
59*0a6a1f1dSLionel Sambuc   template class stdio_sync_filebuf<int[3]>;
60*0a6a1f1dSLionel Sambuc   stdio_sync_filebuf<int[4]> implicit_instantiation;
61f4a2713aSLionel Sambuc }
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc namespace test1 {
64f4a2713aSLionel Sambuc   struct  basic_streambuf   {
65f4a2713aSLionel Sambuc     virtual       ~basic_streambuf();
66f4a2713aSLionel Sambuc   };
67f4a2713aSLionel Sambuc   template<typename _CharT >
68f4a2713aSLionel Sambuc   struct stdio_sync_filebuf : public basic_streambuf {
69f4a2713aSLionel Sambuc     virtual void      xsgetn();
70f4a2713aSLionel Sambuc   };
71f4a2713aSLionel Sambuc 
72f4a2713aSLionel Sambuc   // Just a declaration should not force the vtable to be emitted.
73f4a2713aSLionel Sambuc   template<> void stdio_sync_filebuf<wchar_t>::xsgetn();
74f4a2713aSLionel Sambuc }
75f4a2713aSLionel Sambuc 
76f4a2713aSLionel Sambuc namespace test2 {
77f4a2713aSLionel Sambuc   template<typename T1>
78f4a2713aSLionel Sambuc   class C {
79f4a2713aSLionel Sambuc   public:
80f4a2713aSLionel Sambuc     virtual ~C();
zedbar(double)81f4a2713aSLionel Sambuc     void zedbar(double) {
82f4a2713aSLionel Sambuc     }
83f4a2713aSLionel Sambuc     template<typename T2>
foobar(T2 foo)84f4a2713aSLionel Sambuc     void foobar(T2 foo) {
85f4a2713aSLionel Sambuc     }
86f4a2713aSLionel Sambuc   };
87f4a2713aSLionel Sambuc   extern template class C<int>;
g()88f4a2713aSLionel Sambuc   void g() {
89f4a2713aSLionel Sambuc     // The extern template declaration should not prevent us from producing
90f4a2713aSLionel Sambuc     // the implicit constructor (test at the top).
91f4a2713aSLionel Sambuc     C<int> a;
92f4a2713aSLionel Sambuc 
93f4a2713aSLionel Sambuc     // or foobar(test at the top).
94f4a2713aSLionel Sambuc     a.foobar(0.0);
95f4a2713aSLionel Sambuc 
96f4a2713aSLionel Sambuc     // But it should prevent zebbar
97f4a2713aSLionel Sambuc     // (test at the top).
98f4a2713aSLionel Sambuc     a.zedbar(0.0);
99f4a2713aSLionel Sambuc   }
100f4a2713aSLionel Sambuc }
101f4a2713aSLionel Sambuc 
102f4a2713aSLionel Sambuc namespace test3 {
103f4a2713aSLionel Sambuc   template<typename T>
104f4a2713aSLionel Sambuc   class basic_fstreamXX  {
foo()105f4a2713aSLionel Sambuc     virtual void foo(){}
is_open() const106f4a2713aSLionel Sambuc     virtual void is_open() const  { }
107f4a2713aSLionel Sambuc   };
108f4a2713aSLionel Sambuc 
109f4a2713aSLionel Sambuc   extern template class basic_fstreamXX<char>;
110f4a2713aSLionel Sambuc   // This template instantiation should not cause us to produce a vtable.
111f4a2713aSLionel Sambuc   // (test at the top).
112f4a2713aSLionel Sambuc   template void basic_fstreamXX<char>::is_open() const;
113f4a2713aSLionel Sambuc }
114f4a2713aSLionel Sambuc 
115f4a2713aSLionel Sambuc namespace test3 {
116f4a2713aSLionel Sambuc   template <typename T>
117f4a2713aSLionel Sambuc   struct S  {
118f4a2713aSLionel Sambuc       virtual void m();
119f4a2713aSLionel Sambuc   };
120f4a2713aSLionel Sambuc 
121f4a2713aSLionel Sambuc   template<typename T>
m()122f4a2713aSLionel Sambuc   void S<T>::m() { }
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc   // Should not cause us to produce vtable because template instantiations
125f4a2713aSLionel Sambuc   // don't have key functions.
126f4a2713aSLionel Sambuc   template void S<int>::m();
127f4a2713aSLionel Sambuc }
128f4a2713aSLionel Sambuc 
129f4a2713aSLionel Sambuc namespace test4 {
130f4a2713aSLionel Sambuc   template <class T> struct A { static void foo(); };
131f4a2713aSLionel Sambuc 
132f4a2713aSLionel Sambuc   class B {
133f4a2713aSLionel Sambuc     template <class T> friend void A<T>::foo();
134f4a2713aSLionel Sambuc     B();
135f4a2713aSLionel Sambuc   };
136f4a2713aSLionel Sambuc 
foo()137f4a2713aSLionel Sambuc   template <class T> void A<T>::foo() {
138f4a2713aSLionel Sambuc     B b;
139f4a2713aSLionel Sambuc   }
140f4a2713aSLionel Sambuc 
test()141f4a2713aSLionel Sambuc   unsigned test() {
142f4a2713aSLionel Sambuc     A<int>::foo();
143f4a2713aSLionel Sambuc   }
144f4a2713aSLionel Sambuc }
145f4a2713aSLionel Sambuc 
146f4a2713aSLionel Sambuc namespace PR8505 {
147f4a2713aSLionel Sambuc // Hits an assertion due to bogus instantiation of class B.
148f4a2713aSLionel Sambuc template <int i> class A {
149f4a2713aSLionel Sambuc   class B* g;
150f4a2713aSLionel Sambuc };
151f4a2713aSLionel Sambuc class B {
f()152f4a2713aSLionel Sambuc   void f () {}
153f4a2713aSLionel Sambuc };
154f4a2713aSLionel Sambuc // Should not instantiate class B since it is introduced in namespace scope.
155f4a2713aSLionel Sambuc // CHECK-NOT: _ZN6PR85051AILi0EE1B1fEv
156f4a2713aSLionel Sambuc template class A<0>;
157f4a2713aSLionel Sambuc }
158f4a2713aSLionel Sambuc 
159f4a2713aSLionel Sambuc // Ensure that when instantiating initializers for static data members to
160f4a2713aSLionel Sambuc // complete their type in an unevaluated context, we *do* emit initializers with
161f4a2713aSLionel Sambuc // side-effects, but *don't* emit initializers and variables which are otherwise
162f4a2713aSLionel Sambuc // unused in the program.
163f4a2713aSLionel Sambuc namespace PR10001 {
164f4a2713aSLionel Sambuc   template <typename T> struct S {
165f4a2713aSLionel Sambuc     static const int arr[];
166f4a2713aSLionel Sambuc     static const int arr2[];
167f4a2713aSLionel Sambuc     static const int x, y;
168f4a2713aSLionel Sambuc     static int f();
169f4a2713aSLionel Sambuc   };
170f4a2713aSLionel Sambuc 
171f4a2713aSLionel Sambuc   extern int foo();
172f4a2713aSLionel Sambuc   extern int kBar;
173f4a2713aSLionel Sambuc 
174f4a2713aSLionel Sambuc   template <typename T> const int S<T>::arr[] = { 1, 2, foo() }; // possible side effects
175f4a2713aSLionel Sambuc   template <typename T> const int S<T>::arr2[] = { 1, 2, kBar }; // no side effects
176f4a2713aSLionel Sambuc   template <typename T> const int S<T>::x = sizeof(arr) / sizeof(arr[0]);
177f4a2713aSLionel Sambuc   template <typename T> const int S<T>::y = sizeof(arr2) / sizeof(arr2[0]);
f()178f4a2713aSLionel Sambuc   template <typename T> int S<T>::f() { return x + y; }
179f4a2713aSLionel Sambuc 
180f4a2713aSLionel Sambuc   int x = S<int>::f();
181f4a2713aSLionel Sambuc }
182f4a2713aSLionel Sambuc 
183f4a2713aSLionel Sambuc // Ensure that definitions are emitted for all friend functions defined within
184f4a2713aSLionel Sambuc // class templates. Order of declaration is extremely important here. Different
185f4a2713aSLionel Sambuc // instantiations of the class happen at different points during the deferred
186f4a2713aSLionel Sambuc // method body parsing and afterward. Those different points of instantiation
187f4a2713aSLionel Sambuc // change the exact form the class template appears to have.
188f4a2713aSLionel Sambuc namespace PR10666 {
189f4a2713aSLionel Sambuc   template <int N> struct S {
f1PR10666::S190f4a2713aSLionel Sambuc     void f1() { S<1> s; }
g1(S s)191f4a2713aSLionel Sambuc     friend void g1(S s) {}
192f4a2713aSLionel Sambuc     friend void h1(S s);
f2PR10666::S193f4a2713aSLionel Sambuc     void f2() { S<2> s; }
g2(S s)194f4a2713aSLionel Sambuc     friend void g2(S s) {}
195f4a2713aSLionel Sambuc     friend void h2(S s);
f3PR10666::S196f4a2713aSLionel Sambuc     void f3() { S<3> s; }
197f4a2713aSLionel Sambuc   };
test(S<1> s1,S<2> s2,S<3> s3)198f4a2713aSLionel Sambuc   void test(S<1> s1, S<2> s2, S<3> s3) {
199f4a2713aSLionel Sambuc     g1(s1); g1(s2); g1(s3);
200f4a2713aSLionel Sambuc     g2(s1); g2(s2); g2(s3);
201f4a2713aSLionel Sambuc     h1(s1); h1(s2); h1(s3);
202f4a2713aSLionel Sambuc     h2(s1); h2(s2); h2(s3);
203f4a2713aSLionel Sambuc   }
204f4a2713aSLionel Sambuc }
205