summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-04-16 18:25:01 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-04-16 18:25:01 +0000
commit0f90590c96375052c67116f620fafa2b1eadb41e (patch)
treed3686bc2a2526a002d5fec0cfbd37106c6ae5e62
parent2b5949e0e66934f6e234818eb04209f4f3cb15ef (diff)
Use ordering and the explicit visibility bit instead of modifying
ConsiderGlobalVisibility. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154843 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/Decl.cpp80
1 files changed, 36 insertions, 44 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index f26998081f..ef833d8c7d 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -69,9 +69,9 @@ typedef NamedDecl::LinkageInfo LinkageInfo;
namespace {
/// Flags controlling the computation of linkage and visibility.
struct LVFlags {
- bool ConsiderGlobalVisibility;
- bool ConsiderVisibilityAttributes;
- bool ConsiderTemplateParameterTypes;
+ const bool ConsiderGlobalVisibility;
+ const bool ConsiderVisibilityAttributes;
+ const bool ConsiderTemplateParameterTypes;
LVFlags() : ConsiderGlobalVisibility(true),
ConsiderVisibilityAttributes(true),
@@ -415,12 +415,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
}
}
- // Consider -fvisibility unless the type has C linkage.
- if (F.ConsiderGlobalVisibility)
- F.ConsiderGlobalVisibility =
- (Context.getLangOpts().CPlusPlus &&
- !Tag->getDeclContext()->isExternCContext());
-
// - an enumerator belonging to an enumeration with external linkage;
} else if (isa<EnumConstantDecl>(D)) {
LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()), F);
@@ -452,7 +446,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
if (F.ConsiderVisibilityAttributes) {
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,
// use that namespace's visibility, but don't call it explicit.
@@ -463,7 +456,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
if (!ND) continue;
if (llvm::Optional<Visibility> Vis = ND->getExplicitVisibility()) {
LV.setVisibility(*Vis, true);
- F.ConsiderGlobalVisibility = false;
break;
}
}
@@ -493,21 +485,46 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
LinkageInfo LV;
LV.mergeVisibility(D->getASTContext().getLangOpts().getVisibilityMode());
- // The flags we're going to use to compute the class's visibility.
- LVFlags ClassF = F;
-
+ bool DHasExplicitVisibility = false;
// If we have an explicit visibility attribute, merge that in.
if (F.ConsiderVisibilityAttributes) {
if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) {
LV.mergeVisibility(*Vis, true);
- // Ignore global visibility later, but not this attribute.
- F.ConsiderGlobalVisibility = false;
+ DHasExplicitVisibility = true;
+ }
+ }
+ // Ignore both global visibility and attributes when computing our
+ // parent's visibility if we already have an explicit one.
+ LVFlags ClassF = DHasExplicitVisibility ?
+ LVFlags::CreateOnlyDeclLinkage() : F;
- // Ignore both global visibility and attributes when computing our
- // parent's visibility.
- ClassF = LVFlags::CreateOnlyDeclLinkage();
+ // 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 &&
+ F.ConsiderGlobalVisibility &&
+ !LV.visibilityExplicit() &&
+ MD->getASTContext().getLangOpts().InlineVisibilityHidden &&
+ MD->hasBody(Def) && Def->isInlined())
+ LV.mergeVisibility(HiddenVisibility, true);
}
// Class members only have linkage if their class has external
@@ -526,8 +543,6 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
if (MD->getType()->getLinkage() == UniqueExternalLinkage)
return LinkageInfo::uniqueExternal();
- TemplateSpecializationKind TSK = TSK_Undeclared;
-
// If this is a method template specialization, use the linkage for
// the template parameters and arguments.
if (FunctionTemplateSpecializationInfo *spec
@@ -539,29 +554,6 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
LV.merge(getLVForTemplateParameterList(
spec->getTemplate()->getTemplateParameters()));
}
-
- TSK = spec->getTemplateSpecializationKind();
- } else if (MemberSpecializationInfo *MSI =
- MD->getMemberSpecializationInfo()) {
- TSK = MSI->getTemplateSpecializationKind();
- }
-
- // If we're paying attention to global visibility, apply
- // -finline-visibility-hidden if this is an inline method.
- //
- // Note that ConsiderGlobalVisibility doesn't yet have information
- // about whether containing classes have visibility attributes,
- // and that's intentional.
- if (TSK != TSK_ExplicitInstantiationDeclaration &&
- TSK != TSK_ExplicitInstantiationDefinition &&
- F.ConsiderGlobalVisibility &&
- MD->getASTContext().getLangOpts().InlineVisibilityHidden) {
- // InlineVisibilityHidden only applies to definitions, and
- // isInlined() only gives meaningful answers on definitions
- // anyway.
- const FunctionDecl *Def = 0;
- if (MD->hasBody(Def) && Def->isInlined())
- LV.setVisibility(HiddenVisibility);
}
// Note that in contrast to basically every other situation, we