summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/Decl.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/AST/Decl.cpp117
1 files changed, 50 insertions, 67 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/Decl.cpp b/contrib/llvm/tools/clang/lib/AST/Decl.cpp
index 399f2e4..53032bc 100644
--- a/contrib/llvm/tools/clang/lib/AST/Decl.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/Decl.cpp
@@ -69,33 +69,25 @@ 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),
ConsiderTemplateParameterTypes(true) {
}
+ LVFlags(bool Global, bool Attributes, bool Parameters) :
+ ConsiderGlobalVisibility(Global),
+ ConsiderVisibilityAttributes(Attributes),
+ ConsiderTemplateParameterTypes(Parameters) {
+ }
+
/// \brief Returns a set of flags that is only useful for computing the
/// linkage, not the visibility, of a declaration.
static LVFlags CreateOnlyDeclLinkage() {
- LVFlags F;
- F.ConsiderGlobalVisibility = false;
- F.ConsiderVisibilityAttributes = false;
- F.ConsiderTemplateParameterTypes = false;
- return F;
- }
-
- /// Returns a set of flags, otherwise based on these, which ignores
- /// off all sources of visibility except template arguments.
- LVFlags onlyTemplateVisibility() const {
- LVFlags F = *this;
- F.ConsiderGlobalVisibility = false;
- F.ConsiderVisibilityAttributes = false;
- F.ConsiderTemplateParameterTypes = false;
- return F;
+ return LVFlags(false, false, false);
}
};
} // end anonymous namespace
@@ -284,7 +276,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.
@@ -295,7 +286,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;
}
}
@@ -335,8 +325,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
LinkageInfo TypeLV = getLVForType(Var->getType());
if (TypeLV.linkage() != ExternalLinkage)
return LinkageInfo::uniqueExternal();
- LV.mergeVisibilityWithMin(TypeLV.visibility(),
- TypeLV.visibilityExplicit());
+ LV.mergeVisibilityWithMin(TypeLV);
}
if (Var->getStorageClass() == SC_PrivateExtern)
@@ -412,7 +401,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
= Function->getTemplateSpecializationInfo()) {
if (shouldConsiderTemplateLV(Function, specInfo)) {
LV.merge(getLVForDecl(specInfo->getTemplate(),
- F.onlyTemplateVisibility()));
+ LVFlags::CreateOnlyDeclLinkage()));
const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
LV.mergeWithMin(getLVForTemplateArgumentList(templateArgs, F));
}
@@ -436,7 +425,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
if (shouldConsiderTemplateLV(spec)) {
// From the template.
LV.merge(getLVForDecl(spec->getSpecializedTemplate(),
- F.onlyTemplateVisibility()));
+ LVFlags::CreateOnlyDeclLinkage()));
// The arguments at which the template was instantiated.
const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();
@@ -444,12 +433,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);
@@ -501,21 +484,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 = F.onlyTemplateVisibility();
+ // 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
@@ -534,8 +542,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
@@ -547,29 +553,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
@@ -597,7 +580,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
if (TypeLV.linkage() != ExternalLinkage)
LV.mergeLinkage(UniqueExternalLinkage);
if (!LV.visibilityExplicit())
- LV.mergeVisibility(TypeLV.visibility(), TypeLV.visibilityExplicit());
+ LV.mergeVisibility(TypeLV);
}
return LV;
@@ -802,7 +785,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
LinkageInfo LV;
if (Flags.ConsiderVisibilityAttributes) {
if (llvm::Optional<Visibility> Vis = Function->getExplicitVisibility())
- LV.setVisibility(*Vis);
+ LV.setVisibility(*Vis, true);
}
if (const FunctionDecl *Prev = Function->getPreviousDecl()) {
@@ -823,10 +806,10 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
LinkageInfo LV;
if (Var->getStorageClass() == SC_PrivateExtern)
- LV.setVisibility(HiddenVisibility);
+ LV.setVisibility(HiddenVisibility, true);
else if (Flags.ConsiderVisibilityAttributes) {
if (llvm::Optional<Visibility> Vis = Var->getExplicitVisibility())
- LV.setVisibility(*Vis);
+ LV.setVisibility(*Vis, true);
}
if (const VarDecl *Prev = Var->getPreviousDecl()) {
OpenPOWER on IntegriCloud