[clang] afc6c2b - [Clang] Allow the use of [[gnu::visibility]] with #pragma clang attribute (#145653)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 26 05:54:18 PDT 2025
Author: Nikolas Klauser
Date: 2025-06-26T14:54:15+02:00
New Revision: afc6c2bb9b43c63d5fbf2596f559917ad335ee7d
URL: https://github.com/llvm/llvm-project/commit/afc6c2bb9b43c63d5fbf2596f559917ad335ee7d
DIFF: https://github.com/llvm/llvm-project/commit/afc6c2bb9b43c63d5fbf2596f559917ad335ee7d.diff
LOG: [Clang] Allow the use of [[gnu::visibility]] with #pragma clang attribute (#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.
Added:
Modified:
clang/include/clang/Basic/Attr.td
clang/test/CodeGen/visibility.c
clang/test/CodeGenCXX/visibility.cpp
clang/test/Misc/pragma-attribute-supported-attributes-list.test
clang/test/Sema/attr-visibility.c
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 27fea7dea0a5e..5d8ce6b650d9c 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3735,6 +3735,7 @@ def Visibility : InheritableAttr {
["default", "hidden", "internal", "protected"],
["Default", "Hidden", "Hidden", "Protected"]>];
let MeaningfulToClassTemplateDefinition = 1;
+ let PragmaAttributeSupport = 1;
let Documentation = [Undocumented];
}
diff --git a/clang/test/CodeGen/visibility.c b/clang/test/CodeGen/visibility.c
index ee760ec77879e..947bdf3d377a6 100644
--- a/clang/test/CodeGen/visibility.c
+++ b/clang/test/CodeGen/visibility.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility=default -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT
-// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility=protected -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-PROTECTED
-// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fvisibility=hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -Wno-implicit-function-declaration -fvisibility=default -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-DEFAULT
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -Wno-implicit-function-declaration -fvisibility=protected -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-PROTECTED
+// RUN: %clang_cc1 %s -triple i386-unknown-unknown -Wno-implicit-function-declaration -fvisibility=hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
// CHECK-DEFAULT: @g_def ={{.*}} global i32 0
// CHECK-DEFAULT: @g_com ={{.*}} global i32 0
@@ -72,3 +72,27 @@ __private_extern__ int test4 = 10;
// CHECK-HIDDEN-LABEL: define hidden void @test5()
__attribute__((availability(macosx,introduced=10.5,deprecated=10.6)))
__private_extern__ void test5(void) {}
+
+
+#pragma clang attribute push([[gnu::visibility("hidden")]], apply_to=function)
+
+// CHECK-DEFAULT-LABEL: define hidden void @func()
+// CHECK-PROTECTED-LABEL: define hidden void @func()
+// CHECK-HIDDEN-LABEL: define hidden void @func()
+void func(void) {}
+
+void call(void) {
+ implicit_function();
+ // CHECK-DEFAULT-LABEL: declare hidden i32 @implicit_function(...)
+ // CHECK-PROTECTED-LABEL: declare hidden i32 @implicit_function(...)
+ // CHECK-HIDDEN-LABEL: declare hidden i32 @implicit_function(...)
+}
+
+#pragma clang attribute pop
+
+void call2(void) {
+ implicit_function2();
+ // CHECK-DEFAULT-LABEL: declare i32 @implicit_function2(...)
+ // CHECK-PROTECTED-LABEL: declare i32 @implicit_function2(...)
+ // CHECK-HIDDEN-LABEL: declare i32 @implicit_function2(...)
+}
diff --git a/clang/test/CodeGenCXX/visibility.cpp b/clang/test/CodeGenCXX/visibility.cpp
index 442e2a5aaa2b3..3203d476c45f9 100644
--- a/clang/test/CodeGenCXX/visibility.cpp
+++ b/clang/test/CodeGenCXX/visibility.cpp
@@ -218,7 +218,7 @@ namespace test27 {
namespace Test1 {
// CHECK-LABEL: define hidden void @_ZN5Test11fEv
void HIDDEN f() { }
-
+
}
namespace Test2 {
@@ -230,7 +230,7 @@ namespace Test2 {
// CHECK-LABEL: define hidden void @_ZN5Test21A1fEv
void A::f() { }
}
-
+
namespace Test3 {
struct HIDDEN A {
struct B {
@@ -240,7 +240,7 @@ namespace Test3 {
// B is a nested class where its parent class is hidden.
// CHECK-LABEL: define hidden void @_ZN5Test31A1B1fEv
- void A::B::f() { }
+ void A::B::f() { }
}
namespace Test4 HIDDEN {
@@ -248,15 +248,15 @@ namespace Test4 HIDDEN {
// Test4::g is in a hidden namespace.
// CHECK-LABEL: define hidden void @_ZN5Test41gEv
- void g() { }
-
+ void g() { }
+
struct DEFAULT A {
void f();
};
-
+
// A has default visibility.
// CHECK-LABEL: define void @_ZN5Test41A1fEv
- void A::f() { }
+ void A::f() { }
}
namespace Test5 {
@@ -266,7 +266,7 @@ namespace Test5 {
// CHECK-LABEL: define hidden void @_ZN5Test52NS1fEv()
void f() { }
}
-
+
namespace NS {
// g is in NS, but this NS decl is not hidden.
// CHECK-LABEL: define void @_ZN5Test52NS1gEv
@@ -1536,3 +1536,27 @@ namespace test75 {
// CHECK-LABEL: define linkonce_odr hidden void @_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
// CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test751TIMNS_1AEFvvEE6InvokeIiEEvT_(
}
+
+#pragma clang attribute push([[gnu::visibility("hidden")]], apply_to=function)
+
+namespace pragma_test {
+ struct S {
+ S();
+ };
+
+ S::S() = default;
+ // CHECK-LABEL: define hidden void @_ZN11pragma_test1SC2Ev(
+ // CHECK-HIDDEN-LABEL: define hidden void @_ZN11pragma_test1SC2Ev(
+}
+
+#pragma clang attribute pop
+
+namespace no_pragma_test {
+ struct S {
+ S();
+ };
+
+ S::S() = default;
+ // CHECK-LABEL: define void @_ZN14no_pragma_test1SC2Ev(
+ // CHECK-HIDDEN-LABEL: define hidden void @_ZN14no_pragma_test1SC2Ev(
+}
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 41d00dae3f69a..05693538252aa 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -212,6 +212,7 @@
// CHECK-NEXT: VTablePointerAuthentication (SubjectMatchRule_record)
// CHECK-NEXT: VecReturn (SubjectMatchRule_record)
// CHECK-NEXT: VecTypeHint (SubjectMatchRule_function)
+// CHECK-NEXT: Visibility ()
// CHECK-NEXT: WarnUnused (SubjectMatchRule_record)
// CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType, SubjectMatchRule_type_alias)
// CHECK-NEXT: Weak (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
diff --git a/clang/test/Sema/attr-visibility.c b/clang/test/Sema/attr-visibility.c
index 4acca7a7f69a3..0497e9760c44f 100644
--- a/clang/test/Sema/attr-visibility.c
+++ b/clang/test/Sema/attr-visibility.c
@@ -25,3 +25,9 @@ typedef int __attribute__((visibility("default"))) bar; // expected-warning {{'v
int x __attribute__((type_visibility("default"))); // expected-error {{'type_visibility' attribute only applies to types and namespaces}}
int PR17105 __attribute__((visibility(hidden))); // expected-error {{'visibility' attribute requires a string}}
+
+#pragma clang attribute push([[gnu::visibility("default")]], apply_to=function)
+
+void func(void) {}
+
+#pragma clang attribute pop
More information about the cfe-commits
mailing list