1 // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -ftype-visibility default -emit-llvm -o %t
2 // RUN: FileCheck %s < %t
3 // RUN: FileCheck -check-prefix=CHECK-GLOBAL %s < %t
4 
5 // The two visibility options above are how we translate
6 // -fvisibility-ms-compat in the driver.
7 
8 // rdar://13079314
9 
10 #define HIDDEN __attribute__((visibility("hidden")))
11 #define PROTECTED __attribute__((visibility("protected")))
12 #define DEFAULT __attribute__((visibility("default")))
13 
14 namespace std {
15   class type_info;
16 };
17 
18 namespace test0 {
19   struct A {
20     static void foo();
21     static void bar();
22   };
23 
foo()24   void A::foo() { bar(); }
25   // CHECK-LABEL: define hidden void @_ZN5test01A3fooEv()
26   // CHECK: declare void @_ZN5test01A3barEv()
27 
28   const std::type_info &ti = typeid(A);
29   // CHECK-GLOBAL: @_ZTSN5test01AE = linkonce_odr constant
30   // CHECK-GLOBAL: @_ZTIN5test01AE = linkonce_odr constant
31   // CHECK-GLOBAL: @_ZN5test02tiE = hidden constant
32 }
33 
34 namespace test1 {
35   struct HIDDEN A {
36     static void foo();
37     static void bar();
38   };
39 
foo()40   void A::foo() { bar(); }
41   // CHECK-LABEL: define hidden void @_ZN5test11A3fooEv()
42   // CHECK: declare hidden void @_ZN5test11A3barEv()
43 
44   const std::type_info &ti = typeid(A);
45   // CHECK-GLOBAL: @_ZTSN5test11AE = linkonce_odr hidden constant
46   // CHECK-GLOBAL: @_ZTIN5test11AE = linkonce_odr hidden constant
47   // CHECK-GLOBAL: @_ZN5test12tiE = hidden constant
48 }
49 
50 namespace test2 {
51   struct DEFAULT A {
52     static void foo();
53     static void bar();
54   };
55 
foo()56   void A::foo() { bar(); }
57   // CHECK-LABEL: define void @_ZN5test21A3fooEv()
58   // CHECK: declare void @_ZN5test21A3barEv()
59 
60   const std::type_info &ti = typeid(A);
61   // CHECK-GLOBAL: @_ZTSN5test21AE = linkonce_odr constant
62   // CHECK-GLOBAL: @_ZTIN5test21AE = linkonce_odr constant
63   // CHECK-GLOBAL: @_ZN5test22tiE = hidden constant
64 }
65 
66 namespace test3 {
67   struct A { int x; };
68   template <class T> struct B {
footest3::B69     static void foo() { bar(); }
70     static void bar();
71   };
72 
73   template void B<A>::foo();
74   // CHECK-LABEL: define weak_odr hidden void @_ZN5test31BINS_1AEE3fooEv()
75   // CHECK: declare void @_ZN5test31BINS_1AEE3barEv()
76 
77   const std::type_info &ti = typeid(B<A>);
78   // CHECK-GLOBAL: @_ZTSN5test31BINS_1AEEE = linkonce_odr constant
79   // CHECK-GLOBAL: @_ZTIN5test31BINS_1AEEE = linkonce_odr constant
80 }
81 
82 namespace test4 {
83   struct A { int x; };
84   template <class T> struct DEFAULT B {
footest4::B85     static void foo() { bar(); }
86     static void bar();
87   };
88 
89   template void B<A>::foo();
90   // CHECK-LABEL: define weak_odr void @_ZN5test41BINS_1AEE3fooEv()
91   // CHECK: declare void @_ZN5test41BINS_1AEE3barEv()
92 
93   const std::type_info &ti = typeid(B<A>);
94   // CHECK-GLOBAL: @_ZTSN5test41BINS_1AEEE = linkonce_odr constant
95   // CHECK-GLOBAL: @_ZTIN5test41BINS_1AEEE = linkonce_odr constant
96 }
97 
98 namespace test5 {
99   struct A { int x; };
100   template <class T> struct HIDDEN B {
footest5::B101     static void foo() { bar(); }
102     static void bar();
103   };
104 
105   template void B<A>::foo();
106   // CHECK-LABEL: define weak_odr hidden void @_ZN5test51BINS_1AEE3fooEv()
107   // CHECK: declare hidden void @_ZN5test51BINS_1AEE3barEv()
108 
109   const std::type_info &ti = typeid(B<A>);
110   // CHECK-GLOBAL: @_ZTSN5test51BINS_1AEEE = linkonce_odr hidden constant
111   // CHECK-GLOBAL: @_ZTIN5test51BINS_1AEEE = linkonce_odr hidden constant
112 }
113