Use ordering and the explicit visibility bit instead of modifying

ConsiderGlobalVisibility. No functionality change.

llvm-svn: 154843
This commit is contained in:
Rafael Espindola 2012-04-16 18:25:01 +00:00
parent 4c0db08880
commit 505a7c818d

View File

@ -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,22 +485,47 @@ 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;
// Ignore both global visibility and attributes when computing our
// parent's visibility.
ClassF = LVFlags::CreateOnlyDeclLinkage();
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;
// 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
// linkage.
@ -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