From 0f90590c96375052c67116f620fafa2b1eadb41e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 16 Apr 2012 18:25:01 +0000 Subject: 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 --- lib/AST/Decl.cpp | 80 +++++++++++++++++++++++++------------------------------- 1 file 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(D)) { LinkageInfo EnumLV = getLVForDecl(cast(D->getDeclContext()), F); @@ -452,7 +446,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { if (F.ConsiderVisibilityAttributes) { if (llvm::Optional 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 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 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(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 -- cgit v1.2.3