[cfe-commits] r128336 - in /cfe/trunk: include/clang/AST/Decl.h lib/AST/Decl.cpp lib/CodeGen/CGVTables.cpp lib/CodeGen/CodeGenModule.cpp lib/Sema/SemaAttr.cpp test/CodeGen/attr-availability.c test/CodeGenObjC/attr-availability.m

Douglas Gregor dgregor at apple.com
Sat Mar 26 05:10:19 PDT 2011


Author: dgregor
Date: Sat Mar 26 07:10:19 2011
New Revision: 128336

URL: http://llvm.org/viewvc/llvm-project?rev=128336&view=rev
Log:
On Mac OS X, the presence of an 'availability' attribute for that
platform implies default visibility. To achieve these, refactor our
lookup of explicit visibility so that we search for both an explicit
VisibilityAttr and an appropriate AvailabilityAttr, favoring the
VisibilityAttr if it is present.


Added:
    cfe/trunk/test/CodeGen/attr-availability.c   (with props)
Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/CodeGen/CGVTables.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/Sema/SemaAttr.cpp
    cfe/trunk/test/CodeGenObjC/attr-availability.m

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=128336&r1=128335&r2=128336&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Mar 26 07:10:19 2011
@@ -20,6 +20,7 @@
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/Basic/Linkage.h"
+#include "llvm/ADT/Optional.h"
 
 namespace clang {
 class CXXTemporary;
@@ -273,6 +274,10 @@
   /// \brief Determines the linkage and visibility of this entity.
   LinkageInfo getLinkageAndVisibility() const;
 
+  /// \brief If visibility was explicitly specified for this
+  /// declaration, return that visibility.
+  llvm::Optional<Visibility> getExplicitVisibility() const;
+
   /// \brief Clear the linkage cache in response to a change
   /// to the declaration. 
   void ClearLinkageCache();

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=128336&r1=128335&r2=128336&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sat Mar 26 07:10:19 2011
@@ -25,6 +25,7 @@
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetInfo.h"
 #include "llvm/Support/ErrorHandling.h"
 
 using namespace clang;
@@ -33,53 +34,33 @@
 // NamedDecl Implementation
 //===----------------------------------------------------------------------===//
 
-static const VisibilityAttr *GetExplicitVisibility(const Decl *d) {
-  // Use the most recent declaration of a variable.
-  if (const VarDecl *var = dyn_cast<VarDecl>(d))
-    return var->getMostRecentDeclaration()->getAttr<VisibilityAttr>();
-
-  // Use the most recent declaration of a function, and also handle
-  // function template specializations.
-  if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(d)) {
-    if (const VisibilityAttr *attr
-          = fn->getMostRecentDeclaration()->getAttr<VisibilityAttr>())
-      return attr;
-
-    // If the function is a specialization of a template with an
-    // explicit visibility attribute, use that.
-    if (FunctionTemplateSpecializationInfo *templateInfo
-          = fn->getTemplateSpecializationInfo())
-      return templateInfo->getTemplate()->getTemplatedDecl()
-        ->getAttr<VisibilityAttr>();
+static llvm::Optional<Visibility> getVisibilityOf(const Decl *D) {
+  // If this declaration has an explicit visibility attribute, use it.
+  if (const VisibilityAttr *A = D->getAttr<VisibilityAttr>()) {
+    switch (A->getVisibility()) {
+    case VisibilityAttr::Default:
+      return DefaultVisibility;
+    case VisibilityAttr::Hidden:
+      return HiddenVisibility;
+    case VisibilityAttr::Protected:
+      return ProtectedVisibility;
+    }
 
-    return 0;
+    return DefaultVisibility;
   }
 
-  // Otherwise, just check the declaration itself first.
-  if (const VisibilityAttr *attr = d->getAttr<VisibilityAttr>())
-    return attr;
-
-  // If there wasn't explicit visibility there, and this is a
-  // specialization of a class template, check for visibility
-  // on the pattern.
-  if (const ClassTemplateSpecializationDecl *spec
-        = dyn_cast<ClassTemplateSpecializationDecl>(d))
-    return spec->getSpecializedTemplate()->getTemplatedDecl()
-      ->getAttr<VisibilityAttr>();
-
-  return 0;
-}
-
-static Visibility GetVisibilityFromAttr(const VisibilityAttr *A) {
-  switch (A->getVisibility()) {
-  case VisibilityAttr::Default:
-    return DefaultVisibility;
-  case VisibilityAttr::Hidden:
-    return HiddenVisibility;
-  case VisibilityAttr::Protected:
-    return ProtectedVisibility;
+  // If we're on Mac OS X, an 'availability' for Mac OS X attribute
+  // implies visibility(default).
+  if (D->getASTContext().Target.getTriple().getOS() == llvm::Triple::Darwin) {
+    for (specific_attr_iterator<AvailabilityAttr> 
+              A = D->specific_attr_begin<AvailabilityAttr>(),
+           AEnd = D->specific_attr_end<AvailabilityAttr>();
+         A != AEnd; ++A)
+      if ((*A)->getPlatform()->getName().equals("macosx"))
+        return DefaultVisibility;
   }
-  return DefaultVisibility;
+
+  return llvm::Optional<Visibility>();
 }
 
 typedef NamedDecl::LinkageInfo LinkageInfo;
@@ -286,8 +267,8 @@
   LinkageInfo LV;
 
   if (F.ConsiderVisibilityAttributes) {
-    if (const VisibilityAttr *VA = GetExplicitVisibility(D)) {
-      LV.setVisibility(GetVisibilityFromAttr(VA), true);
+    if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) {
+      LV.setVisibility(*Vis, true);
       F.ConsiderGlobalVisibility = false;
     } else {
       // If we're declared in a namespace with a visibility attribute,
@@ -296,9 +277,9 @@
            !isa<TranslationUnitDecl>(DC);
            DC = DC->getParent()) {
         if (!isa<NamespaceDecl>(DC)) continue;
-        if (const VisibilityAttr *VA =
-              cast<NamespaceDecl>(DC)->getAttr<VisibilityAttr>()) {
-          LV.setVisibility(GetVisibilityFromAttr(VA), false);
+        if (llvm::Optional<Visibility> Vis
+                           = cast<NamespaceDecl>(DC)->getExplicitVisibility()) {
+          LV.setVisibility(*Vis, false);
           F.ConsiderGlobalVisibility = false;
           break;
         }
@@ -506,8 +487,8 @@
 
   // If we have an explicit visibility attribute, merge that in.
   if (F.ConsiderVisibilityAttributes) {
-    if (const VisibilityAttr *VA = GetExplicitVisibility(D)) {
-      LV.mergeVisibility(GetVisibilityFromAttr(VA), true);
+    if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) {
+      LV.mergeVisibility(*Vis, true);
 
       // Ignore global visibility later, but not this attribute.
       F.ConsiderGlobalVisibility = false;
@@ -669,6 +650,41 @@
   return LI;
 }
 
+llvm::Optional<Visibility> NamedDecl::getExplicitVisibility() const {
+  // Use the most recent declaration of a variable.
+  if (const VarDecl *var = dyn_cast<VarDecl>(this))
+    return getVisibilityOf(var->getMostRecentDeclaration());
+
+  // Use the most recent declaration of a function, and also handle
+  // function template specializations.
+  if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(this)) {
+    if (llvm::Optional<Visibility> V
+                            = getVisibilityOf(fn->getMostRecentDeclaration())) 
+      return V;
+
+    // If the function is a specialization of a template with an
+    // explicit visibility attribute, use that.
+    if (FunctionTemplateSpecializationInfo *templateInfo
+          = fn->getTemplateSpecializationInfo())
+      return getVisibilityOf(templateInfo->getTemplate()->getTemplatedDecl());
+
+    return llvm::Optional<Visibility>();
+  }
+
+  // Otherwise, just check the declaration itself first.
+  if (llvm::Optional<Visibility> V = getVisibilityOf(this))
+    return V;
+
+  // If there wasn't explicit visibility there, and this is a
+  // specialization of a class template, check for visibility
+  // on the pattern.
+  if (const ClassTemplateSpecializationDecl *spec
+        = dyn_cast<ClassTemplateSpecializationDecl>(this))
+    return getVisibilityOf(spec->getSpecializedTemplate()->getTemplatedDecl());
+
+  return llvm::Optional<Visibility>();
+}
+
 static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
   // Objective-C: treat all Objective-C declarations as having external
   // linkage.
@@ -722,8 +738,8 @@
 
       LinkageInfo LV;
       if (Flags.ConsiderVisibilityAttributes) {
-        if (const VisibilityAttr *VA = GetExplicitVisibility(Function))
-          LV.setVisibility(GetVisibilityFromAttr(VA));
+        if (llvm::Optional<Visibility> Vis = Function->getExplicitVisibility())
+          LV.setVisibility(*Vis);
       }
       
       if (const FunctionDecl *Prev = Function->getPreviousDeclaration()) {
@@ -745,8 +761,8 @@
         if (Var->getStorageClass() == SC_PrivateExtern)
           LV.setVisibility(HiddenVisibility);
         else if (Flags.ConsiderVisibilityAttributes) {
-          if (const VisibilityAttr *VA = GetExplicitVisibility(Var))
-            LV.setVisibility(GetVisibilityFromAttr(VA));
+          if (llvm::Optional<Visibility> Vis = Var->getExplicitVisibility())
+            LV.setVisibility(*Vis);
         }
         
         if (const VarDecl *Prev = Var->getPreviousDeclaration()) {

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=128336&r1=128335&r2=128336&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Sat Mar 26 07:10:19 2011
@@ -2545,7 +2545,7 @@
       Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
     return;
 
-  if (MD->hasAttr<VisibilityAttr>())
+  if (MD->getExplicitVisibility())
     return;
 
   switch (MD->getTemplateSpecializationKind()) {

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=128336&r1=128335&r2=128336&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sat Mar 26 07:10:19 2011
@@ -224,7 +224,7 @@
     return;
 
   // Don't override an explicit visibility attribute.
-  if (RD->hasAttr<VisibilityAttr>())
+  if (RD->getExplicitVisibility())
     return;
 
   switch (RD->getTemplateSpecializationKind()) {

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=128336&r1=128335&r2=128336&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Sat Mar 26 07:10:19 2011
@@ -297,7 +297,7 @@
   if (!VisContext)
     return;
 
-  if (D->hasAttr<VisibilityAttr>())
+  if (isa<NamedDecl>(D) && cast<NamedDecl>(D)->getExplicitVisibility())
     return;
 
   VisStack *Stack = static_cast<VisStack*>(VisContext);

Added: cfe/trunk/test/CodeGen/attr-availability.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attr-availability.c?rev=128336&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/attr-availability.c (added)
+++ cfe/trunk/test/CodeGen/attr-availability.c Sat Mar 26 07:10:19 2011
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fvisibility hidden "-triple" "x86_64-apple-darwin8.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_4 %s
+// RUN: %clang_cc1 -fvisibility hidden "-triple" "x86_64-apple-darwin9.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_5 %s
+// RUN: %clang_cc1 -fvisibility hidden "-triple" "x86_64-apple-darwin10.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_6 %s
+
+// CHECK-10_4: define hidden void @f2
+// CHECK-10_5: define hidden void @f2
+// CHECK-10_6: define hidden void @f2
+void f2();
+void f2() { }
+
+// CHECK-10_4: define void @f3
+// CHECK-10_5: define void @f3
+// CHECK-10_6: define void @f3
+void f3() __attribute__((availability(macosx,introduced=10.5)));
+void f3() { }
+
+// CHECK-10_4: declare extern_weak void @f0
+// CHECK-10_5: declare void @f0
+// CHECK-10_6: declare void @f0
+void f0() __attribute__((availability(macosx,introduced=10.5)));
+
+// CHECK-10_4: declare extern_weak void @f1
+// CHECK-10_5: declare extern_weak void @f1
+// CHECK-10_6: declare void @f1
+void f1() __attribute__((availability(macosx,introduced=10.6)));
+
+void test() {
+  f0();
+  f1();
+  f2();
+}

Propchange: cfe/trunk/test/CodeGen/attr-availability.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CodeGen/attr-availability.c
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CodeGen/attr-availability.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/test/CodeGenObjC/attr-availability.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/attr-availability.m?rev=128336&r1=128335&r2=128336&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/attr-availability.m (original)
+++ cfe/trunk/test/CodeGenObjC/attr-availability.m Sat Mar 26 07:10:19 2011
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fobjc-nonfragile-abi "-triple" "x86_64-apple-darwin8.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_4 %s
-// RUN: %clang_cc1 -fobjc-nonfragile-abi "-triple" "x86_64-apple-darwin9.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_5 %s
-// RUN: %clang_cc1 -fobjc-nonfragile-abi "-triple" "x86_64-apple-darwin10.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_6 %s
+// RUN: %clang_cc1 -fvisibility hidden -fobjc-nonfragile-abi "-triple" "x86_64-apple-darwin8.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_4 %s
+// RUN: %clang_cc1 -fvisibility hidden -fobjc-nonfragile-abi "-triple" "x86_64-apple-darwin9.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_5 %s
+// RUN: %clang_cc1 -fvisibility hidden -fobjc-nonfragile-abi "-triple" "x86_64-apple-darwin10.0.0" -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-10_6 %s
 
 // CHECK-10_4: @"OBJC_CLASS_$_WeakClass1" = extern_weak global
 // CHECK-10_5: @"OBJC_CLASS_$_WeakClass1" = external global





More information about the cfe-commits mailing list