[cfe-commits] r160174 - in /cfe/trunk: lib/AST/Decl.cpp test/CodeGenCXX/visibility-inlines-hidden.cpp

Rafael Espindola rafael.espindola at gmail.com
Fri Jul 13 07:25:37 PDT 2012


Author: rafael
Date: Fri Jul 13 09:25:36 2012
New Revision: 160174

URL: http://llvm.org/viewvc/llvm-project?rev=160174&view=rev
Log:
Use -fvisibility-inlines-hidden in inline functions too. This matches gcc
behavior since gcc pr30066. Thanks to Benjamin Kramer for pointing it out.

Modified:
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=160174&r1=160173&r2=160174&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Jul 13 09:25:36 2012
@@ -168,6 +168,35 @@
   return !d->hasAttr<VisibilityAttr>() || d->isExplicitSpecialization();
 }
 
+static bool useInlineVisibilityHidden(const NamedDecl *D) {
+  // FIXME: we should warn if -fvisibility-inlines-hidden is used with c.
+  ASTContext &Context = D->getASTContext();
+  if (!Context.getLangOpts().CPlusPlus)
+    return false;
+
+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+  if (!FD)
+    return false;
+
+  TemplateSpecializationKind TSK = TSK_Undeclared;
+  if (FunctionTemplateSpecializationInfo *spec
+      = FD->getTemplateSpecializationInfo()) {
+    TSK = spec->getTemplateSpecializationKind();
+  } else if (MemberSpecializationInfo *MSI =
+             FD->getMemberSpecializationInfo()) {
+    TSK = MSI->getTemplateSpecializationKind();
+  }
+
+  const FunctionDecl *Def = 0;
+  // InlineVisibilityHidden only applies to definitions, and
+  // isInlined() only gives meaningful answers on definitions
+  // anyway.
+  return TSK != TSK_ExplicitInstantiationDeclaration &&
+    TSK != TSK_ExplicitInstantiationDefinition &&
+    FD->getASTContext().getLangOpts().InlineVisibilityHidden &&
+    FD->hasBody(Def) && Def->isInlined();
+}
+
 static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
                                               bool OnlyTemplate) {
   assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
@@ -266,8 +295,13 @@
     }
   }
 
-  if (!OnlyTemplate)
+  if (!OnlyTemplate) {
     LV.mergeVisibility(Context.getLangOpts().getVisibilityMode());
+    // If we're paying attention to global visibility, apply
+    // -finline-visibility-hidden if this is an inline method.
+    if (!LV.visibilityExplicit() && useInlineVisibilityHidden(D))
+      LV.mergeVisibility(HiddenVisibility, true);
+  }
 
   // C++ [basic.link]p4:
 
@@ -473,6 +507,13 @@
   if (!OnlyTemplate) {
     if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility())
       LV.mergeVisibility(*Vis, true);
+    // If we're paying attention to global visibility, apply
+    // -finline-visibility-hidden if this is an inline method.
+    //
+    // Note that we do this before merging information about
+    // the class visibility.
+    if (!LV.visibilityExplicit() && useInlineVisibilityHidden(D))
+      LV.mergeVisibility(HiddenVisibility, true);
   }
 
   // If this class member has an explicit visibility attribute, the only
@@ -480,34 +521,6 @@
   // only look for them when processing the the class.
   bool ClassOnlyTemplate =  LV.visibilityExplicit() ? true : OnlyTemplate;
 
-  // If we're paying attention to global visibility, apply
-  // -finline-visibility-hidden if this is an inline method.
-  //
-  // Note that we do this before merging information about
-  // the class visibility.
-  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
-    TemplateSpecializationKind TSK = TSK_Undeclared;
-    if (FunctionTemplateSpecializationInfo *spec
-        = MD->getTemplateSpecializationInfo()) {
-      TSK = spec->getTemplateSpecializationKind();
-    } else if (MemberSpecializationInfo *MSI =
-               MD->getMemberSpecializationInfo()) {
-      TSK = MSI->getTemplateSpecializationKind();
-    }
-
-    const FunctionDecl *Def = 0;
-    // InlineVisibilityHidden only applies to definitions, and
-    // isInlined() only gives meaningful answers on definitions
-    // anyway.
-    if (TSK != TSK_ExplicitInstantiationDeclaration &&
-        TSK != TSK_ExplicitInstantiationDefinition &&
-        !OnlyTemplate &&
-        !LV.visibilityExplicit() &&
-        MD->getASTContext().getLangOpts().InlineVisibilityHidden &&
-        MD->hasBody(Def) && Def->isInlined())
-      LV.mergeVisibility(HiddenVisibility, true);
-  }
-
   // If this member has an visibility attribute, ClassF will exclude
   // attributes on the class or command line options, keeping only information
   // about the template instantiation. If the member has no visibility

Modified: cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp?rev=160174&r1=160173&r2=160174&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp Fri Jul 13 09:25:36 2012
@@ -108,3 +108,21 @@
   template class Foo<int>;
   // CHECK: define weak_odr i32 @_ZN7PR116423FooIiE3fooEi
 }
+
+// Test that clang implements the new gcc behaviour for inline functions.
+// GCC PR30066.
+namespace test3 {
+  inline void foo(void) {
+  }
+  template<typename T>
+  inline void zed() {
+  }
+  template void zed<float>();
+  void bar(void) {
+    foo();
+    zed<int>();
+  }
+  // CHECK: define weak_odr void @_ZN5test33zedIfEEvv
+  // CHECK: define linkonce_odr hidden void @_ZN5test33fooEv
+  // CHECK: define linkonce_odr hidden void @_ZN5test33zedIiEEvv
+}





More information about the cfe-commits mailing list