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