visibility.cpp revision 7f1b98760d419a09b2261c1ef901f6bc1ff33e19
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: @_ZTTN6Test161AIcEE = external constant 30// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external constant 31// CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant 32 33namespace Test1 { 34 // CHECK: define hidden void @_ZN5Test11fEv 35 void HIDDEN f() { } 36 37} 38 39namespace 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 49namespace 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 61namespace 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 77namespace 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> 93namespace 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 110namespace 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 127namespace 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 140namespace 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 156namespace 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 169namespace 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. 188namespace 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. 205namespace 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. 222namespace 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 231namespace 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 244namespace 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 258namespace 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 293namespace 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 347namespace 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. 361namespace 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_1AILj2EEEE5test4Ev() 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