18ac6b135fb51d2d115b372be0e7c32d3d073d912Rafael Espindola// RUN: %clang_cc1 %s -O1 -disable-llvm-optzns -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola
3e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth// CHECK: @_ZN7PR100011xE = global
4e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth// CHECK-NOT: @_ZN7PR100014kBarE = external global i32
5e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth//
6f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
7e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
89f959db60e8913abafe7d5f5f5a83dc6a5c8d87eRafael Espindola// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = unnamed_addr constant
9f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola
10e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth// CHECK: @_ZN7PR100011SIiE3arrE = weak_odr global [3 x i32]
11e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth// CHECK-NOT: @_ZN7PR100011SIiE3arr2E = weak_odr global [3 x i32]A
12e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth
133bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis// CHECK-NOT: _ZTVN5test31SIiEE
143bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis// CHECK-NOT: _ZTSN5test31SIiEE
153bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis
168ac6b135fb51d2d115b372be0e7c32d3d073d912Rafael Espindola// CHECK: define linkonce_odr void @_ZN5test21CIiEC1Ev(%"class.test2::C"* %this) unnamed_addr
17f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola// CHECK: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_(
18f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola// CHECK: define available_externally void @_ZN5test21CIiE6zedbarEd(
19f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola
2080f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi1EEE()
2180f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi2EEE()
2280f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi3EEE()
2380f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi1EEE()
2480f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi2EEE()
2580f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi3EEE()
2680f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: declare void @_ZN7PR106662h1ENS_1SILi1EEE()
2780f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: declare void @_ZN7PR106662h1ENS_1SILi2EEE()
2880f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: declare void @_ZN7PR106662h1ENS_1SILi3EEE()
2980f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: declare void @_ZN7PR106662h2ENS_1SILi1EEE()
3080f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: declare void @_ZN7PR106662h2ENS_1SILi2EEE()
3180f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// CHECK: declare void @_ZN7PR106662h2ENS_1SILi3EEE()
3280f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth
33f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindolanamespace test0 {
34f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  struct  basic_streambuf   {
35f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    virtual       ~basic_streambuf();
36f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  };
37f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  template<typename _CharT >
38f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  struct stdio_sync_filebuf : public basic_streambuf {
39f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    virtual void      xsgetn();
40f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  };
41f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola
42f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  // This specialization should cause the vtable to be emitted, even with
43f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  // the following extern template declaration.
44f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  template<> void stdio_sync_filebuf<wchar_t>::xsgetn()  {
45f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  }
46f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  extern template class stdio_sync_filebuf<wchar_t>;
47f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola}
48f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola
49f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindolanamespace test1 {
50f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  struct  basic_streambuf   {
51f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    virtual       ~basic_streambuf();
52f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  };
53f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  template<typename _CharT >
54f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  struct stdio_sync_filebuf : public basic_streambuf {
55f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    virtual void      xsgetn();
56f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  };
57f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola
58f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  // Just a declaration should not force the vtable to be emitted.
59f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  template<> void stdio_sync_filebuf<wchar_t>::xsgetn();
60f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola}
61f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola
62f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindolanamespace test2 {
63f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  template<typename T1>
64f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  class C {
657002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall  public:
66f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    virtual ~C();
67f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    void zedbar(double) {
68f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    }
69f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    template<typename T2>
70f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    void foobar(T2 foo) {
71f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    }
72f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  };
73f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  extern template class C<int>;
74f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  void g() {
75f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    // The extern template declaration should not prevent us from producing
76f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    // the implicit constructor (test at the top).
77f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    C<int> a;
78f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola
79f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    // or foobar(test at the top).
80f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    a.foobar(0.0);
81f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola
82f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    // But it should prevent zebbar
83f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    // (test at the top).
84f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola    a.zedbar(0.0);
85f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola  }
86f3eaf45bf3ebef039c99c1e9efb05b477b2a07aaRafael Espindola}
87e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola
88e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindolanamespace test3 {
89e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola  template<typename T>
90e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola  class basic_fstreamXX  {
91e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola    virtual void foo(){}
92e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola    virtual void is_open() const  { }
93e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola  };
94e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola
95e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola  extern template class basic_fstreamXX<char>;
96e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola  // This template instantiation should not cause us to produce a vtable.
97e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola  // (test at the top).
98e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola  template void basic_fstreamXX<char>::is_open() const;
99e0f38678f01291e68fc70ea6056260b54d529307Rafael Espindola}
1003bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis
1013bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidisnamespace test3 {
1023bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis  template <typename T>
1033bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis  struct S  {
1043bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis      virtual void m();
1053bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis  };
1063bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis
1073bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis  template<typename T>
1083bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis  void S<T>::m() { }
1093bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis
1103bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis  // Should not cause us to produce vtable because template instantiations
1113bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis  // don't have key functions.
1123bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis  template void S<int>::m();
1133bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis}
1146102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall
1156102ca1d490836096678d7d934f0b2b78f9293ecJohn McCallnamespace test4 {
1166102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  template <class T> struct A { static void foo(); };
1176102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall
1186102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  class B {
1196102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall    template <class T> friend void A<T>::foo();
1206102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall    B();
1216102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  };
1226102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall
1236102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  template <class T> void A<T>::foo() {
1246102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall    B b;
1256102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  }
1266102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall
1276102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  unsigned test() {
1286102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall    A<int>::foo();
1296102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  }
1306102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall}
131bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidis
132bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidisnamespace PR8505 {
133bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidis// Hits an assertion due to bogus instantiation of class B.
134bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidistemplate <int i> class A {
135bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidis  class B* g;
136bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidis};
137bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidisclass B {
138bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidis  void f () {}
139bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidis};
140bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidis// Should not instantiate class B since it is introduced in namespace scope.
141bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidis// CHECK-NOT: _ZN6PR85051AILi0EE1B1fEv
142bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidistemplate class A<0>;
143bb5e431bf187a9f3cabb72045694fbaea414a702Argyrios Kyrtzidis}
144e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth
145e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth// Ensure that when instantiating initializers for static data members to
146e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth// complete their type in an unevaluated context, we *do* emit initializers with
147e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth// side-effects, but *don't* emit initializers and variables which are otherwise
148e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth// unused in the program.
149e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruthnamespace PR10001 {
150e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  template <typename T> struct S {
151e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth    static const int arr[];
152e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth    static const int arr2[];
153e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth    static const int x, y;
154e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth    static int f();
155e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  };
156e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth
157e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  extern int foo();
158e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  extern int kBar;
159e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth
160e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  template <typename T> const int S<T>::arr[] = { 1, 2, foo() }; // possible side effects
161e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  template <typename T> const int S<T>::arr2[] = { 1, 2, kBar }; // no side effects
162e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  template <typename T> const int S<T>::x = sizeof(arr) / sizeof(arr[0]);
163e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  template <typename T> const int S<T>::y = sizeof(arr2) / sizeof(arr2[0]);
164e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  template <typename T> int S<T>::f() { return x + y; }
165e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth
166e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth  int x = S<int>::f();
167e4d645cbe073042d8abc1a4eb600af4ff7a8dffbChandler Carruth}
16880f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth
16980f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// Ensure that definitions are emitted for all friend functions defined within
17080f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// class templates. Order of declaration is extremely important here. Different
17180f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// instantiations of the class happen at different points during the deferred
17280f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// method body parsing and afterward. Those different points of instantiation
17380f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth// change the exact form the class template appears to have.
17480f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruthnamespace PR10666 {
17580f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth  template <int N> struct S {
17680f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    void f1() { S<1> s; }
17780f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    friend void g1(S s) {}
17880f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    friend void h1(S s);
17980f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    void f2() { S<2> s; }
18080f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    friend void g2(S s) {}
18180f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    friend void h2(S s);
18280f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    void f3() { S<3> s; }
18380f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth  };
18480f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth  void test(S<1> s1, S<2> s2, S<3> s3) {
18580f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    g1(s1); g1(s2); g1(s3);
18680f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    g2(s1); g2(s2); g2(s3);
18780f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    h1(s1); h1(s2); h1(s3);
18880f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth    h2(s1); h2(s2); h2(s3);
18980f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth  }
19080f5b16efb658dabbcf971f42ed8b789aaaa6baaChandler Carruth}
191