Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
      2 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
      3 
      4 #define HIDDEN __attribute__((visibility("hidden")))
      5 #define PROTECTED __attribute__((visibility("protected")))
      6 #define DEFAULT __attribute__((visibility("default")))
      7 
      8 // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
      9 // CHECK: @_ZN5Test71aE = hidden global
     10 // CHECK: @_ZN5Test71bE = global
     11 // CHECK: @test9_var = global
     12 // CHECK-HIDDEN: @test9_var = global
     13 // CHECK: @_ZN6Test121A6hiddenE = external hidden global
     14 // CHECK: @_ZN6Test121A7visibleE = external global
     15 // CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global
     16 // CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global
     17 // CHECK: @_ZN6Test131B1aE = hidden global
     18 // CHECK: @_ZN6Test131C1aE = global
     19 // CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global
     20 // CHECK-HIDDEN: @_ZN6Test131C1aE = global
     21 // CHECK: @_ZN6Test143varE = external global
     22 // CHECK-HIDDEN: @_ZN6Test143varE = external global
     23 // CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
     24 // CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
     25 // CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
     26 // CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
     27 // CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
     28 // CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
     29 // CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
     30 // CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
     31 // CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
     32 
     33 namespace Test1 {
     34   // CHECK: define hidden void @_ZN5Test11fEv
     35   void HIDDEN f() { }
     36 
     37 }
     38 
     39 namespace Test2 {
     40   struct HIDDEN A {
     41     void f();
     42   };
     43 
     44   // A::f is a member function of a hidden class.
     45   // CHECK: define hidden void @_ZN5Test21A1fEv
     46   void A::f() { }
     47 }
     48 
     49 namespace Test3 {
     50   struct HIDDEN A {
     51     struct B {
     52       void f();
     53     };
     54   };
     55 
     56   // B is a nested class where its parent class is hidden.
     57   // CHECK: define hidden void @_ZN5Test31A1B1fEv
     58   void A::B::f() { }
     59 }
     60 
     61 namespace Test4 HIDDEN {
     62   int VariableInHiddenNamespace = 10;
     63 
     64   // Test4::g is in a hidden namespace.
     65   // CHECK: define hidden void @_ZN5Test41gEv
     66   void g() { }
     67 
     68   struct DEFAULT A {
     69     void f();
     70   };
     71 
     72   // A has default visibility.
     73   // CHECK: define void @_ZN5Test41A1fEv
     74   void A::f() { }
     75 }
     76 
     77 namespace Test5 {
     78 
     79   namespace NS HIDDEN {
     80     // f is in NS which is hidden.
     81     // CHECK: define hidden void @_ZN5Test52NS1fEv()
     82     void f() { }
     83   }
     84 
     85   namespace NS {
     86     // g is in NS, but this NS decl is not hidden.
     87     // CHECK: define void @_ZN5Test52NS1gEv
     88     void g() { }
     89   }
     90 }
     91 
     92 // <rdar://problem/8091955>
     93 namespace Test6 {
     94   struct HIDDEN foo {
     95     foo() { }
     96     void bonk();
     97     virtual void bar() = 0;
     98 
     99     virtual void zonk() {}
    100   };
    101 
    102   struct barc : public foo {
    103     barc();
    104     virtual void bar();
    105   };
    106 
    107   barc::barc() {}
    108 }
    109 
    110 namespace Test7 {
    111   class HIDDEN A {};
    112   A a; // top of file
    113 
    114   template <A&> struct Aref {
    115     static void foo() {}
    116   };
    117 
    118   class B : public A {};
    119   B b; // top of file
    120 
    121   // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
    122   void test() {
    123     Aref<a>::foo();
    124   }
    125 }
    126 
    127 namespace Test8 {
    128   void foo();
    129   void bar() {}
    130   // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
    131   // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
    132 
    133   void test() {
    134     foo();
    135     bar();
    136   }
    137 }
    138 
    139 // PR8457
    140 namespace Test9 {
    141   extern "C" {
    142     struct A { int field; };
    143     void DEFAULT test9_fun(struct A *a) { }
    144     struct A DEFAULT test9_var; // above
    145   }
    146   // CHECK: define void @test9_fun(
    147   // CHECK-HIDDEN: define void @test9_fun(
    148 
    149   void test() {
    150     A a = test9_var;
    151     test9_fun(&a);
    152   }
    153 }
    154 
    155 // PR8478
    156 namespace Test10 {
    157   struct A;
    158 
    159   DEFAULT class B {
    160     void foo(A*);
    161   };
    162 
    163   // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
    164   // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
    165   void B::foo(A*) {}
    166 }
    167 
    168 // PR8492
    169 namespace Test11 {
    170   struct A {
    171     void foo() {}
    172     void DEFAULT bar() {}
    173   };
    174 
    175   void test() {
    176     A a;
    177     a.foo();
    178     a.bar();
    179   }
    180 
    181   // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
    182   // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
    183   // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
    184   // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
    185 }
    186 
    187 // Tested at top of file.
    188 namespace Test12 {
    189   struct A {
    190     // This is hidden in all cases: the explicit attribute takes
    191     // priority over -fvisibility on the parent.
    192     static int hidden HIDDEN;
    193 
    194     // This is default in all cases because it's only a declaration.
    195     static int visible;
    196   };
    197 
    198   void test() {
    199     A::hidden = 0;
    200     A::visible = 0;
    201   }
    202 }
    203 
    204 // Tested at top of file.
    205 namespace Test13 {
    206   struct HIDDEN A {};
    207 
    208   // Should be hidden in all cases.
    209   struct B {
    210     static A a;
    211   };
    212   A B::a;
    213 
    214   // Should be default in all cases.
    215   struct DEFAULT C {
    216     static A a;
    217   };
    218   A C::a;
    219 };
    220 
    221 // Tested at top of file.
    222 namespace Test14 {
    223   // Neither the visibility of the type nor -fvisibility=hidden should
    224   // apply to declarations.
    225   extern struct A *var;
    226 
    227   struct A *test() { return var; }
    228 }
    229 
    230 // rdar://problem/8613093
    231 namespace Test15 {
    232   struct A {};
    233   template <class T> struct Temp {
    234     struct Inner {
    235       static char buffer[0];
    236     };
    237   };
    238 
    239   char *test() {
    240     return Temp<A>::Inner::buffer;
    241   }
    242 }
    243 
    244 namespace Test16 {
    245   struct Base1 { virtual void foo(); };
    246   struct Base2 : virtual Base1 { virtual void foo(); };
    247   template <class T> struct A : virtual Base1, Base2 {
    248     virtual void foo();
    249   };
    250   extern template struct A<char>;
    251 
    252   void test() {
    253     A<char> a;
    254     a.foo();
    255   }
    256 }
    257 
    258 namespace Test17 {
    259   struct HIDDEN A {
    260     static void foo();
    261     static void DEFAULT bar();
    262     static void HIDDEN baz();
    263 
    264     struct DEFAULT B {
    265       static void foo();
    266       static void DEFAULT bar();
    267       static void HIDDEN baz();
    268     };
    269   };
    270 
    271   void test() {
    272     A::foo();
    273     A::bar();
    274     A::baz();
    275     A::B::foo();
    276     A::B::bar();
    277     A::B::baz();
    278   }
    279   // CHECK: declare hidden void @_ZN6Test171A3fooEv()
    280   // CHECK: declare void @_ZN6Test171A3barEv()
    281   // CHECK: declare hidden void @_ZN6Test171A3bazEv()
    282   // CHECK: declare void @_ZN6Test171A1B3fooEv()
    283   // CHECK: declare void @_ZN6Test171A1B3barEv()
    284   // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
    285   // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
    286   // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
    287   // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
    288   // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
    289   // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
    290   // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
    291 }
    292 
    293 namespace Test18 {
    294   template <class T> struct HIDDEN A {
    295     static void foo();
    296     static void DEFAULT bar();
    297     static void HIDDEN baz();
    298 
    299     struct DEFAULT B {
    300       static void foo();
    301       static void DEFAULT bar();
    302       static void HIDDEN baz();
    303     };
    304   };
    305   struct HIDDEN H;
    306 
    307   void test() {
    308     A<int>::foo();
    309     A<int>::bar();
    310     A<int>::baz();
    311     A<int>::B::foo();
    312     A<int>::B::bar();
    313     A<int>::B::baz();
    314     A<H>::foo();
    315     A<H>::bar();
    316     A<H>::baz();
    317     A<H>::B::foo();
    318     A<H>::B::bar();
    319     A<H>::B::baz();
    320   }
    321   // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
    322   // CHECK: declare void @_ZN6Test181AIiE3barEv()
    323   // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
    324   // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
    325   // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
    326   // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
    327   // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
    328   // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
    329   // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
    330   // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
    331   // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
    332   // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
    333   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
    334   // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
    335   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
    336   // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
    337   // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
    338   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
    339   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
    340   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
    341   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
    342   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
    343   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
    344   // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
    345 }
    346 
    347 namespace Test19 {
    348   struct A { A(); ~A(); };
    349 
    350   // Tested at top of file.
    351   template <class T> void foo() {
    352     static A a;
    353   }
    354 
    355   void test() {
    356     foo<int>();
    357   }
    358 }
    359 
    360 // Various things with class template specializations.
    361 namespace Test20 {
    362   template <unsigned> struct HIDDEN A {};
    363 
    364   // An explicit specialization inherits the explicit visibility of
    365   // the template.
    366   template <> struct A<0> {
    367     static void test0();
    368     static void test1();
    369   };
    370 
    371   // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev()
    372   void A<0>::test0() {}
    373 
    374   // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
    375   void test1() {
    376     A<0>::test1();
    377   }
    378 
    379   // ...unless that's explicitly overridden.
    380   template <> struct DEFAULT A<1> {
    381     static void test2();
    382     static void test3();
    383   };
    384 
    385   // CHECK: define void @_ZN6Test201AILj1EE5test2Ev()
    386   void A<1>::test2() {}
    387 
    388   // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
    389   void test3() {
    390     A<1>::test3();
    391   }
    392 
    393   // <rdar://problem/8778497>
    394   // But we should assume that an unknown specialization has the
    395   // explicit visibility settings of the template.
    396   template <class T> struct B {
    397     static void test4() {}
    398     static void test5();
    399   };
    400 
    401   // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
    402   void test4() {
    403     B<A<2> >::test4();
    404   }
    405 
    406   // CHECK: declare void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
    407   // (but explicit visibility on a template argument doesn't count as
    408   //  explicit visibility for the template for purposes of deciding
    409   //  whether an external symbol gets visibility)
    410   void test5() {
    411     B<A<2> >::test5();
    412   }
    413 }
    414 
    415 // PR9371
    416 namespace test21 {
    417   enum En { en };
    418   template<En> struct A {
    419     __attribute__((visibility("default"))) void foo() {}
    420   };
    421 
    422   // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
    423   template void A<en>::foo();
    424 }
    425 
    426 // rdar://problem/9616154
    427 // Visibility on explicit specializations should take precedence.
    428 namespace test22 {
    429   class A1 {};
    430   class A2 {};
    431 
    432   template <class T> struct B {};
    433   template <> struct DEFAULT B<A1> {
    434     static void foo();
    435     static void bar() {}
    436   };
    437   template <> struct B<A2> {
    438     static void foo();
    439     static void bar() {}
    440   };
    441 
    442   void test() {
    443     B<A1>::foo();
    444     B<A1>::bar();
    445     B<A2>::foo();
    446     B<A2>::bar();
    447   }
    448   // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
    449   // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
    450   // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
    451   // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
    452   // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
    453   // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
    454   // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
    455   // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
    456 }
    457