Skip to content

Commit a45edf6

Browse files
philnik777rlavaee
authored andcommitted
[Clang] Allow the use of [[gnu::visibility]] with #pragma clang attribute (llvm#145653)
I don't see any reason this shouldn't be allowed. AFAICT this is only disabled due to the heuristics used to determine whether it makes sense to allow the use of an attribute with `#pragma clang attribute`. This allows libc++ to drop `_LIBCPP_HIDE_FROM_ABI` in a lot of places, making the library significantly easier to read.
1 parent e46ba7b commit a45edf6

File tree

5 files changed

+67
-11
lines changed

5 files changed

+67
-11
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3735,6 +3735,7 @@ def Visibility : InheritableAttr {
37353735
["default", "hidden", "internal", "protected"],
37363736
["Default", "Hidden", "Hidden", "Protected"]>];
37373737
let MeaningfulToClassTemplateDefinition = 1;
3738+
let PragmaAttributeSupport = 1;
37383739
let Documentation = [Undocumented];
37393740
}
37403741

clang/test/CodeGen/visibility.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility=default -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT
2-
// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility=protected -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-PROTECTED
3-
// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility=hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
1+
// RUN: %clang_cc1 %s -triple i386-unknown-unknown -Wno-implicit-function-declaration -fvisibility=default -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT
2+
// RUN: %clang_cc1 %s -triple i386-unknown-unknown -Wno-implicit-function-declaration -fvisibility=protected -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-PROTECTED
3+
// RUN: %clang_cc1 %s -triple i386-unknown-unknown -Wno-implicit-function-declaration -fvisibility=hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
44

55
// CHECK-DEFAULT: @g_def ={{.*}} global i32 0
66
// CHECK-DEFAULT: @g_com ={{.*}} global i32 0
@@ -72,3 +72,27 @@ __private_extern__ int test4 = 10;
7272
// CHECK-HIDDEN-LABEL: define hidden void @test5()
7373
__attribute__((availability(macosx,introduced=10.5,deprecated=10.6)))
7474
__private_extern__ void test5(void) {}
75+
76+
77+
#pragma clang attribute push([[gnu::visibility("hidden")]], apply_to=function)
78+
79+
// CHECK-DEFAULT-LABEL: define hidden void @func()
80+
// CHECK-PROTECTED-LABEL: define hidden void @func()
81+
// CHECK-HIDDEN-LABEL: define hidden void @func()
82+
void func(void) {}
83+
84+
void call(void) {
85+
implicit_function();
86+
// CHECK-DEFAULT-LABEL: declare hidden i32 @implicit_function(...)
87+
// CHECK-PROTECTED-LABEL: declare hidden i32 @implicit_function(...)
88+
// CHECK-HIDDEN-LABEL: declare hidden i32 @implicit_function(...)
89+
}
90+
91+
#pragma clang attribute pop
92+
93+
void call2(void) {
94+
implicit_function2();
95+
// CHECK-DEFAULT-LABEL: declare i32 @implicit_function2(...)
96+
// CHECK-PROTECTED-LABEL: declare i32 @implicit_function2(...)
97+
// CHECK-HIDDEN-LABEL: declare i32 @implicit_function2(...)
98+
}

clang/test/CodeGenCXX/visibility.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ namespace test27 {
218218
namespace Test1 {
219219
// CHECK-LABEL: define hidden void @_ZN5Test11fEv
220220
void HIDDEN f() { }
221-
221+
222222
}
223223

224224
namespace Test2 {
@@ -230,7 +230,7 @@ namespace Test2 {
230230
// CHECK-LABEL: define hidden void @_ZN5Test21A1fEv
231231
void A::f() { }
232232
}
233-
233+
234234
namespace Test3 {
235235
struct HIDDEN A {
236236
struct B {
@@ -240,23 +240,23 @@ namespace Test3 {
240240

241241
// B is a nested class where its parent class is hidden.
242242
// CHECK-LABEL: define hidden void @_ZN5Test31A1B1fEv
243-
void A::B::f() { }
243+
void A::B::f() { }
244244
}
245245

246246
namespace Test4 HIDDEN {
247247
int VariableInHiddenNamespace = 10;
248248

249249
// Test4::g is in a hidden namespace.
250250
// CHECK-LABEL: define hidden void @_ZN5Test41gEv
251-
void g() { }
252-
251+
void g() { }
252+
253253
struct DEFAULT A {
254254
void f();
255255
};
256-
256+
257257
// A has default visibility.
258258
// CHECK-LABEL: define void @_ZN5Test41A1fEv
259-
void A::f() { }
259+
void A::f() { }
260260
}
261261

262262
namespace Test5 {
@@ -266,7 +266,7 @@ namespace Test5 {
266266
// CHECK-LABEL: define hidden void @_ZN5Test52NS1fEv()
267267
void f() { }
268268
}
269-
269+
270270
namespace NS {
271271
// g is in NS, but this NS decl is not hidden.
272272
// CHECK-LABEL: define void @_ZN5Test52NS1gEv
@@ -1536,3 +1536,27 @@ namespace test75 {
15361536
// CHECK-LABEL: define linkonce_odr hidden void @_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
15371537
// CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
15381538
}
1539+
1540+
#pragma clang attribute push([[gnu::visibility("hidden")]], apply_to=function)
1541+
1542+
namespace pragma_test {
1543+
struct S {
1544+
S();
1545+
};
1546+
1547+
S::S() = default;
1548+
// CHECK-LABEL: define hidden void @_ZN11pragma_test1SC2Ev(
1549+
// CHECK-HIDDEN-LABEL: define hidden void @_ZN11pragma_test1SC2Ev(
1550+
}
1551+
1552+
#pragma clang attribute pop
1553+
1554+
namespace no_pragma_test {
1555+
struct S {
1556+
S();
1557+
};
1558+
1559+
S::S() = default;
1560+
// CHECK-LABEL: define void @_ZN14no_pragma_test1SC2Ev(
1561+
// CHECK-HIDDEN-LABEL: define hidden void @_ZN14no_pragma_test1SC2Ev(
1562+
}

clang/test/Misc/pragma-attribute-supported-attributes-list.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@
212212
// CHECK-NEXT: VTablePointerAuthentication (SubjectMatchRule_record)
213213
// CHECK-NEXT: VecReturn (SubjectMatchRule_record)
214214
// CHECK-NEXT: VecTypeHint (SubjectMatchRule_function)
215+
// CHECK-NEXT: Visibility ()
215216
// CHECK-NEXT: WarnUnused (SubjectMatchRule_record)
216217
// CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType, SubjectMatchRule_type_alias)
217218
// CHECK-NEXT: Weak (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)

clang/test/Sema/attr-visibility.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,9 @@ typedef int __attribute__((visibility("default"))) bar; // expected-warning {{'v
2525
int x __attribute__((type_visibility("default"))); // expected-error {{'type_visibility' attribute only applies to types and namespaces}}
2626

2727
int PR17105 __attribute__((visibility(hidden))); // expected-error {{'visibility' attribute requires a string}}
28+
29+
#pragma clang attribute push([[gnu::visibility("default")]], apply_to=function)
30+
31+
void func(void) {}
32+
33+
#pragma clang attribute pop

0 commit comments

Comments
 (0)