brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.5 KiB · f1797cb Raw
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