207 lines · cpp
1// RUN: %clang_cc1 %s -O1 -disable-llvm-passes -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s2// RUN: %clang_cc1 %s -O1 -disable-llvm-passes -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK23 4// Instantiation order varies on different C++ dialects (IE, between C++98 and C++11).5// CHECK-DAG: @_ZN7PR100011xE ={{.*}} global6// CHECK-DAG: @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant7// CHECK-DAG: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32]8// CHECK-DAG: @_ZTVN5test018stdio_sync_filebufIA4_iEE = linkonce_odr unnamed_addr constant9 10// Negative checks go under prefix "CHECK2" to avoid interference with CHECK and CHECK-DAG.11// CHECK2-NOT: @_ZN7PR100014kBarE = external global i3212// CHECK2-NOT: @_ZTVN5test118stdio_sync_filebufIwEE ={{.*}} constant13// CHECK2-NOT: _ZTVN5test315basic_fstreamXXIcEE14// CHECK2-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE15// CHECK2-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE16// CHECK2-NOT: @_ZN7PR100011SIiE3arr2E = linkonce_odr global [3 x i32]A17 18// CHECK2-NOT: _ZTVN5test31SIiEE19// CHECK2-NOT: _ZTSN5test31SIiEE20// CHECK2: !{!"p1 _ZTSN5test31SIiEE",21 22// CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiEC1Ev(ptr {{[^,]*}} %this) unnamed_addr23// CHECK-LABEL: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_(24// CHECK-LABEL: define available_externally void @_ZN5test21CIiE6zedbarEd(25 26// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi1EEE()27// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi2EEE()28// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi3EEE()29// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi1EEE()30// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi2EEE()31// CHECK-LABEL: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi3EEE()32// CHECK: declare void @_ZN7PR106662h1ENS_1SILi1EEE()33// CHECK: declare void @_ZN7PR106662h1ENS_1SILi2EEE()34// CHECK: declare void @_ZN7PR106662h1ENS_1SILi3EEE()35// CHECK: declare void @_ZN7PR106662h2ENS_1SILi1EEE()36// CHECK: declare void @_ZN7PR106662h2ENS_1SILi2EEE()37// CHECK: declare void @_ZN7PR106662h2ENS_1SILi3EEE()38 39namespace test0 {40 struct basic_streambuf {41 virtual ~basic_streambuf();42 };43 template<typename _CharT >44 struct stdio_sync_filebuf : public basic_streambuf {45 virtual void xsgetn();46 };47 48 // This specialization is not a key function, so doesn't cause the vtable to49 // be instantiated unless we're instantiating a class definition anyway.50 template<> void stdio_sync_filebuf<int[1]>::xsgetn() {51 }52 template<> void stdio_sync_filebuf<int[2]>::xsgetn() {53 }54 template<> void stdio_sync_filebuf<int[3]>::xsgetn() {55 }56 template<> void stdio_sync_filebuf<int[4]>::xsgetn() {57 }58 extern template class stdio_sync_filebuf<int[2]>;59 60 // These two both cause vtables to be emitted.61 template class stdio_sync_filebuf<int[3]>;62 stdio_sync_filebuf<int[4]> implicit_instantiation;63}64 65namespace test1 {66 struct basic_streambuf {67 virtual ~basic_streambuf();68 };69 template<typename _CharT >70 struct stdio_sync_filebuf : public basic_streambuf {71 virtual void xsgetn();72 };73 74 // Just a declaration should not force the vtable to be emitted.75 template<> void stdio_sync_filebuf<wchar_t>::xsgetn();76}77 78namespace test2 {79 template<typename T1>80 class C {81 public:82 virtual ~C();83 void zedbar(double) {84 }85 template<typename T2>86 void foobar(T2 foo) {87 }88 };89 extern template class C<int>;90 void g() {91 // The extern template declaration should not prevent us from producing92 // the implicit constructor (test at the top).93 C<int> a;94 95 // or foobar(test at the top).96 a.foobar(0.0);97 98 // But it should prevent zebbar99 // (test at the top).100 a.zedbar(0.0);101 }102}103 104namespace test3 {105 template<typename T>106 class basic_fstreamXX {107 virtual void foo(){}108 virtual void is_open() const { }109 };110 111 extern template class basic_fstreamXX<char>;112 // This template instantiation should not cause us to produce a vtable.113 // (test at the top).114 template void basic_fstreamXX<char>::is_open() const;115}116 117namespace test3 {118 template <typename T>119 struct S {120 virtual void m();121 };122 123 template<typename T>124 void S<T>::m() { }125 126 // Should not cause us to produce vtable because template instantiations127 // don't have key functions.128 template void S<int>::m();129}130 131namespace test4 {132 template <class T> struct A { static void foo(); };133 134 class B {135 template <class T> friend void A<T>::foo();136 B();137 };138 139 template <class T> void A<T>::foo() {140 B b;141 }142 143 void test() {144 A<int>::foo();145 }146}147 148namespace PR8505 {149// Hits an assertion due to bogus instantiation of class B.150template <int i> class A {151 class B* g;152};153class B {154 void f () {}155};156// Should not instantiate class B since it is introduced in namespace scope.157// CHECK2-NOT: _ZN6PR85051AILi0EE1B1fEv158template class A<0>;159}160 161// Ensure that when instantiating initializers for static data members to162// complete their type in an unevaluated context, we *do* emit initializers with163// side-effects, but *don't* emit initializers and variables which are otherwise164// unused in the program.165namespace PR10001 {166 template <typename T> struct S {167 static const int arr[];168 static const int arr2[];169 static const int x, y;170 static int f();171 };172 173 extern int foo();174 extern int kBar;175 176 template <typename T> const int S<T>::arr[] = { 1, 2, foo() }; // possible side effects177 template <typename T> const int S<T>::arr2[] = { 1, 2, kBar }; // no side effects178 template <typename T> const int S<T>::x = sizeof(arr) / sizeof(arr[0]);179 template <typename T> const int S<T>::y = sizeof(arr2) / sizeof(arr2[0]);180 template <typename T> int S<T>::f() { return x + y; }181 182 int x = S<int>::f();183}184 185// Ensure that definitions are emitted for all friend functions defined within186// class templates. Order of declaration is extremely important here. Different187// instantiations of the class happen at different points during the deferred188// method body parsing and afterward. Those different points of instantiation189// change the exact form the class template appears to have.190namespace PR10666 {191 template <int N> struct S {192 void f1() { S<1> s; }193 friend void g1(S s) {}194 friend void h1(S s);195 void f2() { S<2> s; }196 friend void g2(S s) {}197 friend void h2(S s);198 void f3() { S<3> s; }199 };200 void test(S<1> s1, S<2> s2, S<3> s3) {201 g1(s1); g1(s2); g1(s3);202 g2(s1); g2(s2); g2(s3);203 h1(s1); h1(s2); h1(s3);204 h2(s1); h2(s2); h2(s3);205 }206}207