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