[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