1f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s 2f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN 3f4a2713aSLionel Sambuc 4f4a2713aSLionel Sambuc #define HIDDEN __attribute__((visibility("hidden"))) 5f4a2713aSLionel Sambuc #define PROTECTED __attribute__((visibility("protected"))) 6f4a2713aSLionel Sambuc #define DEFAULT __attribute__((visibility("default"))) 7f4a2713aSLionel Sambuc 8f4a2713aSLionel Sambuc namespace test30 { 9f4a2713aSLionel Sambuc // When H is hidden, it should make X hidden, even if the template argument 10f4a2713aSLionel Sambuc // is not. 11f4a2713aSLionel Sambuc struct H { 12f4a2713aSLionel Sambuc }; 13f4a2713aSLionel Sambuc template<H *T> 14f4a2713aSLionel Sambuc struct X { 15f4a2713aSLionel Sambuc }; 16f4a2713aSLionel Sambuc H DEFAULT a; 17f4a2713aSLionel Sambuc X<&a> b; 18f4a2713aSLionel Sambuc // CHECK: _ZN6test301bE = global 19f4a2713aSLionel Sambuc // CHECK-HIDDEN: _ZN6test301bE = hidden global 20f4a2713aSLionel Sambuc } 21f4a2713aSLionel Sambuc 22f4a2713aSLionel Sambuc namespace test25 { 23f4a2713aSLionel Sambuc template<typename T> 24f4a2713aSLionel Sambuc struct X { 25f4a2713aSLionel Sambuc template<typename U> 26f4a2713aSLionel Sambuc struct definition { 27f4a2713aSLionel Sambuc }; 28f4a2713aSLionel Sambuc }; 29f4a2713aSLionel Sambuc 30f4a2713aSLionel Sambuc class DEFAULT A { }; 31f4a2713aSLionel Sambuc 32f4a2713aSLionel Sambuc X<int>::definition<A> a; 33f4a2713aSLionel Sambuc // CHECK: @_ZN6test251aE = global 34f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6test251aE = hidden global 35f4a2713aSLionel Sambuc } 36f4a2713aSLionel Sambuc 37f4a2713aSLionel Sambuc namespace test28 { 38f4a2713aSLionel Sambuc class DEFAULT foo { 39f4a2713aSLionel Sambuc }; 40f4a2713aSLionel Sambuc foo myvec; 41f4a2713aSLionel Sambuc // CHECK: @_ZN6test285myvecE = global 42f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global 43f4a2713aSLionel Sambuc } 44f4a2713aSLionel Sambuc 45f4a2713aSLionel Sambuc namespace test29 { 46f4a2713aSLionel Sambuc #pragma GCC visibility push(hidden) 47f4a2713aSLionel Sambuc struct RECT { 48f4a2713aSLionel Sambuc int top; 49f4a2713aSLionel Sambuc }; 50f4a2713aSLionel Sambuc DEFAULT extern RECT data_rect; 51f4a2713aSLionel Sambuc RECT data_rect = { -1}; 52f4a2713aSLionel Sambuc #pragma GCC visibility pop 53f4a2713aSLionel Sambuc // CHECK: @_ZN6test299data_rectE = global 54f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6test299data_rectE = global 55f4a2713aSLionel Sambuc } 56f4a2713aSLionel Sambuc 57f4a2713aSLionel Sambuc namespace test40 { 58f4a2713aSLionel Sambuc template<typename T> 59f4a2713aSLionel Sambuc struct foo { 60f4a2713aSLionel Sambuc DEFAULT static int bar; 61f4a2713aSLionel Sambuc }; 62f4a2713aSLionel Sambuc template<typename T> 63f4a2713aSLionel Sambuc int foo<T>::bar; 64f4a2713aSLionel Sambuc template struct foo<int>; 65f4a2713aSLionel Sambuc // CHECK: _ZN6test403fooIiE3barE = weak_odr global 66f4a2713aSLionel Sambuc // CHECK-HIDDEN: _ZN6test403fooIiE3barE = weak_odr global 67f4a2713aSLionel Sambuc } 68f4a2713aSLionel Sambuc 69f4a2713aSLionel Sambuc namespace test41 { 70f4a2713aSLionel Sambuc // Unlike gcc we propagate the information that foo not only is hidden, but 71f4a2713aSLionel Sambuc // has been explicitly marked as so. This lets us produce a hidden undefined 72f4a2713aSLionel Sambuc // reference to bar. 73f4a2713aSLionel Sambuc struct HIDDEN foo {}; 74f4a2713aSLionel Sambuc extern foo bar; zed()75f4a2713aSLionel Sambuc foo *zed() { 76f4a2713aSLionel Sambuc return &bar; 77f4a2713aSLionel Sambuc } 78f4a2713aSLionel Sambuc // CHECK: @_ZN6test413barE = external hidden global 79f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6test413barE = external hidden global 80f4a2713aSLionel Sambuc } 81f4a2713aSLionel Sambuc 82f4a2713aSLionel Sambuc namespace test48 { 83f4a2713aSLionel Sambuc // Test that we use the visibility of struct foo when instantiating the 84f4a2713aSLionel Sambuc // template. Note that is a case where we disagree with gcc, it produces 85f4a2713aSLionel Sambuc // a default symbol. 86f4a2713aSLionel Sambuc struct HIDDEN foo { 87f4a2713aSLionel Sambuc }; 88f4a2713aSLionel Sambuc DEFAULT foo x; 89f4a2713aSLionel Sambuc 90f4a2713aSLionel Sambuc struct bar { 91f4a2713aSLionel Sambuc template<foo *z> 92f4a2713aSLionel Sambuc struct zed { 93f4a2713aSLionel Sambuc }; 94f4a2713aSLionel Sambuc }; 95f4a2713aSLionel Sambuc 96f4a2713aSLionel Sambuc bar::zed<&x> y; 97f4a2713aSLionel Sambuc // CHECK: _ZN6test481yE = hidden global 98f4a2713aSLionel Sambuc // CHECK-HIDDEN: _ZN6test481yE = hidden global 99f4a2713aSLionel Sambuc } 100f4a2713aSLionel Sambuc 101f4a2713aSLionel Sambuc // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10 102f4a2713aSLionel Sambuc // CHECK: @_ZN5Test71aE = hidden global 103f4a2713aSLionel Sambuc // CHECK: @_ZN5Test71bE = global 104f4a2713aSLionel Sambuc // CHECK: @test9_var = global 105f4a2713aSLionel Sambuc // CHECK-HIDDEN: @test9_var = global 106f4a2713aSLionel Sambuc // CHECK: @_ZN6Test121A6hiddenE = external hidden global 107f4a2713aSLionel Sambuc // CHECK: @_ZN6Test121A7visibleE = external global 108f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global 109f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global 110f4a2713aSLionel Sambuc // CHECK: @_ZN6Test131B1aE = hidden global 111f4a2713aSLionel Sambuc // CHECK: @_ZN6Test131C1aE = global 112f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global 113f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6Test131C1aE = global 114f4a2713aSLionel Sambuc // CHECK: @_ZN6Test143varE = external global 115f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6Test143varE = external global 116f4a2713aSLionel Sambuc // CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] 117f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] 118f4a2713aSLionel Sambuc 119f4a2713aSLionel Sambuc namespace test27 { 120f4a2713aSLionel Sambuc template<typename T> 121f4a2713aSLionel Sambuc class C { 122f4a2713aSLionel Sambuc class DEFAULT D { 123f4a2713aSLionel Sambuc void f(); 124f4a2713aSLionel Sambuc }; 125f4a2713aSLionel Sambuc }; 126f4a2713aSLionel Sambuc 127f4a2713aSLionel Sambuc template<> 128f4a2713aSLionel Sambuc class C<int>::D { 129f4a2713aSLionel Sambuc virtual void g(); 130f4a2713aSLionel Sambuc }; 131f4a2713aSLionel Sambuc g()132f4a2713aSLionel Sambuc void C<int>::D::g() { 133f4a2713aSLionel Sambuc } 134f4a2713aSLionel Sambuc // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant 135f4a2713aSLionel Sambuc // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant 136f4a2713aSLionel Sambuc } 137f4a2713aSLionel Sambuc 138f4a2713aSLionel Sambuc // CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global 139f4a2713aSLionel Sambuc // CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64 140f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global 141f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64 142f4a2713aSLionel Sambuc // CHECK: @_ZZN6test681fC1EvE4test = linkonce_odr global 143f4a2713aSLionel Sambuc // CHECK: @_ZGVZN6test681fC1EvE4test = linkonce_odr global 144f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZZN6test681fC1EvE4test = linkonce_odr hidden global 145f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZGVZN6test681fC1EvE4test = linkonce_odr hidden global 146f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant 147f4a2713aSLionel Sambuc // CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant 148f4a2713aSLionel Sambuc // CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant 149f4a2713aSLionel Sambuc 150f4a2713aSLionel Sambuc namespace Test1 { 151f4a2713aSLionel Sambuc // CHECK-LABEL: define hidden void @_ZN5Test11fEv f()152f4a2713aSLionel Sambuc void HIDDEN f() { } 153f4a2713aSLionel Sambuc 154f4a2713aSLionel Sambuc } 155f4a2713aSLionel Sambuc 156f4a2713aSLionel Sambuc namespace Test2 { 157f4a2713aSLionel Sambuc struct HIDDEN A { 158f4a2713aSLionel Sambuc void f(); 159f4a2713aSLionel Sambuc }; 160f4a2713aSLionel Sambuc 161f4a2713aSLionel Sambuc // A::f is a member function of a hidden class. 162f4a2713aSLionel Sambuc // CHECK-LABEL: define hidden void @_ZN5Test21A1fEv f()163f4a2713aSLionel Sambuc void A::f() { } 164f4a2713aSLionel Sambuc } 165f4a2713aSLionel Sambuc 166f4a2713aSLionel Sambuc namespace Test3 { 167f4a2713aSLionel Sambuc struct HIDDEN A { 168f4a2713aSLionel Sambuc struct B { 169f4a2713aSLionel Sambuc void f(); 170f4a2713aSLionel Sambuc }; 171f4a2713aSLionel Sambuc }; 172f4a2713aSLionel Sambuc 173f4a2713aSLionel Sambuc // B is a nested class where its parent class is hidden. 174f4a2713aSLionel Sambuc // CHECK-LABEL: define hidden void @_ZN5Test31A1B1fEv f()175f4a2713aSLionel Sambuc void A::B::f() { } 176f4a2713aSLionel Sambuc } 177f4a2713aSLionel Sambuc 178f4a2713aSLionel Sambuc namespace Test4 HIDDEN { 179f4a2713aSLionel Sambuc int VariableInHiddenNamespace = 10; 180f4a2713aSLionel Sambuc 181f4a2713aSLionel Sambuc // Test4::g is in a hidden namespace. 182f4a2713aSLionel Sambuc // CHECK-LABEL: define hidden void @_ZN5Test41gEv g()183f4a2713aSLionel Sambuc void g() { } 184f4a2713aSLionel Sambuc 185f4a2713aSLionel Sambuc struct DEFAULT A { 186f4a2713aSLionel Sambuc void f(); 187f4a2713aSLionel Sambuc }; 188f4a2713aSLionel Sambuc 189f4a2713aSLionel Sambuc // A has default visibility. 190f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN5Test41A1fEv f()191f4a2713aSLionel Sambuc void A::f() { } 192f4a2713aSLionel Sambuc } 193f4a2713aSLionel Sambuc 194f4a2713aSLionel Sambuc namespace Test5 { 195f4a2713aSLionel Sambuc 196f4a2713aSLionel Sambuc namespace NS HIDDEN { 197f4a2713aSLionel Sambuc // f is in NS which is hidden. 198f4a2713aSLionel Sambuc // CHECK-LABEL: define hidden void @_ZN5Test52NS1fEv() f()199f4a2713aSLionel Sambuc void f() { } 200f4a2713aSLionel Sambuc } 201f4a2713aSLionel Sambuc 202f4a2713aSLionel Sambuc namespace NS { 203f4a2713aSLionel Sambuc // g is in NS, but this NS decl is not hidden. 204f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN5Test52NS1gEv g()205f4a2713aSLionel Sambuc void g() { } 206f4a2713aSLionel Sambuc } 207f4a2713aSLionel Sambuc } 208f4a2713aSLionel Sambuc 209f4a2713aSLionel Sambuc // <rdar://problem/8091955> 210f4a2713aSLionel Sambuc namespace Test6 { 211f4a2713aSLionel Sambuc struct HIDDEN foo { fooTest6::foo212f4a2713aSLionel Sambuc foo() { } 213f4a2713aSLionel Sambuc void bonk(); 214f4a2713aSLionel Sambuc virtual void bar() = 0; 215f4a2713aSLionel Sambuc zonkTest6::foo216f4a2713aSLionel Sambuc virtual void zonk() {} 217f4a2713aSLionel Sambuc }; 218f4a2713aSLionel Sambuc 219f4a2713aSLionel Sambuc struct barc : public foo { 220f4a2713aSLionel Sambuc barc(); 221f4a2713aSLionel Sambuc virtual void bar(); 222f4a2713aSLionel Sambuc }; 223f4a2713aSLionel Sambuc barc()224f4a2713aSLionel Sambuc barc::barc() {} 225f4a2713aSLionel Sambuc } 226f4a2713aSLionel Sambuc 227f4a2713aSLionel Sambuc namespace Test7 { 228f4a2713aSLionel Sambuc class HIDDEN A {}; 229f4a2713aSLionel Sambuc A a; // top of file 230f4a2713aSLionel Sambuc 231f4a2713aSLionel Sambuc template <A&> struct Aref { fooTest7::Aref232f4a2713aSLionel Sambuc static void foo() {} 233f4a2713aSLionel Sambuc }; 234f4a2713aSLionel Sambuc 235f4a2713aSLionel Sambuc class B : public A {}; 236f4a2713aSLionel Sambuc B b; // top of file 237f4a2713aSLionel Sambuc 238f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv() test()239f4a2713aSLionel Sambuc void test() { 240f4a2713aSLionel Sambuc Aref<a>::foo(); 241f4a2713aSLionel Sambuc } 242f4a2713aSLionel Sambuc } 243f4a2713aSLionel Sambuc 244f4a2713aSLionel Sambuc namespace Test8 { 245f4a2713aSLionel Sambuc void foo(); bar()246f4a2713aSLionel Sambuc void bar() {} 247f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define hidden void @_ZN5Test83barEv() 248f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN5Test83fooEv() 249f4a2713aSLionel Sambuc test()250f4a2713aSLionel Sambuc void test() { 251f4a2713aSLionel Sambuc foo(); 252f4a2713aSLionel Sambuc bar(); 253f4a2713aSLionel Sambuc } 254f4a2713aSLionel Sambuc } 255f4a2713aSLionel Sambuc 256f4a2713aSLionel Sambuc // PR8457 257f4a2713aSLionel Sambuc namespace Test9 { 258f4a2713aSLionel Sambuc extern "C" { 259f4a2713aSLionel Sambuc struct A { int field; }; test9_fun(struct A * a)260f4a2713aSLionel Sambuc void DEFAULT test9_fun(struct A *a) { } 261f4a2713aSLionel Sambuc struct A DEFAULT test9_var; // above 262f4a2713aSLionel Sambuc } 263f4a2713aSLionel Sambuc // CHECK-LABEL: define void @test9_fun( 264f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define void @test9_fun( 265f4a2713aSLionel Sambuc test()266f4a2713aSLionel Sambuc void test() { 267f4a2713aSLionel Sambuc A a = test9_var; 268f4a2713aSLionel Sambuc test9_fun(&a); 269f4a2713aSLionel Sambuc } 270f4a2713aSLionel Sambuc } 271f4a2713aSLionel Sambuc 272f4a2713aSLionel Sambuc // PR8478 273f4a2713aSLionel Sambuc namespace Test10 { 274f4a2713aSLionel Sambuc struct A; 275f4a2713aSLionel Sambuc 276f4a2713aSLionel Sambuc class DEFAULT B { 277f4a2713aSLionel Sambuc void foo(A*); 278f4a2713aSLionel Sambuc }; 279f4a2713aSLionel Sambuc 280f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6Test101B3fooEPNS_1AE( 281f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define void @_ZN6Test101B3fooEPNS_1AE( foo(A *)282f4a2713aSLionel Sambuc void B::foo(A*) {} 283f4a2713aSLionel Sambuc } 284f4a2713aSLionel Sambuc 285f4a2713aSLionel Sambuc // PR8492 286f4a2713aSLionel Sambuc namespace Test11 { 287f4a2713aSLionel Sambuc struct A { fooTest11::A288f4a2713aSLionel Sambuc void foo() {} barTest11::A289f4a2713aSLionel Sambuc void DEFAULT bar() {} 290f4a2713aSLionel Sambuc }; 291f4a2713aSLionel Sambuc test()292f4a2713aSLionel Sambuc void test() { 293f4a2713aSLionel Sambuc A a; 294f4a2713aSLionel Sambuc a.foo(); 295f4a2713aSLionel Sambuc a.bar(); 296f4a2713aSLionel Sambuc } 297f4a2713aSLionel Sambuc 298f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6Test111A3fooEv( 299f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6Test111A3barEv( 300f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6Test111A3fooEv( 301f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6Test111A3barEv( 302f4a2713aSLionel Sambuc } 303f4a2713aSLionel Sambuc 304f4a2713aSLionel Sambuc // Tested at top of file. 305f4a2713aSLionel Sambuc namespace Test12 { 306f4a2713aSLionel Sambuc struct A { 307f4a2713aSLionel Sambuc // This is hidden in all cases: the explicit attribute takes 308f4a2713aSLionel Sambuc // priority over -fvisibility on the parent. 309f4a2713aSLionel Sambuc static int hidden HIDDEN; 310f4a2713aSLionel Sambuc 311f4a2713aSLionel Sambuc // This is default in all cases because it's only a declaration. 312f4a2713aSLionel Sambuc static int visible; 313f4a2713aSLionel Sambuc }; 314f4a2713aSLionel Sambuc test()315f4a2713aSLionel Sambuc void test() { 316f4a2713aSLionel Sambuc A::hidden = 0; 317f4a2713aSLionel Sambuc A::visible = 0; 318f4a2713aSLionel Sambuc } 319f4a2713aSLionel Sambuc } 320f4a2713aSLionel Sambuc 321f4a2713aSLionel Sambuc // Tested at top of file. 322f4a2713aSLionel Sambuc namespace Test13 { 323f4a2713aSLionel Sambuc struct HIDDEN A {}; 324f4a2713aSLionel Sambuc 325f4a2713aSLionel Sambuc // Should be hidden in all cases. 326f4a2713aSLionel Sambuc struct B { 327f4a2713aSLionel Sambuc static A a; 328f4a2713aSLionel Sambuc }; 329f4a2713aSLionel Sambuc A B::a; 330f4a2713aSLionel Sambuc 331f4a2713aSLionel Sambuc // Should be default in all cases. 332f4a2713aSLionel Sambuc struct DEFAULT C { 333f4a2713aSLionel Sambuc static A a; 334f4a2713aSLionel Sambuc }; 335f4a2713aSLionel Sambuc A C::a; 336f4a2713aSLionel Sambuc }; 337f4a2713aSLionel Sambuc 338f4a2713aSLionel Sambuc // Tested at top of file. 339f4a2713aSLionel Sambuc namespace Test14 { 340f4a2713aSLionel Sambuc // Neither the visibility of the type nor -fvisibility=hidden should 341f4a2713aSLionel Sambuc // apply to declarations. 342f4a2713aSLionel Sambuc extern struct A *var; 343f4a2713aSLionel Sambuc test()344f4a2713aSLionel Sambuc struct A *test() { return var; } 345f4a2713aSLionel Sambuc } 346f4a2713aSLionel Sambuc 347f4a2713aSLionel Sambuc // rdar://problem/8613093 348f4a2713aSLionel Sambuc namespace Test15 { 349f4a2713aSLionel Sambuc struct A {}; 350f4a2713aSLionel Sambuc template <class T> struct Temp { 351f4a2713aSLionel Sambuc struct Inner { 352f4a2713aSLionel Sambuc static char buffer[0]; 353f4a2713aSLionel Sambuc }; 354f4a2713aSLionel Sambuc }; 355f4a2713aSLionel Sambuc test()356f4a2713aSLionel Sambuc char *test() { 357f4a2713aSLionel Sambuc return Temp<A>::Inner::buffer; 358f4a2713aSLionel Sambuc } 359f4a2713aSLionel Sambuc } 360f4a2713aSLionel Sambuc 361f4a2713aSLionel Sambuc namespace Test16 { 362f4a2713aSLionel Sambuc struct Base1 { virtual void foo(); }; 363f4a2713aSLionel Sambuc struct Base2 : virtual Base1 { virtual void foo(); }; 364f4a2713aSLionel Sambuc template <class T> struct A : virtual Base1, Base2 { 365f4a2713aSLionel Sambuc virtual void foo(); 366f4a2713aSLionel Sambuc }; 367f4a2713aSLionel Sambuc extern template struct A<char>; 368f4a2713aSLionel Sambuc test()369f4a2713aSLionel Sambuc void test() { 370f4a2713aSLionel Sambuc A<char> a; 371f4a2713aSLionel Sambuc a.foo(); 372f4a2713aSLionel Sambuc } 373f4a2713aSLionel Sambuc } 374f4a2713aSLionel Sambuc 375f4a2713aSLionel Sambuc namespace Test17 { 376f4a2713aSLionel Sambuc struct HIDDEN A { 377f4a2713aSLionel Sambuc static void foo(); 378f4a2713aSLionel Sambuc static void DEFAULT bar(); 379f4a2713aSLionel Sambuc static void HIDDEN baz(); 380f4a2713aSLionel Sambuc 381f4a2713aSLionel Sambuc struct DEFAULT B { 382f4a2713aSLionel Sambuc static void foo(); 383f4a2713aSLionel Sambuc static void DEFAULT bar(); 384f4a2713aSLionel Sambuc static void HIDDEN baz(); 385f4a2713aSLionel Sambuc }; 386f4a2713aSLionel Sambuc }; 387f4a2713aSLionel Sambuc test()388f4a2713aSLionel Sambuc void test() { 389f4a2713aSLionel Sambuc A::foo(); 390f4a2713aSLionel Sambuc A::bar(); 391f4a2713aSLionel Sambuc A::baz(); 392f4a2713aSLionel Sambuc A::B::foo(); 393f4a2713aSLionel Sambuc A::B::bar(); 394f4a2713aSLionel Sambuc A::B::baz(); 395f4a2713aSLionel Sambuc } 396f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test171A3fooEv() 397f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6Test171A3barEv() 398f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test171A3bazEv() 399f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6Test171A1B3fooEv() 400f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6Test171A1B3barEv() 401f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test171A1B3bazEv() 402f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv() 403f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv() 404f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv() 405f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv() 406f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv() 407f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv() 408f4a2713aSLionel Sambuc } 409f4a2713aSLionel Sambuc 410f4a2713aSLionel Sambuc namespace Test18 { 411f4a2713aSLionel Sambuc template <class T> struct HIDDEN A { 412f4a2713aSLionel Sambuc static void foo(); 413f4a2713aSLionel Sambuc static void DEFAULT bar(); 414f4a2713aSLionel Sambuc static void HIDDEN baz(); 415f4a2713aSLionel Sambuc 416f4a2713aSLionel Sambuc struct DEFAULT B { 417f4a2713aSLionel Sambuc static void foo(); 418f4a2713aSLionel Sambuc static void DEFAULT bar(); 419f4a2713aSLionel Sambuc static void HIDDEN baz(); 420f4a2713aSLionel Sambuc }; 421f4a2713aSLionel Sambuc }; 422f4a2713aSLionel Sambuc struct HIDDEN H; 423f4a2713aSLionel Sambuc test()424f4a2713aSLionel Sambuc void test() { 425f4a2713aSLionel Sambuc A<int>::foo(); 426f4a2713aSLionel Sambuc A<int>::bar(); 427f4a2713aSLionel Sambuc A<int>::baz(); 428f4a2713aSLionel Sambuc A<int>::B::foo(); 429f4a2713aSLionel Sambuc A<int>::B::bar(); 430f4a2713aSLionel Sambuc A<int>::B::baz(); 431f4a2713aSLionel Sambuc A<H>::foo(); 432f4a2713aSLionel Sambuc A<H>::bar(); 433f4a2713aSLionel Sambuc A<H>::baz(); 434f4a2713aSLionel Sambuc A<H>::B::foo(); 435f4a2713aSLionel Sambuc A<H>::B::bar(); 436f4a2713aSLionel Sambuc A<H>::B::baz(); 437f4a2713aSLionel Sambuc } 438f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv() 439f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6Test181AIiE3barEv() 440f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv() 441f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6Test181AIiE1B3fooEv() 442f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6Test181AIiE1B3barEv() 443f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv() 444f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() 445f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv() 446f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() 447f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() 448f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() 449f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() 450f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv() 451f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv() 452f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv() 453f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv() 454f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv() 455f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv() 456f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() 457f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv() 458f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() 459f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() 460f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() 461f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() 462f4a2713aSLionel Sambuc } 463f4a2713aSLionel Sambuc 464f4a2713aSLionel Sambuc namespace Test19 { 465f4a2713aSLionel Sambuc struct A { A(); ~A(); }; 466f4a2713aSLionel Sambuc 467f4a2713aSLionel Sambuc // Tested at top of file. foo()468f4a2713aSLionel Sambuc template <class T> void foo() { 469f4a2713aSLionel Sambuc static A a; 470f4a2713aSLionel Sambuc } 471f4a2713aSLionel Sambuc test()472f4a2713aSLionel Sambuc void test() { 473f4a2713aSLionel Sambuc foo<int>(); 474f4a2713aSLionel Sambuc } 475f4a2713aSLionel Sambuc } 476f4a2713aSLionel Sambuc 477f4a2713aSLionel Sambuc // Various things with class template specializations. 478f4a2713aSLionel Sambuc namespace Test20 { 479f4a2713aSLionel Sambuc template <unsigned> struct HIDDEN A {}; 480f4a2713aSLionel Sambuc 481f4a2713aSLionel Sambuc // An explicit specialization inherits the explicit visibility of 482f4a2713aSLionel Sambuc // the template. 483f4a2713aSLionel Sambuc template <> struct A<0> { 484f4a2713aSLionel Sambuc static void test0(); 485f4a2713aSLionel Sambuc static void test1(); 486f4a2713aSLionel Sambuc }; 487f4a2713aSLionel Sambuc 488f4a2713aSLionel Sambuc // CHECK-LABEL: define hidden void @_ZN6Test201AILj0EE5test0Ev() test0()489f4a2713aSLionel Sambuc void A<0>::test0() {} 490f4a2713aSLionel Sambuc 491f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev() test1()492f4a2713aSLionel Sambuc void test1() { 493f4a2713aSLionel Sambuc A<0>::test1(); 494f4a2713aSLionel Sambuc } 495f4a2713aSLionel Sambuc 496f4a2713aSLionel Sambuc // ...unless that's explicitly overridden. 497f4a2713aSLionel Sambuc template <> struct DEFAULT A<1> { 498f4a2713aSLionel Sambuc static void test2(); 499f4a2713aSLionel Sambuc static void test3(); 500f4a2713aSLionel Sambuc }; 501f4a2713aSLionel Sambuc 502f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6Test201AILj1EE5test2Ev() test2()503f4a2713aSLionel Sambuc void A<1>::test2() {} 504f4a2713aSLionel Sambuc 505f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev() test3()506f4a2713aSLionel Sambuc void test3() { 507f4a2713aSLionel Sambuc A<1>::test3(); 508f4a2713aSLionel Sambuc } 509f4a2713aSLionel Sambuc 510f4a2713aSLionel Sambuc // <rdar://problem/8778497> 511f4a2713aSLionel Sambuc // But we should assume that an unknown specialization has the 512f4a2713aSLionel Sambuc // explicit visibility settings of the template. 513f4a2713aSLionel Sambuc template <class T> struct B { test4Test20::B514f4a2713aSLionel Sambuc static void test4() {} 515f4a2713aSLionel Sambuc static void test5(); 516f4a2713aSLionel Sambuc }; 517f4a2713aSLionel Sambuc 518f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev() test4()519f4a2713aSLionel Sambuc void test4() { 520f4a2713aSLionel Sambuc B<A<2> >::test4(); 521f4a2713aSLionel Sambuc } 522f4a2713aSLionel Sambuc 523f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev() test5()524f4a2713aSLionel Sambuc void test5() { 525f4a2713aSLionel Sambuc B<A<2> >::test5(); 526f4a2713aSLionel Sambuc } 527f4a2713aSLionel Sambuc } 528f4a2713aSLionel Sambuc 529f4a2713aSLionel Sambuc // PR9371 530f4a2713aSLionel Sambuc namespace test21 { 531f4a2713aSLionel Sambuc enum En { en }; 532f4a2713aSLionel Sambuc template<En> struct A { footest21::A533f4a2713aSLionel Sambuc DEFAULT void foo() {} 534f4a2713aSLionel Sambuc }; 535f4a2713aSLionel Sambuc 536f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv( 537f4a2713aSLionel Sambuc template void A<en>::foo(); 538f4a2713aSLionel Sambuc } 539f4a2713aSLionel Sambuc 540f4a2713aSLionel Sambuc // rdar://problem/9616154 541f4a2713aSLionel Sambuc // Visibility on explicit specializations should take precedence. 542f4a2713aSLionel Sambuc namespace test22 { 543f4a2713aSLionel Sambuc class A1 {}; 544f4a2713aSLionel Sambuc class A2 {}; 545f4a2713aSLionel Sambuc 546f4a2713aSLionel Sambuc template <class T> struct B {}; 547f4a2713aSLionel Sambuc template <> struct DEFAULT B<A1> { 548f4a2713aSLionel Sambuc static void foo(); bartest22::B549f4a2713aSLionel Sambuc static void bar() {} 550f4a2713aSLionel Sambuc }; 551f4a2713aSLionel Sambuc template <> struct B<A2> { 552f4a2713aSLionel Sambuc static void foo(); bartest22::B553f4a2713aSLionel Sambuc static void bar() {} 554f4a2713aSLionel Sambuc }; 555f4a2713aSLionel Sambuc test()556f4a2713aSLionel Sambuc void test() { 557f4a2713aSLionel Sambuc B<A1>::foo(); 558f4a2713aSLionel Sambuc B<A1>::bar(); 559f4a2713aSLionel Sambuc B<A2>::foo(); 560f4a2713aSLionel Sambuc B<A2>::bar(); 561f4a2713aSLionel Sambuc } 562f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv() 563f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() 564f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv() 565f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv() 566f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv() 567f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() 568f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv() 569f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv() 570f4a2713aSLionel Sambuc } 571f4a2713aSLionel Sambuc 572f4a2713aSLionel Sambuc namespace PR10113 { 573f4a2713aSLionel Sambuc namespace foo DEFAULT { 574f4a2713aSLionel Sambuc template<typename T> 575f4a2713aSLionel Sambuc class bar { zed()576f4a2713aSLionel Sambuc void zed() {} 577f4a2713aSLionel Sambuc }; 578f4a2713aSLionel Sambuc } 579f4a2713aSLionel Sambuc template class foo::bar<char>; 580f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv 581f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv 582f4a2713aSLionel Sambuc 583f4a2713aSLionel Sambuc struct zed { 584f4a2713aSLionel Sambuc }; 585f4a2713aSLionel Sambuc template class foo::bar<zed>; 586f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv 587f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv 588f4a2713aSLionel Sambuc } 589f4a2713aSLionel Sambuc 590f4a2713aSLionel Sambuc namespace PR11690 { 591f4a2713aSLionel Sambuc template<class T> struct Class { sizePR11690::Class592f4a2713aSLionel Sambuc void size() const { 593f4a2713aSLionel Sambuc } 594f4a2713aSLionel Sambuc }; 595f4a2713aSLionel Sambuc template class DEFAULT Class<char>; 596f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv 597f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv 598f4a2713aSLionel Sambuc Method()599f4a2713aSLionel Sambuc template<class T> void Method() {} 600f4a2713aSLionel Sambuc template DEFAULT void Method<char>(); 601f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv 602f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv 603f4a2713aSLionel Sambuc } 604f4a2713aSLionel Sambuc 605f4a2713aSLionel Sambuc namespace PR11690_2 { 606f4a2713aSLionel Sambuc namespace foo DEFAULT { 607f4a2713aSLionel Sambuc class bar; 608f4a2713aSLionel Sambuc template<typename T1, typename T2 = bar> 609f4a2713aSLionel Sambuc class zed { bar()610f4a2713aSLionel Sambuc void bar() { 611f4a2713aSLionel Sambuc } 612f4a2713aSLionel Sambuc }; 613f4a2713aSLionel Sambuc } 614f4a2713aSLionel Sambuc struct baz { 615f4a2713aSLionel Sambuc }; 616f4a2713aSLionel Sambuc template class foo::zed<baz>; 617f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv 618f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv 619f4a2713aSLionel Sambuc } 620f4a2713aSLionel Sambuc 621f4a2713aSLionel Sambuc namespace test23 { 622f4a2713aSLionel Sambuc // Having a template argument that is explicitly visible should not make 623f4a2713aSLionel Sambuc // the template instantiation visible. 624f4a2713aSLionel Sambuc template <typename T> 625f4a2713aSLionel Sambuc struct X { ftest23::X626f4a2713aSLionel Sambuc static void f() { 627f4a2713aSLionel Sambuc } 628f4a2713aSLionel Sambuc }; 629f4a2713aSLionel Sambuc 630f4a2713aSLionel Sambuc class DEFAULT A; 631f4a2713aSLionel Sambuc g()632f4a2713aSLionel Sambuc void g() { 633f4a2713aSLionel Sambuc X<A> y; 634f4a2713aSLionel Sambuc y.f(); 635f4a2713aSLionel Sambuc } 636f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv 637f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv 638f4a2713aSLionel Sambuc } 639f4a2713aSLionel Sambuc 640f4a2713aSLionel Sambuc namespace PR12001 { 641f4a2713aSLionel Sambuc template <typename P1> Bind(const P1 & p1)642f4a2713aSLionel Sambuc void Bind(const P1& p1) { 643f4a2713aSLionel Sambuc } 644f4a2713aSLionel Sambuc 645f4a2713aSLionel Sambuc class DEFAULT Version { }; 646f4a2713aSLionel Sambuc f()647f4a2713aSLionel Sambuc void f() { 648f4a2713aSLionel Sambuc Bind(Version()); 649f4a2713aSLionel Sambuc } 650f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_ 651f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_ 652f4a2713aSLionel Sambuc } 653f4a2713aSLionel Sambuc 654f4a2713aSLionel Sambuc namespace test24 { 655f4a2713aSLionel Sambuc class DEFAULT A { }; 656f4a2713aSLionel Sambuc 657f4a2713aSLionel Sambuc struct S { 658f4a2713aSLionel Sambuc template <typename T> memtest24::S659f4a2713aSLionel Sambuc void mem() {} 660f4a2713aSLionel Sambuc }; 661f4a2713aSLionel Sambuc test()662f4a2713aSLionel Sambuc void test() { 663f4a2713aSLionel Sambuc S s; 664f4a2713aSLionel Sambuc s.mem<A>(); 665f4a2713aSLionel Sambuc } 666f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv 667f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv 668f4a2713aSLionel Sambuc } 669f4a2713aSLionel Sambuc 670f4a2713aSLionel Sambuc namespace test26 { 671f4a2713aSLionel Sambuc template<typename T> 672f4a2713aSLionel Sambuc class C { 673f4a2713aSLionel Sambuc DEFAULT void f(); 674f4a2713aSLionel Sambuc }; 675f4a2713aSLionel Sambuc 676f4a2713aSLionel Sambuc template<> f()677f4a2713aSLionel Sambuc void C<int>::f() { } 678f4a2713aSLionel Sambuc 679f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test261CIiE1fEv 680f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define void @_ZN6test261CIiE1fEv 681f4a2713aSLionel Sambuc } 682f4a2713aSLionel Sambuc 683f4a2713aSLionel Sambuc namespace test31 { 684f4a2713aSLionel Sambuc struct A { 685f4a2713aSLionel Sambuc struct HIDDEN B { 686f4a2713aSLionel Sambuc static void DEFAULT baz(); 687f4a2713aSLionel Sambuc }; 688f4a2713aSLionel Sambuc }; f()689f4a2713aSLionel Sambuc void f() { 690f4a2713aSLionel Sambuc A::B::baz(); 691f4a2713aSLionel Sambuc } 692f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6test311A1B3bazEv() 693f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv() 694f4a2713aSLionel Sambuc } 695f4a2713aSLionel Sambuc 696f4a2713aSLionel Sambuc namespace test32 { 697f4a2713aSLionel Sambuc struct HIDDEN A { 698f4a2713aSLionel Sambuc struct DEFAULT B { 699f4a2713aSLionel Sambuc void DEFAULT baz(); 700f4a2713aSLionel Sambuc }; 701f4a2713aSLionel Sambuc }; baz()702f4a2713aSLionel Sambuc void A::B::baz() { 703f4a2713aSLionel Sambuc } 704f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test321A1B3bazEv 705f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define void @_ZN6test321A1B3bazEv 706f4a2713aSLionel Sambuc } 707f4a2713aSLionel Sambuc 708f4a2713aSLionel Sambuc namespace test33 { 709f4a2713aSLionel Sambuc template<typename T> 710f4a2713aSLionel Sambuc class foo { bar()711f4a2713aSLionel Sambuc void bar() {} 712f4a2713aSLionel Sambuc }; 713f4a2713aSLionel Sambuc struct HIDDEN zed { 714f4a2713aSLionel Sambuc }; 715f4a2713aSLionel Sambuc template class DEFAULT foo<zed>; 716f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv 717f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv 718f4a2713aSLionel Sambuc } 719f4a2713aSLionel Sambuc 720f4a2713aSLionel Sambuc namespace test34 { 721f4a2713aSLionel Sambuc struct foo { 722f4a2713aSLionel Sambuc }; 723f4a2713aSLionel Sambuc template<class T> bar()724f4a2713aSLionel Sambuc void bar() {} 725f4a2713aSLionel Sambuc template DEFAULT void bar<foo>(); 726f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv 727f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv 728f4a2713aSLionel Sambuc } 729f4a2713aSLionel Sambuc 730f4a2713aSLionel Sambuc namespace test35 { 731f4a2713aSLionel Sambuc // This is a really ugly testcase. GCC propagates the DEFAULT in zed's 732f4a2713aSLionel Sambuc // definition. It's not really clear what we can do here, because we 733f4a2713aSLionel Sambuc // produce the symbols before even seeing the DEFAULT definition of zed. 734f4a2713aSLionel Sambuc // FIXME: Maybe the best thing to do here is error? It's certainly hard 735f4a2713aSLionel Sambuc // to argue that this ought to be valid. 736f4a2713aSLionel Sambuc template<typename T> 737f4a2713aSLionel Sambuc struct DEFAULT foo { bartest35::foo738f4a2713aSLionel Sambuc void bar() {} 739f4a2713aSLionel Sambuc }; 740f4a2713aSLionel Sambuc class zed; 741f4a2713aSLionel Sambuc template class foo<zed>; 742f4a2713aSLionel Sambuc class DEFAULT zed { 743f4a2713aSLionel Sambuc }; 744f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv 745f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test353fooINS_3zedEE3barEv 746f4a2713aSLionel Sambuc } 747f4a2713aSLionel Sambuc 748f4a2713aSLionel Sambuc namespace test36 { 749f4a2713aSLionel Sambuc template<typename T1, typename T2> 750f4a2713aSLionel Sambuc class foo { bar()751f4a2713aSLionel Sambuc void bar() {} 752f4a2713aSLionel Sambuc }; 753f4a2713aSLionel Sambuc class DEFAULT S1 {}; 754f4a2713aSLionel Sambuc struct HIDDEN S2 {}; 755f4a2713aSLionel Sambuc template class foo<S1, S2>; 756f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv 757f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv 758f4a2713aSLionel Sambuc } 759f4a2713aSLionel Sambuc 760f4a2713aSLionel Sambuc namespace test37 { 761f4a2713aSLionel Sambuc struct HIDDEN foo { 762f4a2713aSLionel Sambuc }; 763f4a2713aSLionel Sambuc template<class T> bar()764f4a2713aSLionel Sambuc DEFAULT void bar() {} 765f4a2713aSLionel Sambuc template DEFAULT void bar<foo>(); 766f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv 767f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv 768f4a2713aSLionel Sambuc } 769f4a2713aSLionel Sambuc 770f4a2713aSLionel Sambuc namespace test38 { 771f4a2713aSLionel Sambuc template<typename T> 772f4a2713aSLionel Sambuc class DEFAULT foo { bar()773f4a2713aSLionel Sambuc void bar() {} 774f4a2713aSLionel Sambuc }; 775f4a2713aSLionel Sambuc struct HIDDEN zed { 776f4a2713aSLionel Sambuc }; 777f4a2713aSLionel Sambuc template class foo<zed>; 778f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv 779f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv 780f4a2713aSLionel Sambuc } 781f4a2713aSLionel Sambuc 782f4a2713aSLionel Sambuc namespace test39 { 783f4a2713aSLionel Sambuc class DEFAULT default_t; 784f4a2713aSLionel Sambuc class HIDDEN hidden_t; 785f4a2713aSLionel Sambuc template <class T> class A { 786f4a2713aSLionel Sambuc template <class U> class B { hidden()787f4a2713aSLionel Sambuc HIDDEN void hidden() {} noattr()788f4a2713aSLionel Sambuc void noattr() {} temp()789f4a2713aSLionel Sambuc template <class V> void temp() {} 790f4a2713aSLionel Sambuc }; 791f4a2713aSLionel Sambuc }; 792f4a2713aSLionel Sambuc template class DEFAULT A<hidden_t>; 793f4a2713aSLionel Sambuc template class DEFAULT A<hidden_t>::B<hidden_t>; 794f4a2713aSLionel Sambuc template void A<hidden_t>::B<hidden_t>::temp<default_t>(); 795f4a2713aSLionel Sambuc template void A<hidden_t>::B<hidden_t>::temp<hidden_t>(); 796f4a2713aSLionel Sambuc 797f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv 798f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv 799f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv 800f4a2713aSLionel Sambuc 801f4a2713aSLionel Sambuc // GCC produces a default for this one. Why? 802f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv 803f4a2713aSLionel Sambuc 804f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv 805f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv 806f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv 807f4a2713aSLionel Sambuc 808f4a2713aSLionel Sambuc // GCC produces a default for this one. Why? 809f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv 810f4a2713aSLionel Sambuc } 811f4a2713aSLionel Sambuc 812f4a2713aSLionel Sambuc namespace test42 { 813f4a2713aSLionel Sambuc struct HIDDEN foo { 814f4a2713aSLionel Sambuc }; 815f4a2713aSLionel Sambuc template <class P> 816f4a2713aSLionel Sambuc struct bar { 817f4a2713aSLionel Sambuc }; 818f4a2713aSLionel Sambuc template <> 819f4a2713aSLionel Sambuc struct HIDDEN bar<foo> { 820f4a2713aSLionel Sambuc DEFAULT static void zed(); 821f4a2713aSLionel Sambuc }; zed()822f4a2713aSLionel Sambuc void bar<foo>::zed() { 823f4a2713aSLionel Sambuc } 824f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv 825f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv 826f4a2713aSLionel Sambuc } 827f4a2713aSLionel Sambuc 828f4a2713aSLionel Sambuc namespace test43 { 829f4a2713aSLionel Sambuc struct HIDDEN foo { 830f4a2713aSLionel Sambuc }; 831f4a2713aSLionel Sambuc template <class P> bar()832f4a2713aSLionel Sambuc void bar() { 833f4a2713aSLionel Sambuc } 834f4a2713aSLionel Sambuc template <> bar()835f4a2713aSLionel Sambuc DEFAULT void bar<foo>() { 836f4a2713aSLionel Sambuc } 837f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test433barINS_3fooEEEvv 838f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define void @_ZN6test433barINS_3fooEEEvv 839f4a2713aSLionel Sambuc } 840f4a2713aSLionel Sambuc 841f4a2713aSLionel Sambuc namespace test44 { 842f4a2713aSLionel Sambuc template <typename T> 843f4a2713aSLionel Sambuc struct foo { footest44::foo844f4a2713aSLionel Sambuc foo() {} 845f4a2713aSLionel Sambuc }; 846f4a2713aSLionel Sambuc namespace { 847f4a2713aSLionel Sambuc struct bar; 848f4a2713aSLionel Sambuc } 849f4a2713aSLionel Sambuc template struct DEFAULT foo<bar>; 850f4a2713aSLionel Sambuc foo<bar> x; 851f4a2713aSLionel Sambuc // CHECK-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev 852f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev 853f4a2713aSLionel Sambuc } 854f4a2713aSLionel Sambuc 855f4a2713aSLionel Sambuc namespace test45 { 856f4a2713aSLionel Sambuc template <typename T> 857f4a2713aSLionel Sambuc struct foo { 858f4a2713aSLionel Sambuc template <typename T2> 859f4a2713aSLionel Sambuc struct bar { bartest45::foo::bar860f4a2713aSLionel Sambuc bar() {}; 861f4a2713aSLionel Sambuc }; 862f4a2713aSLionel Sambuc }; 863f4a2713aSLionel Sambuc namespace { 864f4a2713aSLionel Sambuc struct zed; 865f4a2713aSLionel Sambuc } 866f4a2713aSLionel Sambuc template struct DEFAULT foo<int>::bar<zed>; 867f4a2713aSLionel Sambuc foo<int>::bar<zed> x; 868f4a2713aSLionel Sambuc // CHECK-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev 869f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev 870f4a2713aSLionel Sambuc } 871f4a2713aSLionel Sambuc 872f4a2713aSLionel Sambuc namespace test46 { 873f4a2713aSLionel Sambuc template <typename T> foo()874f4a2713aSLionel Sambuc void foo() { 875f4a2713aSLionel Sambuc } 876f4a2713aSLionel Sambuc namespace { 877f4a2713aSLionel Sambuc struct bar; 878f4a2713aSLionel Sambuc } 879f4a2713aSLionel Sambuc template DEFAULT void foo<bar>(); zed()880f4a2713aSLionel Sambuc void zed() { 881f4a2713aSLionel Sambuc foo<bar>(); 882f4a2713aSLionel Sambuc } 883f4a2713aSLionel Sambuc // CHECK-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv 884f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv 885f4a2713aSLionel Sambuc } 886f4a2713aSLionel Sambuc 887f4a2713aSLionel Sambuc namespace test47 { 888f4a2713aSLionel Sambuc struct foo { 889f4a2713aSLionel Sambuc template <typename T> bartest47::foo890f4a2713aSLionel Sambuc static void bar() { 891f4a2713aSLionel Sambuc } 892f4a2713aSLionel Sambuc }; 893f4a2713aSLionel Sambuc namespace { 894f4a2713aSLionel Sambuc struct zed; 895f4a2713aSLionel Sambuc } 896f4a2713aSLionel Sambuc template DEFAULT void foo::bar<zed>(); baz()897f4a2713aSLionel Sambuc void baz() { 898f4a2713aSLionel Sambuc foo::bar<zed>(); 899f4a2713aSLionel Sambuc } 900f4a2713aSLionel Sambuc // CHECK-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv 901f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv 902f4a2713aSLionel Sambuc } 903f4a2713aSLionel Sambuc 904f4a2713aSLionel Sambuc namespace test49 { 905f4a2713aSLionel Sambuc // Test that we use the visibility of struct foo when instantiating the 906f4a2713aSLionel Sambuc // template. Note that is a case where we disagree with gcc, it produces 907f4a2713aSLionel Sambuc // a default symbol. 908f4a2713aSLionel Sambuc 909f4a2713aSLionel Sambuc struct HIDDEN foo { 910f4a2713aSLionel Sambuc }; 911f4a2713aSLionel Sambuc 912f4a2713aSLionel Sambuc DEFAULT foo x; 913f4a2713aSLionel Sambuc 914f4a2713aSLionel Sambuc struct bar { 915f4a2713aSLionel Sambuc template<foo *z> zedtest49::bar916f4a2713aSLionel Sambuc void zed() { 917f4a2713aSLionel Sambuc } 918f4a2713aSLionel Sambuc }; 919f4a2713aSLionel Sambuc 920f4a2713aSLionel Sambuc template void bar::zed<&x>(); 921f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv 922f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv 923f4a2713aSLionel Sambuc } 924f4a2713aSLionel Sambuc 925f4a2713aSLionel Sambuc namespace test50 { 926f4a2713aSLionel Sambuc // Test that we use the visibility of struct foo when instantiating the 927f4a2713aSLionel Sambuc // template. Note that is a case where we disagree with gcc, it produces 928f4a2713aSLionel Sambuc // a default symbol. 929f4a2713aSLionel Sambuc 930f4a2713aSLionel Sambuc struct HIDDEN foo { 931f4a2713aSLionel Sambuc }; 932f4a2713aSLionel Sambuc DEFAULT foo x; 933f4a2713aSLionel Sambuc template<foo *z> 934f4a2713aSLionel Sambuc struct DEFAULT bar { zedtest50::bar935f4a2713aSLionel Sambuc void zed() { 936f4a2713aSLionel Sambuc } 937f4a2713aSLionel Sambuc }; 938f4a2713aSLionel Sambuc template void bar<&x>::zed(); 939f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv 940f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv 941f4a2713aSLionel Sambuc } 942f4a2713aSLionel Sambuc 943f4a2713aSLionel Sambuc namespace test51 { 944f4a2713aSLionel Sambuc // Test that we use the visibility of struct foo when instantiating the 945f4a2713aSLionel Sambuc // template. Note that is a case where we disagree with gcc, it produces 946f4a2713aSLionel Sambuc // a default symbol. 947f4a2713aSLionel Sambuc 948f4a2713aSLionel Sambuc struct HIDDEN foo { 949f4a2713aSLionel Sambuc }; 950f4a2713aSLionel Sambuc DEFAULT foo x; 951f4a2713aSLionel Sambuc template<foo *z> zed()952f4a2713aSLionel Sambuc void DEFAULT zed() { 953f4a2713aSLionel Sambuc } 954f4a2713aSLionel Sambuc template void zed<&x>(); 955f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv 956f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv 957f4a2713aSLionel Sambuc } 958f4a2713aSLionel Sambuc 959f4a2713aSLionel Sambuc namespace test52 { 960f4a2713aSLionel Sambuc // Test that we use the linkage of struct foo when instantiating the 961f4a2713aSLionel Sambuc // template. Note that is a case where we disagree with gcc, it produces 962f4a2713aSLionel Sambuc // an external symbol. 963f4a2713aSLionel Sambuc 964f4a2713aSLionel Sambuc namespace { 965f4a2713aSLionel Sambuc struct foo { 966f4a2713aSLionel Sambuc }; 967f4a2713aSLionel Sambuc } 968f4a2713aSLionel Sambuc template<foo *x> zed()969f4a2713aSLionel Sambuc void zed() { 970f4a2713aSLionel Sambuc } f()971f4a2713aSLionel Sambuc void f() { 972f4a2713aSLionel Sambuc zed<nullptr>(); 973f4a2713aSLionel Sambuc } 974f4a2713aSLionel Sambuc // CHECK-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv 975f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv 976f4a2713aSLionel Sambuc } 977f4a2713aSLionel Sambuc 978f4a2713aSLionel Sambuc namespace test53 { 979f4a2713aSLionel Sambuc template<typename _Tp > struct vector { 980f4a2713aSLionel Sambuc static void _M_fill_insert(); 981f4a2713aSLionel Sambuc }; 982f4a2713aSLionel Sambuc #pragma GCC visibility push(hidden) 983f4a2713aSLionel Sambuc // GCC doesn't seem to use the visibility of enums at all, we do. 984f4a2713aSLionel Sambuc enum zed {v1}; 985f4a2713aSLionel Sambuc 986f4a2713aSLionel Sambuc // GCC fails to mark this specialization hidden, we mark it. 987f4a2713aSLionel Sambuc template<> 988f4a2713aSLionel Sambuc struct vector<int> { 989f4a2713aSLionel Sambuc static void _M_fill_insert(); 990f4a2713aSLionel Sambuc }; foo()991f4a2713aSLionel Sambuc void foo() { 992f4a2713aSLionel Sambuc vector<unsigned>::_M_fill_insert(); 993f4a2713aSLionel Sambuc vector<int>::_M_fill_insert(); 994f4a2713aSLionel Sambuc vector<zed>::_M_fill_insert(); 995f4a2713aSLionel Sambuc } 996f4a2713aSLionel Sambuc #pragma GCC visibility pop 997f4a2713aSLionel Sambuc // CHECK: declare void @_ZN6test536vectorIjE14_M_fill_insertEv 998f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare void @_ZN6test536vectorIjE14_M_fill_insertEv 999f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv 1000f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv 1001f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv 1002f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv 1003f4a2713aSLionel Sambuc } 1004f4a2713aSLionel Sambuc 1005f4a2713aSLionel Sambuc namespace test54 { 1006f4a2713aSLionel Sambuc template <class T> 1007f4a2713aSLionel Sambuc struct foo { 1008f4a2713aSLionel Sambuc static void bar(); 1009f4a2713aSLionel Sambuc }; 1010f4a2713aSLionel Sambuc #pragma GCC visibility push(hidden) 1011f4a2713aSLionel Sambuc class zed { 1012f4a2713aSLionel Sambuc zed(const zed &); 1013f4a2713aSLionel Sambuc }; bah()1014f4a2713aSLionel Sambuc void bah() { 1015f4a2713aSLionel Sambuc foo<zed>::bar(); 1016f4a2713aSLionel Sambuc } 1017f4a2713aSLionel Sambuc #pragma GCC visibility pop 1018f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6test543fooINS_3zedEE3barEv 1019f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6test543fooINS_3zedEE3barEv 1020f4a2713aSLionel Sambuc } 1021f4a2713aSLionel Sambuc 1022f4a2713aSLionel Sambuc namespace test55 { 1023f4a2713aSLionel Sambuc template <class T> 1024f4a2713aSLionel Sambuc struct HIDDEN foo { 1025f4a2713aSLionel Sambuc static void bar(); 1026f4a2713aSLionel Sambuc }; 1027f4a2713aSLionel Sambuc template <class T> struct foo; foobar()1028f4a2713aSLionel Sambuc void foobar() { 1029f4a2713aSLionel Sambuc foo<int>::bar(); 1030f4a2713aSLionel Sambuc } 1031f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6test553fooIiE3barEv 1032f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6test553fooIiE3barEv 1033f4a2713aSLionel Sambuc } 1034f4a2713aSLionel Sambuc 1035f4a2713aSLionel Sambuc namespace test56 { 1036f4a2713aSLionel Sambuc template <class T> struct foo; 1037f4a2713aSLionel Sambuc template <class T> 1038f4a2713aSLionel Sambuc struct HIDDEN foo { 1039f4a2713aSLionel Sambuc static void bar(); 1040f4a2713aSLionel Sambuc }; foobar()1041f4a2713aSLionel Sambuc void foobar() { 1042f4a2713aSLionel Sambuc foo<int>::bar(); 1043f4a2713aSLionel Sambuc } 1044f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6test563fooIiE3barEv 1045f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6test563fooIiE3barEv 1046f4a2713aSLionel Sambuc } 1047f4a2713aSLionel Sambuc 1048f4a2713aSLionel Sambuc namespace test57 { 1049f4a2713aSLionel Sambuc #pragma GCC visibility push(hidden) 1050f4a2713aSLionel Sambuc template <class T> 1051f4a2713aSLionel Sambuc struct foo; 1052f4a2713aSLionel Sambuc void bar(foo<int>*); 1053f4a2713aSLionel Sambuc template <class T> 1054f4a2713aSLionel Sambuc struct foo { 1055f4a2713aSLionel Sambuc static void zed(); 1056f4a2713aSLionel Sambuc }; bah()1057f4a2713aSLionel Sambuc void bah() { 1058f4a2713aSLionel Sambuc foo<int>::zed(); 1059f4a2713aSLionel Sambuc } 1060f4a2713aSLionel Sambuc #pragma GCC visibility pop 1061f4a2713aSLionel Sambuc // CHECK: declare hidden void @_ZN6test573fooIiE3zedEv 1062f4a2713aSLionel Sambuc // CHECK-HIDDEN: declare hidden void @_ZN6test573fooIiE3zedEv 1063f4a2713aSLionel Sambuc } 1064f4a2713aSLionel Sambuc 1065f4a2713aSLionel Sambuc namespace test58 { 1066f4a2713aSLionel Sambuc #pragma GCC visibility push(hidden) 1067f4a2713aSLionel Sambuc struct foo; 1068f4a2713aSLionel Sambuc template<typename T> 1069f4a2713aSLionel Sambuc struct DEFAULT bar { zedtest58::bar1070f4a2713aSLionel Sambuc static void zed() { 1071f4a2713aSLionel Sambuc } 1072f4a2713aSLionel Sambuc }; bah()1073f4a2713aSLionel Sambuc void bah() { 1074f4a2713aSLionel Sambuc bar<foo>::zed(); 1075f4a2713aSLionel Sambuc } 1076f4a2713aSLionel Sambuc #pragma GCC visibility pop 1077f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv 1078f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv 1079f4a2713aSLionel Sambuc } 1080f4a2713aSLionel Sambuc 1081f4a2713aSLionel Sambuc namespace test59 { 1082f4a2713aSLionel Sambuc DEFAULT int f(); 1083f4a2713aSLionel Sambuc HIDDEN int g(); 1084f4a2713aSLionel Sambuc typedef int (*foo)(); 1085f4a2713aSLionel Sambuc template<foo x, foo y> test()1086f4a2713aSLionel Sambuc void test() {} use()1087f4a2713aSLionel Sambuc void use() { 1088f4a2713aSLionel Sambuc test<&g, &f>(); 1089f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv 1090f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv 1091f4a2713aSLionel Sambuc 1092f4a2713aSLionel Sambuc test<&f, &g>(); 1093f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv 1094f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv 1095f4a2713aSLionel Sambuc } 1096f4a2713aSLionel Sambuc } 1097f4a2713aSLionel Sambuc 1098f4a2713aSLionel Sambuc namespace test60 { 1099f4a2713aSLionel Sambuc template<int i> 1100f4a2713aSLionel Sambuc class HIDDEN a {}; 1101f4a2713aSLionel Sambuc template<int i> 1102f4a2713aSLionel Sambuc class DEFAULT b {}; 1103f4a2713aSLionel Sambuc template<template<int> class x, template<int> class y> test()1104f4a2713aSLionel Sambuc void test() {} use()1105f4a2713aSLionel Sambuc void use() { 1106f4a2713aSLionel Sambuc test<a, b>(); 1107f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv 1108f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv 1109f4a2713aSLionel Sambuc 1110f4a2713aSLionel Sambuc test<b, a>(); 1111f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv 1112f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv 1113f4a2713aSLionel Sambuc } 1114f4a2713aSLionel Sambuc } 1115f4a2713aSLionel Sambuc 1116f4a2713aSLionel Sambuc namespace test61 { 1117f4a2713aSLionel Sambuc template <typename T1> 1118f4a2713aSLionel Sambuc struct Class1 1119f4a2713aSLionel Sambuc { f1test61::Class11120f4a2713aSLionel Sambuc void f1() { f2(); } 1121f4a2713aSLionel Sambuc inline void f2(); 1122f4a2713aSLionel Sambuc }; 1123f4a2713aSLionel Sambuc template<> f2()1124f4a2713aSLionel Sambuc inline void Class1<int>::f2() 1125f4a2713aSLionel Sambuc { 1126f4a2713aSLionel Sambuc } g(Class1<int> * x)1127f4a2713aSLionel Sambuc void g(Class1<int> *x) { 1128f4a2713aSLionel Sambuc x->f1(); 1129f4a2713aSLionel Sambuc } 1130f4a2713aSLionel Sambuc } 1131f4a2713aSLionel Sambuc namespace test61 { 1132f4a2713aSLionel Sambuc // Just test that we don't crash. Currently we apply this attribute. Current 1133f4a2713aSLionel Sambuc // gcc issues a warning about it being unused since "the type is already 1134f4a2713aSLionel Sambuc // defined". We should probably do the same. 1135f4a2713aSLionel Sambuc template class HIDDEN Class1<int>; 1136f4a2713aSLionel Sambuc } 1137f4a2713aSLionel Sambuc 1138f4a2713aSLionel Sambuc namespace test62 { 1139f4a2713aSLionel Sambuc template <typename T1> 1140f4a2713aSLionel Sambuc struct Class1 1141f4a2713aSLionel Sambuc { f1test62::Class11142f4a2713aSLionel Sambuc void f1() { f2(); } f2test62::Class11143f4a2713aSLionel Sambuc inline void f2() {} 1144f4a2713aSLionel Sambuc }; 1145f4a2713aSLionel Sambuc template<> f2()1146f4a2713aSLionel Sambuc inline void Class1<int>::f2() 1147f4a2713aSLionel Sambuc { 1148f4a2713aSLionel Sambuc } g(Class1<int> * x)1149f4a2713aSLionel Sambuc void g(Class1<int> *x) { 1150f4a2713aSLionel Sambuc x->f2(); 1151f4a2713aSLionel Sambuc } 1152f4a2713aSLionel Sambuc } 1153f4a2713aSLionel Sambuc namespace test62 { 1154f4a2713aSLionel Sambuc template class HIDDEN Class1<int>; 1155f4a2713aSLionel Sambuc // Just test that we don't crash. Currently we apply this attribute. Current 1156f4a2713aSLionel Sambuc // gcc issues a warning about it being unused since "the type is already 1157f4a2713aSLionel Sambuc // defined". We should probably do the same. 1158f4a2713aSLionel Sambuc } 1159f4a2713aSLionel Sambuc 1160f4a2713aSLionel Sambuc namespace test63 { 1161f4a2713aSLionel Sambuc enum HIDDEN E { E0 }; 1162f4a2713aSLionel Sambuc struct A { footest63::A1163f4a2713aSLionel Sambuc template <E> static void foo() {} 1164f4a2713aSLionel Sambuc 1165f4a2713aSLionel Sambuc template <E> struct B { footest63::A::B1166f4a2713aSLionel Sambuc static void foo() {} 1167f4a2713aSLionel Sambuc }; 1168f4a2713aSLionel Sambuc }; 1169f4a2713aSLionel Sambuc test()1170f4a2713aSLionel Sambuc void test() { 1171f4a2713aSLionel Sambuc A::foo<E0>(); 1172f4a2713aSLionel Sambuc A::B<E0>::foo(); 1173f4a2713aSLionel Sambuc } 1174f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A3fooILNS_1EE0EEEvv() 1175f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A1BILNS_1EE0EE3fooEv() 1176f4a2713aSLionel Sambuc } 1177f4a2713aSLionel Sambuc 1178f4a2713aSLionel Sambuc // Don't ignore the visibility of template arguments just because we 1179f4a2713aSLionel Sambuc // explicitly instantiated something. 1180f4a2713aSLionel Sambuc namespace test64 { 1181f4a2713aSLionel Sambuc struct HIDDEN A {}; 1182f4a2713aSLionel Sambuc template <class P> struct B { footest64::B1183f4a2713aSLionel Sambuc static DEFAULT void foo() {} 1184f4a2713aSLionel Sambuc }; 1185f4a2713aSLionel Sambuc 1186f4a2713aSLionel Sambuc template class B<A>; 1187f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr hidden void @_ZN6test641BINS_1AEE3fooEv() 1188f4a2713aSLionel Sambuc } 1189f4a2713aSLionel Sambuc 1190f4a2713aSLionel Sambuc namespace test65 { 1191f4a2713aSLionel Sambuc class HIDDEN A {}; 1192f4a2713aSLionel Sambuc template <class T> struct B { 1193f4a2713aSLionel Sambuc static void func(); 1194f4a2713aSLionel Sambuc template <class U> static void funcT1(); 1195f4a2713aSLionel Sambuc template <class U> static void funcT2(); 1196f4a2713aSLionel Sambuc class Inner {}; 1197f4a2713aSLionel Sambuc template <class U> class InnerT {}; 1198f4a2713aSLionel Sambuc }; 1199f4a2713aSLionel Sambuc template <template <class T> class Temp> struct C { footest65::C1200f4a2713aSLionel Sambuc static void foo() {} 1201f4a2713aSLionel Sambuc }; 1202f4a2713aSLionel Sambuc 1203f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test651BINS_1AEE4funcEv() func()1204f4a2713aSLionel Sambuc template <> DEFAULT void B<A>::func() {} 1205f4a2713aSLionel Sambuc 1206f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test651BINS_1AEE6funcT2IS1_EEvv() funcT2()1207f4a2713aSLionel Sambuc template <> template <> DEFAULT void B<A>::funcT2<A>() {} 1208f4a2713aSLionel Sambuc 1209f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6funcT1IiEEvv() 1210f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6funcT1IS1_EEvv() funcT1()1211f4a2713aSLionel Sambuc template <> template <class T> DEFAULT void B<A>::funcT1() {} 1212f4a2713aSLionel Sambuc 1213f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE5Inner3fooEv() 1214f4a2713aSLionel Sambuc template <> struct DEFAULT B<A>::Inner { footest65::B::Inner1215f4a2713aSLionel Sambuc static void foo() {} 1216f4a2713aSLionel Sambuc }; 1217f4a2713aSLionel Sambuc 1218f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6InnerTIiE3fooEv() 1219f4a2713aSLionel Sambuc // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6InnerTIS1_E3fooEv() 1220f4a2713aSLionel Sambuc template <> template <class U> struct DEFAULT B<A>::InnerT { footest65::B::InnerT1221f4a2713aSLionel Sambuc static void foo() {} 1222f4a2713aSLionel Sambuc }; 1223f4a2713aSLionel Sambuc test()1224f4a2713aSLionel Sambuc void test() { 1225f4a2713aSLionel Sambuc B<A>::funcT1<int>(); 1226f4a2713aSLionel Sambuc B<A>::funcT1<A>(); 1227f4a2713aSLionel Sambuc B<A>::Inner::foo(); 1228f4a2713aSLionel Sambuc B<A>::InnerT<int>::foo(); 1229f4a2713aSLionel Sambuc B<A>::InnerT<A>::foo(); 1230f4a2713aSLionel Sambuc } 1231f4a2713aSLionel Sambuc 1232f4a2713aSLionel Sambuc template class C<B<A>::InnerT>; 1233f4a2713aSLionel Sambuc } 1234f4a2713aSLionel Sambuc 1235f4a2713aSLionel Sambuc namespace test66 { 1236f4a2713aSLionel Sambuc template <typename T> 1237f4a2713aSLionel Sambuc struct DEFAULT barT { zedtest66::barT1238f4a2713aSLionel Sambuc static void zed() {} 1239f4a2713aSLionel Sambuc }; 1240f4a2713aSLionel Sambuc class foo; 1241f4a2713aSLionel Sambuc class DEFAULT foo; 1242f4a2713aSLionel Sambuc template struct barT<foo>; 1243f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv 1244f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv 1245f4a2713aSLionel Sambuc 1246f4a2713aSLionel Sambuc template <int* I> 1247f4a2713aSLionel Sambuc struct DEFAULT barI { zedtest66::barI1248f4a2713aSLionel Sambuc static void zed() {} 1249f4a2713aSLionel Sambuc }; 1250f4a2713aSLionel Sambuc extern int I; 1251f4a2713aSLionel Sambuc extern int I DEFAULT; 1252f4a2713aSLionel Sambuc template struct barI<&I>; 1253f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv 1254f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv 1255f4a2713aSLionel Sambuc 1256f4a2713aSLionel Sambuc typedef void (*fType)(void); 1257f4a2713aSLionel Sambuc template<fType F> 1258f4a2713aSLionel Sambuc struct DEFAULT barF { zedtest66::barF1259f4a2713aSLionel Sambuc static void zed() {} 1260f4a2713aSLionel Sambuc }; 1261f4a2713aSLionel Sambuc void F(); 1262f4a2713aSLionel Sambuc void F() DEFAULT; 1263f4a2713aSLionel Sambuc template struct barF<F>; 1264f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv 1265f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv 1266f4a2713aSLionel Sambuc } 1267f4a2713aSLionel Sambuc 1268f4a2713aSLionel Sambuc namespace test67 { 1269f4a2713aSLionel Sambuc template <typename T> 1270f4a2713aSLionel Sambuc struct DEFAULT bar { zedtest67::bar1271f4a2713aSLionel Sambuc static void zed() {} 1272f4a2713aSLionel Sambuc }; 1273f4a2713aSLionel Sambuc 1274f4a2713aSLionel Sambuc class foo; 1275f4a2713aSLionel Sambuc class compute { 1276f4a2713aSLionel Sambuc void f(foo *rootfoo); 1277f4a2713aSLionel Sambuc }; 1278f4a2713aSLionel Sambuc class DEFAULT foo; 1279f4a2713aSLionel Sambuc 1280f4a2713aSLionel Sambuc template struct bar<foo>; 1281f4a2713aSLionel Sambuc // CHECK-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv 1282f4a2713aSLionel Sambuc // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv 1283f4a2713aSLionel Sambuc } 1284f4a2713aSLionel Sambuc 1285f4a2713aSLionel Sambuc namespace test68 { 1286f4a2713aSLionel Sambuc class A { public: ~A(); }; 1287f4a2713aSLionel Sambuc class f { 1288f4a2713aSLionel Sambuc public: f()1289f4a2713aSLionel Sambuc f() { 1290f4a2713aSLionel Sambuc static A test; 1291f4a2713aSLionel Sambuc } 1292f4a2713aSLionel Sambuc }; g()1293f4a2713aSLionel Sambuc void g() { 1294f4a2713aSLionel Sambuc f a; 1295f4a2713aSLionel Sambuc } 1296f4a2713aSLionel Sambuc // Check lines at top of file. 1297f4a2713aSLionel Sambuc } 1298*0a6a1f1dSLionel Sambuc 1299*0a6a1f1dSLionel Sambuc namespace test69 { 1300*0a6a1f1dSLionel Sambuc // PR18174 1301*0a6a1f1dSLionel Sambuc namespace foo { 1302*0a6a1f1dSLionel Sambuc void f(); 1303*0a6a1f1dSLionel Sambuc } 1304*0a6a1f1dSLionel Sambuc namespace foo { f()1305*0a6a1f1dSLionel Sambuc void f() {}; 1306*0a6a1f1dSLionel Sambuc } 1307*0a6a1f1dSLionel Sambuc namespace foo __attribute__((visibility("hidden"))) { 1308*0a6a1f1dSLionel Sambuc } 1309*0a6a1f1dSLionel Sambuc // CHECK-LABEL: define void @_ZN6test693foo1fEv 1310*0a6a1f1dSLionel Sambuc // CHECK-HIDDEN-LABEL: define hidden void @_ZN6test693foo1fEv 1311*0a6a1f1dSLionel Sambuc } 1312