1 // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o %t.ll
2 // RUN: FileCheck %s -check-prefix=FUNS < %t.ll
3 // RUN: FileCheck %s -check-prefix=VARS < %t.ll
4 // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o %t.ll
5 // RUN: FileCheck %s -check-prefix=FUNS-HIDDEN < %t.ll
6 // RUN: FileCheck %s -check-prefix=VARS-HIDDEN < %t.ll
7 
8 #define HIDDEN __attribute__((visibility("hidden")))
9 #define PROTECTED __attribute__((visibility("protected")))
10 #define DEFAULT __attribute__((visibility("default")))
11 #define TYPE_HIDDEN __attribute__((type_visibility("hidden")))
12 #define TYPE_PROTECTED __attribute__((type_visibility("protected")))
13 #define TYPE_DEFAULT __attribute__((type_visibility("default")))
14 
15 // type_visibility is rdar://11880378
16 
17 #if !__has_attribute(type_visibility)
18 #error No type_visibility attribute!
19 #endif
20 
21 // The template tests come first because IR-gen reorders RTTI wierdly.
22 namespace temp0 {
23   struct A;
24   template <class T> struct TYPE_DEFAULT B {
footemp0::B25     virtual void foo() {}
26   };
27 
28   template struct B<A>;
29   // FUNS-LABEL:        define weak_odr void @_ZN5temp01BINS_1AEE3fooEv(
30   // VARS:        @_ZTVN5temp01BINS_1AEEE = weak_odr unnamed_addr constant
31   // VARS:        @_ZTSN5temp01BINS_1AEEE = weak_odr constant
32   // VARS:        @_ZTIN5temp01BINS_1AEEE = weak_odr constant
33   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp01BINS_1AEE3fooEv(
34   // VARS-HIDDEN: @_ZTVN5temp01BINS_1AEEE = weak_odr hidden unnamed_addr constant
35   // VARS-HIDDEN: @_ZTSN5temp01BINS_1AEEE = weak_odr hidden constant
36   // VARS-HIDDEN: @_ZTIN5temp01BINS_1AEEE = weak_odr hidden constant
37 }
38 
39 namespace temp1 {
40   struct TYPE_DEFAULT A;
41   template <class T> struct TYPE_DEFAULT B {
footemp1::B42     virtual void foo() {}
43   };
44 
45   template struct B<A>;
46   // FUNS-LABEL:        define weak_odr void @_ZN5temp11BINS_1AEE3fooEv(
47   // VARS:        @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
48   // VARS:        @_ZTSN5temp11BINS_1AEEE = weak_odr constant
49   // VARS:        @_ZTIN5temp11BINS_1AEEE = weak_odr constant
50   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp11BINS_1AEE3fooEv(
51   // VARS-HIDDEN: @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
52   // VARS-HIDDEN: @_ZTSN5temp11BINS_1AEEE = weak_odr constant
53   // VARS-HIDDEN: @_ZTIN5temp11BINS_1AEEE = weak_odr constant
54 }
55 
56 namespace temp2 {
57   struct TYPE_DEFAULT A;
58   template <class T> struct B {
footemp2::B59     virtual void foo() {}
60   };
61 
62   template struct B<A>;
63   // FUNS-LABEL:        define weak_odr void @_ZN5temp21BINS_1AEE3fooEv(
64   // VARS:        @_ZTVN5temp21BINS_1AEEE = weak_odr unnamed_addr constant
65   // VARS:        @_ZTSN5temp21BINS_1AEEE = weak_odr constant
66   // VARS:        @_ZTIN5temp21BINS_1AEEE = weak_odr constant
67   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp21BINS_1AEE3fooEv(
68   // VARS-HIDDEN: @_ZTVN5temp21BINS_1AEEE = weak_odr hidden unnamed_addr constant
69   // VARS-HIDDEN: @_ZTSN5temp21BINS_1AEEE = weak_odr hidden constant
70   // VARS-HIDDEN: @_ZTIN5temp21BINS_1AEEE = weak_odr hidden constant
71 }
72 
73 namespace temp3 {
74   struct TYPE_HIDDEN A;
75   template <class T> struct TYPE_DEFAULT B {
footemp3::B76     virtual void foo() {}
77   };
78 
79   template struct B<A>;
80   // FUNS-LABEL:        define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
81   // VARS:        @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
82   // VARS:        @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
83   // VARS:        @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
84   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
85   // VARS-HIDDEN: @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
86   // VARS-HIDDEN: @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
87   // VARS-HIDDEN: @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
88 }
89 
90 namespace temp4 {
91   struct TYPE_DEFAULT A;
92   template <class T> struct TYPE_HIDDEN B {
footemp4::B93     virtual void foo() {}
94   };
95 
96   template struct B<A>;
97   // FUNS-LABEL:        define weak_odr void @_ZN5temp41BINS_1AEE3fooEv(
98   // VARS:        @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
99   // VARS:        @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
100   // VARS:        @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
101   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp41BINS_1AEE3fooEv(
102   // VARS-HIDDEN: @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
103   // VARS-HIDDEN: @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
104   // VARS-HIDDEN: @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
105 }
106 
107 namespace type0 {
108   struct TYPE_DEFAULT A {
109     virtual void foo();
110   };
111 
foo()112   void A::foo() {}
113   // FUNS-LABEL:        define void @_ZN5type01A3fooEv(
114   // VARS:        @_ZTVN5type01AE = unnamed_addr constant
115   // VARS:        @_ZTSN5type01AE = constant
116   // VARS:        @_ZTIN5type01AE = constant
117   // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type01A3fooEv(
118   // VARS-HIDDEN: @_ZTVN5type01AE = unnamed_addr constant
119   // VARS-HIDDEN: @_ZTSN5type01AE = constant
120   // VARS-HIDDEN: @_ZTIN5type01AE = constant
121 }
122 
123 namespace type1 {
124   struct HIDDEN TYPE_DEFAULT A {
125     virtual void foo();
126   };
127 
foo()128   void A::foo() {}
129   // FUNS-LABEL:        define hidden void @_ZN5type11A3fooEv(
130   // VARS:        @_ZTVN5type11AE = unnamed_addr constant
131   // VARS:        @_ZTSN5type11AE = constant
132   // VARS:        @_ZTIN5type11AE = constant
133   // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type11A3fooEv(
134   // VARS-HIDDEN: @_ZTVN5type11AE = unnamed_addr constant
135   // VARS-HIDDEN: @_ZTSN5type11AE = constant
136   // VARS-HIDDEN: @_ZTIN5type11AE = constant
137 }
138 
139 namespace type2 {
140   struct TYPE_HIDDEN A {
141     virtual void foo();
142   };
143 
foo()144   void A::foo() {}
145   // FUNS-LABEL:        define void @_ZN5type21A3fooEv(
146   // VARS:        @_ZTVN5type21AE = hidden unnamed_addr constant
147   // VARS:        @_ZTSN5type21AE = hidden constant
148   // VARS:        @_ZTIN5type21AE = hidden constant
149   // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type21A3fooEv(
150   // VARS-HIDDEN: @_ZTVN5type21AE = hidden unnamed_addr constant
151   // VARS-HIDDEN: @_ZTSN5type21AE = hidden constant
152   // VARS-HIDDEN: @_ZTIN5type21AE = hidden constant
153 }
154 
155 namespace type3 {
156   struct DEFAULT TYPE_HIDDEN A {
157     virtual void foo();
158   };
159 
foo()160   void A::foo() {}
161   // FUNS-LABEL:        define void @_ZN5type31A3fooEv(
162   // VARS:        @_ZTVN5type31AE = hidden unnamed_addr constant
163   // VARS:        @_ZTSN5type31AE = hidden constant
164   // VARS:        @_ZTIN5type31AE = hidden constant
165   // FUNS-HIDDEN-LABEL: define void @_ZN5type31A3fooEv(
166   // VARS-HIDDEN: @_ZTVN5type31AE = hidden unnamed_addr constant
167   // VARS-HIDDEN: @_ZTSN5type31AE = hidden constant
168   // VARS-HIDDEN: @_ZTIN5type31AE = hidden constant
169 }
170 
171