[cfe-commits] r117351 - in /cfe/trunk: include/clang/AST/DeclBase.h lib/AST/Decl.cpp lib/AST/DeclBase.cpp test/CodeGen/visibility.c test/CodeGenCXX/visibility.cpp
Rafael Espíndola
rafael.espindola at gmail.com
Tue Oct 26 07:14:41 PDT 2010
Thanks!
On 26 October 2010 00:59, John McCall <rjmccall at apple.com> wrote:
> Author: rjmccall
> Date: Mon Oct 25 23:59:26 2010
> New Revision: 117351
>
> URL: http://llvm.org/viewvc/llvm-project?rev=117351&view=rev
> Log:
> A couple of tweaks to the visibility rules:
> - tags with C linkage should ignore visibility=hidden
> - functions and variables with explicit visibility attributes should
> ignore the linkage of their types
> Either of these should be sufficient to fix PR8457.
>
> Also, FileCheck-ize a test case.
>
>
> Modified:
> cfe/trunk/include/clang/AST/DeclBase.h
> cfe/trunk/lib/AST/Decl.cpp
> cfe/trunk/lib/AST/DeclBase.cpp
> cfe/trunk/test/CodeGen/visibility.c
> cfe/trunk/test/CodeGenCXX/visibility.cpp
>
> Modified: cfe/trunk/include/clang/AST/DeclBase.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=117351&r1=117350&r2=117351&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/DeclBase.h (original)
> +++ cfe/trunk/include/clang/AST/DeclBase.h Mon Oct 25 23:59:26 2010
> @@ -816,6 +816,10 @@
> /// C++0x scoped enums), and C++ linkage specifications.
> bool isTransparentContext() const;
>
> + /// \brief Determines whether this context is, or is nested within,
> + /// a C++ extern "C" linkage spec.
> + bool isExternCContext() const;
> +
> /// \brief Determine whether this declaration context is equivalent
> /// to the declaration context DC.
> bool Equals(const DeclContext *DC) const {
>
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=117351&r1=117350&r2=117351&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Mon Oct 25 23:59:26 2010
> @@ -212,9 +212,13 @@
> // given variable or function shall be identical...
> // C does not have an equivalent rule.
> //
> + // Ignore this if we've got an explicit attribute; the user
> + // probably knows what they're doing.
> + //
> // Note that we don't want to make the variable non-external
> // because of this, but unique-external linkage suits us.
> - if (Context.getLangOptions().CPlusPlus && !Var->isExternC()) {
> + if (Context.getLangOptions().CPlusPlus && !Var->isExternC() &&
> + !Var->hasAttr<VisibilityAttr>()) {
> LVPair TypeLV = Var->getType()->getLinkageAndVisibility();
> if (TypeLV.first != ExternalLinkage)
> return LVPair(UniqueExternalLinkage, DefaultVisibility);
> @@ -247,7 +251,8 @@
> } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
> // Modify the function's LV by the LV of its type unless this is
> // C or extern "C". See the comment above about variables.
> - if (Context.getLangOptions().CPlusPlus && !Function->isExternC()) {
> + if (Context.getLangOptions().CPlusPlus && !Function->isExternC() &&
> + !Function->hasAttr<VisibilityAttr>()) {
> LVPair TypeLV = Function->getType()->getLinkageAndVisibility();
> if (TypeLV.first != ExternalLinkage)
> return LVPair(UniqueExternalLinkage, DefaultVisibility);
> @@ -321,8 +326,11 @@
> ConsiderDashFVisibility = false;
> }
>
> + // Consider -fvisibility unless the type has C linkage.
> if (ConsiderDashFVisibility)
> - ConsiderDashFVisibility = Tag->isDefinition();
> + ConsiderDashFVisibility =
> + (Context.getLangOptions().CPlusPlus &&
> + !Tag->getDeclContext()->isExternCContext());
>
> // - an enumerator belonging to an enumeration with external linkage;
> } else if (isa<EnumConstantDecl>(D)) {
>
> Modified: cfe/trunk/lib/AST/DeclBase.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=117351&r1=117350&r2=117351&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> +++ cfe/trunk/lib/AST/DeclBase.cpp Mon Oct 25 23:59:26 2010
> @@ -529,6 +529,17 @@
> return false;
> }
>
> +bool DeclContext::isExternCContext() const {
> + const DeclContext *DC = this;
> + while (DC->DeclKind != Decl::TranslationUnit) {
> + if (DC->DeclKind == Decl::LinkageSpec)
> + return cast<LinkageSpecDecl>(DC)->getLanguage()
> + == LinkageSpecDecl::lang_c;
> + DC = DC->getParent();
> + }
> + return false;
> +}
> +
> bool DeclContext::Encloses(const DeclContext *DC) const {
> if (getPrimaryContext() != this)
> return getPrimaryContext()->Encloses(DC);
>
> Modified: cfe/trunk/test/CodeGen/visibility.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/visibility.c?rev=117351&r1=117350&r2=117351&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGen/visibility.c (original)
> +++ cfe/trunk/test/CodeGen/visibility.c Mon Oct 25 23:59:26 2010
> @@ -1,33 +1,34 @@
> -// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility default -emit-llvm -o %t %s
> -// RUN: grep '@g_com = common global i32 0' %t
> -// RUN: grep '@g_def = global i32 0' %t
> -// RUN: grep '@g_ext = external global i32' %t
> -// RUN: grep '@g_deferred = internal global' %t
> -// RUN: grep 'declare void @f_ext()' %t
> -// RUN: grep 'define internal void @f_deferred()' %t
> -// RUN: grep 'define i32 @f_def()' %t
> -// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility protected -emit-llvm -o %t %s
> -// RUN: grep '@g_com = common protected global i32 0' %t
> -// RUN: grep '@g_def = protected global i32 0' %t
> -// RUN: grep '@g_ext = external global i32' %t
> -// RUN: grep '@g_deferred = internal global' %t
> -// RUN: grep 'declare void @f_ext()' %t
> -// RUN: grep 'define internal void @f_deferred()' %t
> -// RUN: grep 'define protected i32 @f_def()' %t
> -// RUN: %clang_cc1 -triple i386-unknown-unknown -fvisibility hidden -emit-llvm -o %t %s
> -// RUN: grep '@g_com = common hidden global i32 0' %t
> -// RUN: grep '@g_def = hidden global i32 0' %t
> -// RUN: grep '@g_ext = external global i32' %t
> -// RUN: grep '@g_deferred = internal global' %t
> -// RUN: grep 'declare void @f_ext()' %t
> -// RUN: grep 'define internal void @f_deferred()' %t
> -// RUN: grep 'define hidden i32 @f_def()' %t
> +// 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
>
> +// CHECK-DEFAULT: @g_def = global i32 0
> +// CHECK-DEFAULT: @g_com = common global i32 0
> +// CHECK-DEFAULT: @g_ext = external global i32
> +// CHECK-DEFAULT: @g_deferred = internal global
> +// CHECK-PROTECTED: @g_def = protected global i32 0
> +// CHECK-PROTECTED: @g_com = common protected global i32 0
> +// CHECK-PROTECTED: @g_ext = external global i32
> +// CHECK-PROTECTED: @g_deferred = internal global
> +// CHECK-HIDDEN: @g_def = hidden global i32 0
> +// CHECK-HIDDEN: @g_com = common hidden global i32 0
> +// CHECK-HIDDEN: @g_ext = external global i32
> +// CHECK-HIDDEN: @g_deferred = internal global
> int g_com;
> int g_def = 0;
> extern int g_ext;
> static char g_deferred[] = "hello";
>
> +// CHECK-DEFAULT: define i32 @f_def()
> +// CHECK-DEFAULT: declare void @f_ext()
> +// CHECK-DEFAULT: define internal void @f_deferred()
> +// CHECK-PROTECTED: define protected i32 @f_def()
> +// CHECK-PROTECTED: declare void @f_ext()
> +// CHECK-PROTECTED: define internal void @f_deferred()
> +// CHECK-HIDDEN: define hidden i32 @f_def()
> +// CHECK-HIDDEN: declare void @f_ext()
> +// CHECK-HIDDEN: define internal void @f_deferred()
> +
> extern void f_ext(void);
>
> static void f_deferred(void) {
> @@ -38,3 +39,10 @@
> f_deferred();
> return g_com + g_def + g_ext + g_deferred[0];
> }
> +
> +// PR8457
> +// CHECK-DEFAULT: define void @test1(
> +// CHECK-PROTECTED: define void @test1(
> +// CHECK-HIDDEN: define void @test1(
> +struct Test1 { int field; };
> +void __attribute__((visibility("default"))) test1(struct Test1 *v) { }
>
> Modified: cfe/trunk/test/CodeGenCXX/visibility.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/visibility.cpp?rev=117351&r1=117350&r2=117351&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/visibility.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/visibility.cpp Mon Oct 25 23:59:26 2010
> @@ -8,6 +8,8 @@
> // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
> // CHECK: @_ZN5Test71aE = hidden global
> // CHECK: @_ZN5Test71bE = global
> +// CHECK: @test9_var = global
> +// CHECK-HIDDEN: @test9_var = global
> // CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant
>
> namespace Test1 {
> @@ -115,3 +117,19 @@
> bar();
> }
> }
> +
> +// PR8457
> +namespace Test9 {
> + extern "C" {
> + struct A { int field; };
> + void DEFAULT test9_fun(struct A *a) { }
> + struct A DEFAULT test9_var; // above
> + }
> + // CHECK: define void @test9_fun(
> + // CHECK-HIDDEN: define void @test9_fun(
> +
> + void test() {
> + A a = test9_var;
> + test9_fun(&a);
> + }
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list