[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