Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
      2 
      3 // The trickery with optimization in the run line is to get IR
      4 // generation to emit available_externally function bodies, but not
      5 // actually inline them (and thus remove the emitted bodies).
      6 
      7 struct X0 {
      8   void __attribute__((visibility("default"))) f1() { }
      9   void f2() { }
     10   void f3();
     11   static void f5() { }
     12   virtual void f6() { }
     13 };
     14 
     15 inline void X0::f3() { }
     16 
     17 template<typename T>
     18 struct X1 {
     19   void __attribute__((visibility("default"))) f1() { }
     20   void f2() { }
     21   void f3();
     22   void f4();
     23   static void f5() { }
     24   virtual void f6() { }
     25 };
     26 
     27 template<typename T>
     28 inline void X1<T>::f3() { }
     29 
     30 template<>
     31 inline void X1<int>::f4() { }
     32 
     33 struct __attribute__((visibility("default"))) X2 {
     34   void f2() { }
     35 };
     36 
     37 extern template struct X1<float>;
     38 
     39 void use(X0 *x0, X1<int> *x1, X2 *x2, X1<float> *x3) {
     40   // CHECK-LABEL: define linkonce_odr void @_ZN2X02f1Ev
     41   x0->f1();
     42   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f2Ev
     43   x0->f2();
     44   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f3Ev
     45   x0->f3();
     46   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f5Ev
     47   X0::f5();
     48   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f6Ev
     49   x0->X0::f6();
     50   // CHECK-LABEL: define linkonce_odr void @_ZN2X1IiE2f1Ev
     51   x1->f1();
     52   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f2Ev
     53   x1->f2();
     54   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f3Ev
     55   x1->f3();
     56   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f4Ev
     57   x1->f4();
     58   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f5Ev
     59   X1<int>::f5();
     60   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f6Ev
     61   x1->X1::f6();
     62   // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X22f2Ev
     63   x2->f2();
     64   // CHECK-LABEL: define available_externally void @_ZN2X1IfE2f2Ev
     65   x3->f2();
     66 }
     67 
     68 // rdar://problem/8614470
     69 namespace test1 {
     70   struct __attribute__((visibility("default"))) A {
     71     inline void foo();
     72     ~A();
     73   };
     74 
     75   void test() {
     76     A a;
     77     a.foo();
     78   }
     79 // CHECK: declare void @_ZN5test11A3fooEv
     80 // CHECK: declare {{.*}} @_ZN5test11AD1Ev
     81 }
     82 
     83 // PR8713
     84 namespace test2 {
     85   struct A {};
     86   template <class T> class B {};
     87   typedef B<A> arg;
     88 
     89   namespace ns __attribute__((visibility("default"))) {
     90     template <class T> inline void foo() {}
     91     extern template void foo<arg>();
     92   }
     93 
     94   void test() {
     95     ns::foo<arg>();
     96   }
     97 
     98   // CHECK-LABEL: define available_externally void @_ZN5test22ns3fooINS_1BINS_1AEEEEEvv()
     99 }
    100 
    101 namespace PR11642 {
    102   template <typename T>
    103   class Foo {
    104   public:
    105     T foo(T x) { return x; }
    106   };
    107   extern template class Foo<int>;
    108   template class Foo<int>;
    109   // CHECK-LABEL: define weak_odr i32 @_ZN7PR116423FooIiE3fooEi
    110 }
    111 
    112 // Test that clang implements the new gcc behaviour for inline functions.
    113 // GCC PR30066.
    114 namespace test3 {
    115   inline void foo(void) {
    116   }
    117   template<typename T>
    118   inline void zed() {
    119   }
    120   template void zed<float>();
    121   void bar(void) {
    122     foo();
    123     zed<int>();
    124   }
    125   // CHECK-LABEL: define weak_odr void @_ZN5test33zedIfEEvv
    126   // CHECK-LABEL: define linkonce_odr hidden void @_ZN5test33fooEv
    127   // CHECK-LABEL: define linkonce_odr hidden void @_ZN5test33zedIiEEvv
    128 }
    129 
    130 namespace test4 {
    131   extern inline __attribute__ ((__gnu_inline__))
    132   void foo() {}
    133   void bar() {
    134     foo();
    135   }
    136   // CHECK-LABEL: define available_externally void @_ZN5test43fooE
    137 }
    138 
    139 namespace test5 {
    140   // just don't crash.
    141   template <int> inline void Op();
    142   class UnaryInstruction {
    143     UnaryInstruction() {
    144       Op<0>();
    145     }
    146   };
    147   template <int Idx_nocapture> void Op() {
    148   }
    149 }
    150 
    151 namespace test6 {
    152   // just don't crash.
    153   template <typename T>
    154   void f(T x) {
    155   }
    156   struct C {
    157     static void g() {
    158       f([](){});
    159     }
    160   };
    161   void g() {
    162     C::g();
    163   }
    164 }
    165