visibility.cpp revision 3698748400478880d2a146ef9eaa111cd0e60522
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-HIDDEN: @_ZTTN6Test161AIcEE = external constant 26// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external constant 27// CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant 28 29namespace Test1 { 30 // CHECK: define hidden void @_ZN5Test11fEv 31 void HIDDEN f() { } 32 33} 34 35namespace Test2 { 36 struct HIDDEN A { 37 void f(); 38 }; 39 40 // A::f is a member function of a hidden class. 41 // CHECK: define hidden void @_ZN5Test21A1fEv 42 void A::f() { } 43} 44 45namespace Test3 { 46 struct HIDDEN A { 47 struct B { 48 void f(); 49 }; 50 }; 51 52 // B is a nested class where its parent class is hidden. 53 // CHECK: define hidden void @_ZN5Test31A1B1fEv 54 void A::B::f() { } 55} 56 57namespace Test4 HIDDEN { 58 int VariableInHiddenNamespace = 10; 59 60 // Test4::g is in a hidden namespace. 61 // CHECK: define hidden void @_ZN5Test41gEv 62 void g() { } 63 64 struct DEFAULT A { 65 void f(); 66 }; 67 68 // A has default visibility. 69 // CHECK: define void @_ZN5Test41A1fEv 70 void A::f() { } 71} 72 73namespace Test5 { 74 75 namespace NS HIDDEN { 76 // f is in NS which is hidden. 77 // CHECK: define hidden void @_ZN5Test52NS1fEv() 78 void f() { } 79 } 80 81 namespace NS { 82 // g is in NS, but this NS decl is not hidden. 83 // CHECK: define void @_ZN5Test52NS1gEv 84 void g() { } 85 } 86} 87 88// <rdar://problem/8091955> 89namespace Test6 { 90 struct HIDDEN foo { 91 foo() { } 92 void bonk(); 93 virtual void bar() = 0; 94 95 virtual void zonk() {} 96 }; 97 98 struct barc : public foo { 99 barc(); 100 virtual void bar(); 101 }; 102 103 barc::barc() {} 104} 105 106namespace Test7 { 107 class HIDDEN A {}; 108 A a; // top of file 109 110 template <A&> struct Aref { 111 static void foo() {} 112 }; 113 114 class B : public A {}; 115 B b; // top of file 116 117 // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv() 118 void test() { 119 Aref<a>::foo(); 120 } 121} 122 123namespace Test8 { 124 void foo(); 125 void bar() {} 126 // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv() 127 // CHECK-HIDDEN: declare void @_ZN5Test83fooEv() 128 129 void test() { 130 foo(); 131 bar(); 132 } 133} 134 135// PR8457 136namespace Test9 { 137 extern "C" { 138 struct A { int field; }; 139 void DEFAULT test9_fun(struct A *a) { } 140 struct A DEFAULT test9_var; // above 141 } 142 // CHECK: define void @test9_fun( 143 // CHECK-HIDDEN: define void @test9_fun( 144 145 void test() { 146 A a = test9_var; 147 test9_fun(&a); 148 } 149} 150 151// PR8478 152namespace Test10 { 153 struct A; 154 155 DEFAULT class B { 156 void foo(A*); 157 }; 158 159 // CHECK: define void @_ZN6Test101B3fooEPNS_1AE( 160 // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE( 161 void B::foo(A*) {} 162} 163 164// PR8492 165namespace Test11 { 166 struct A { 167 void foo() {} 168 void DEFAULT bar() {} 169 }; 170 171 void test() { 172 A a; 173 a.foo(); 174 a.bar(); 175 } 176 177 // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv( 178 // CHECK: define linkonce_odr void @_ZN6Test111A3barEv( 179 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv( 180 // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv( 181} 182 183// Tested at top of file. 184namespace Test12 { 185 struct A { 186 // This is hidden in all cases: the explicit attribute takes 187 // priority over -fvisibility on the parent. 188 static int hidden HIDDEN; 189 190 // This is default in all cases because it's only a declaration. 191 static int visible; 192 }; 193 194 void test() { 195 A::hidden = 0; 196 A::visible = 0; 197 } 198} 199 200// Tested at top of file. 201namespace Test13 { 202 struct HIDDEN A {}; 203 204 // Should be hidden in all cases. 205 struct B { 206 static A a; 207 }; 208 A B::a; 209 210 // Should be default in all cases. 211 struct DEFAULT C { 212 static A a; 213 }; 214 A C::a; 215}; 216 217// Tested at top of file. 218namespace Test14 { 219 // Neither the visibility of the type nor -fvisibility=hidden should 220 // apply to declarations. 221 extern struct A *var; 222 223 struct A *test() { return var; } 224} 225 226// rdar://problem/8613093 227namespace Test15 { 228 struct A {}; 229 template <class T> struct Temp { 230 struct Inner { 231 static char buffer[0]; 232 }; 233 }; 234 235 char *test() { 236 return Temp<A>::Inner::buffer; 237 } 238} 239 240namespace Test16 { 241 struct Base1 { virtual void foo(); }; 242 struct Base2 : virtual Base1 { virtual void foo(); }; 243 template <class T> struct A : virtual Base1, Base2 { 244 virtual void foo(); 245 }; 246 extern template struct A<char>; 247 248 void test() { 249 A<char> a; 250 a.foo(); 251 } 252} 253 254namespace Test17 { 255 struct HIDDEN A { 256 static void foo(); 257 static void DEFAULT bar(); 258 static void HIDDEN baz(); 259 260 struct DEFAULT B { 261 static void foo(); 262 static void DEFAULT bar(); 263 static void HIDDEN baz(); 264 }; 265 }; 266 267 void test() { 268 A::foo(); 269 A::bar(); 270 A::baz(); 271 A::B::foo(); 272 A::B::bar(); 273 A::B::baz(); 274 } 275 // CHECK: declare hidden void @_ZN6Test171A3fooEv() 276 // CHECK: declare void @_ZN6Test171A3barEv() 277 // CHECK: declare hidden void @_ZN6Test171A3bazEv() 278 // CHECK: declare void @_ZN6Test171A1B3fooEv() 279 // CHECK: declare void @_ZN6Test171A1B3barEv() 280 // CHECK: declare hidden void @_ZN6Test171A1B3bazEv() 281 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv() 282 // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv() 283 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv() 284 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv() 285 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv() 286 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv() 287} 288 289namespace Test18 { 290 template <class T> struct HIDDEN A { 291 static void foo(); 292 static void DEFAULT bar(); 293 static void HIDDEN baz(); 294 295 struct DEFAULT B { 296 static void foo(); 297 static void DEFAULT bar(); 298 static void HIDDEN baz(); 299 }; 300 }; 301 struct HIDDEN H; 302 303 void test() { 304 A<int>::foo(); 305 A<int>::bar(); 306 A<int>::baz(); 307 A<int>::B::foo(); 308 A<int>::B::bar(); 309 A<int>::B::baz(); 310 A<H>::foo(); 311 A<H>::bar(); 312 A<H>::baz(); 313 A<H>::B::foo(); 314 A<H>::B::bar(); 315 A<H>::B::baz(); 316 } 317 // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv() 318 // CHECK: declare void @_ZN6Test181AIiE3barEv() 319 // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv() 320 // CHECK: declare void @_ZN6Test181AIiE1B3fooEv() 321 // CHECK: declare void @_ZN6Test181AIiE1B3barEv() 322 // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv() 323 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() 324 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv() 325 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() 326 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() 327 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() 328 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() 329 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv() 330 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv() 331 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv() 332 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv() 333 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv() 334 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv() 335 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() 336 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv() 337 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() 338 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() 339 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() 340 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() 341} 342