|
@@ -12,6 +12,7 @@
|
|
//===----------------------------------------------------------------------===//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
#include "clang/AST/Decl.h"
|
|
#include "clang/AST/Decl.h"
|
|
|
|
+#include "Linkage.h"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/AST/ASTLambda.h"
|
|
#include "clang/AST/ASTLambda.h"
|
|
#include "clang/AST/ASTMutationListener.h"
|
|
#include "clang/AST/ASTMutationListener.h"
|
|
@@ -99,38 +100,6 @@ TranslationUnitDecl::TranslationUnitDecl(ASTContext &ctx)
|
|
// and 'matcher' is a type only matters when looking for attributes
|
|
// and 'matcher' is a type only matters when looking for attributes
|
|
// and settings from the immediate context.
|
|
// and settings from the immediate context.
|
|
|
|
|
|
-const static unsigned IgnoreExplicitVisibilityBit = 2;
|
|
|
|
-const static unsigned IgnoreAllVisibilityBit = 4;
|
|
|
|
-
|
|
|
|
-/// Kinds of LV computation. The linkage side of the computation is
|
|
|
|
-/// always the same, but different things can change how visibility is
|
|
|
|
-/// computed.
|
|
|
|
-enum LVComputationKind {
|
|
|
|
- /// Do an LV computation for, ultimately, a type.
|
|
|
|
- /// Visibility may be restricted by type visibility settings and
|
|
|
|
- /// the visibility of template arguments.
|
|
|
|
- LVForType = NamedDecl::VisibilityForType,
|
|
|
|
-
|
|
|
|
- /// Do an LV computation for, ultimately, a non-type declaration.
|
|
|
|
- /// Visibility may be restricted by value visibility settings and
|
|
|
|
- /// the visibility of template arguments.
|
|
|
|
- LVForValue = NamedDecl::VisibilityForValue,
|
|
|
|
-
|
|
|
|
- /// Do an LV computation for, ultimately, a type that already has
|
|
|
|
- /// some sort of explicit visibility. Visibility may only be
|
|
|
|
- /// restricted by the visibility of template arguments.
|
|
|
|
- LVForExplicitType = (LVForType | IgnoreExplicitVisibilityBit),
|
|
|
|
-
|
|
|
|
- /// Do an LV computation for, ultimately, a non-type declaration
|
|
|
|
- /// that already has some sort of explicit visibility. Visibility
|
|
|
|
- /// may only be restricted by the visibility of template arguments.
|
|
|
|
- LVForExplicitValue = (LVForValue | IgnoreExplicitVisibilityBit),
|
|
|
|
-
|
|
|
|
- /// Do an LV computation when we only care about the linkage.
|
|
|
|
- LVForLinkageOnly =
|
|
|
|
- LVForValue | IgnoreExplicitVisibilityBit | IgnoreAllVisibilityBit
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
/// Does this computation kind permit us to consider additional
|
|
/// Does this computation kind permit us to consider additional
|
|
/// visibility settings from attributes and the like?
|
|
/// visibility settings from attributes and the like?
|
|
static bool hasExplicitVisibilityAlready(LVComputationKind computation) {
|
|
static bool hasExplicitVisibilityAlready(LVComputationKind computation) {
|
|
@@ -219,8 +188,8 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D,
|
|
return None;
|
|
return None;
|
|
}
|
|
}
|
|
|
|
|
|
-static LinkageInfo
|
|
|
|
-getLVForType(const Type &T, LVComputationKind computation) {
|
|
|
|
|
|
+LinkageInfo LinkageComputer::getLVForType(const Type &T,
|
|
|
|
+ LVComputationKind computation) {
|
|
if (computation == LVForLinkageOnly)
|
|
if (computation == LVForLinkageOnly)
|
|
return LinkageInfo(T.getLinkage(), DefaultVisibility, true);
|
|
return LinkageInfo(T.getLinkage(), DefaultVisibility, true);
|
|
return T.getLinkageAndVisibility();
|
|
return T.getLinkageAndVisibility();
|
|
@@ -229,9 +198,8 @@ getLVForType(const Type &T, LVComputationKind computation) {
|
|
/// \brief Get the most restrictive linkage for the types in the given
|
|
/// \brief Get the most restrictive linkage for the types in the given
|
|
/// template parameter list. For visibility purposes, template
|
|
/// template parameter list. For visibility purposes, template
|
|
/// parameters are part of the signature of a template.
|
|
/// parameters are part of the signature of a template.
|
|
-static LinkageInfo
|
|
|
|
-getLVForTemplateParameterList(const TemplateParameterList *Params,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+LinkageInfo LinkageComputer::getLVForTemplateParameterList(
|
|
|
|
+ const TemplateParameterList *Params, LVComputationKind computation) {
|
|
LinkageInfo LV;
|
|
LinkageInfo LV;
|
|
for (const NamedDecl *P : *Params) {
|
|
for (const NamedDecl *P : *Params) {
|
|
// Template type parameters are the most common and never
|
|
// Template type parameters are the most common and never
|
|
@@ -283,10 +251,6 @@ getLVForTemplateParameterList(const TemplateParameterList *Params,
|
|
return LV;
|
|
return LV;
|
|
}
|
|
}
|
|
|
|
|
|
-/// getLVForDecl - Get the linkage and visibility for the given declaration.
|
|
|
|
-static LinkageInfo getLVForDecl(const NamedDecl *D,
|
|
|
|
- LVComputationKind computation);
|
|
|
|
-
|
|
|
|
static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
|
|
static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
|
|
const Decl *Ret = nullptr;
|
|
const Decl *Ret = nullptr;
|
|
const DeclContext *DC = D->getDeclContext();
|
|
const DeclContext *DC = D->getDeclContext();
|
|
@@ -303,8 +267,9 @@ static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
|
|
///
|
|
///
|
|
/// Note that we don't take an LVComputationKind because we always
|
|
/// Note that we don't take an LVComputationKind because we always
|
|
/// want to honor the visibility of template arguments in the same way.
|
|
/// want to honor the visibility of template arguments in the same way.
|
|
-static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+LinkageInfo
|
|
|
|
+LinkageComputer::getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
|
|
|
|
+ LVComputationKind computation) {
|
|
LinkageInfo LV;
|
|
LinkageInfo LV;
|
|
|
|
|
|
for (const TemplateArgument &Arg : Args) {
|
|
for (const TemplateArgument &Arg : Args) {
|
|
@@ -346,9 +311,9 @@ static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
|
|
return LV;
|
|
return LV;
|
|
}
|
|
}
|
|
|
|
|
|
-static LinkageInfo
|
|
|
|
-getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+LinkageInfo
|
|
|
|
+LinkageComputer::getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
|
|
|
|
+ LVComputationKind computation) {
|
|
return getLVForTemplateArgumentList(TArgs.asArray(), computation);
|
|
return getLVForTemplateArgumentList(TArgs.asArray(), computation);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -371,10 +336,10 @@ static bool shouldConsiderTemplateVisibility(const FunctionDecl *fn,
|
|
/// LVForValue.
|
|
/// LVForValue.
|
|
///
|
|
///
|
|
/// \param[out] LV the computation to use for the parent
|
|
/// \param[out] LV the computation to use for the parent
|
|
-static void
|
|
|
|
-mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
|
|
|
|
- const FunctionTemplateSpecializationInfo *specInfo,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+void LinkageComputer::mergeTemplateLV(
|
|
|
|
+ LinkageInfo &LV, const FunctionDecl *fn,
|
|
|
|
+ const FunctionTemplateSpecializationInfo *specInfo,
|
|
|
|
+ LVComputationKind computation) {
|
|
bool considerVisibility =
|
|
bool considerVisibility =
|
|
shouldConsiderTemplateVisibility(fn, specInfo);
|
|
shouldConsiderTemplateVisibility(fn, specInfo);
|
|
|
|
|
|
@@ -449,9 +414,9 @@ static bool shouldConsiderTemplateVisibility(
|
|
|
|
|
|
/// Merge in template-related linkage and visibility for the given
|
|
/// Merge in template-related linkage and visibility for the given
|
|
/// class template specialization.
|
|
/// class template specialization.
|
|
-static void mergeTemplateLV(LinkageInfo &LV,
|
|
|
|
- const ClassTemplateSpecializationDecl *spec,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+void LinkageComputer::mergeTemplateLV(
|
|
|
|
+ LinkageInfo &LV, const ClassTemplateSpecializationDecl *spec,
|
|
|
|
+ LVComputationKind computation) {
|
|
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
|
|
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
|
|
|
|
|
|
// Merge information from the template parameters, but ignore
|
|
// Merge information from the template parameters, but ignore
|
|
@@ -501,9 +466,9 @@ static bool shouldConsiderTemplateVisibility(
|
|
/// Merge in template-related linkage and visibility for the given
|
|
/// Merge in template-related linkage and visibility for the given
|
|
/// variable template specialization. As usual, follow class template
|
|
/// variable template specialization. As usual, follow class template
|
|
/// specialization logic up to initialization.
|
|
/// specialization logic up to initialization.
|
|
-static void mergeTemplateLV(LinkageInfo &LV,
|
|
|
|
- const VarTemplateSpecializationDecl *spec,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+void LinkageComputer::mergeTemplateLV(LinkageInfo &LV,
|
|
|
|
+ const VarTemplateSpecializationDecl *spec,
|
|
|
|
+ LVComputationKind computation) {
|
|
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
|
|
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
|
|
|
|
|
|
// Merge information from the template parameters, but ignore
|
|
// Merge information from the template parameters, but ignore
|
|
@@ -603,8 +568,9 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
|
|
return LinkageInfo::external();
|
|
return LinkageInfo::external();
|
|
}
|
|
}
|
|
|
|
|
|
-static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+LinkageInfo
|
|
|
|
+LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
|
|
|
|
+ LVComputationKind computation) {
|
|
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
|
|
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
|
|
"Not a name having namespace scope");
|
|
"Not a name having namespace scope");
|
|
ASTContext &Context = D->getASTContext();
|
|
ASTContext &Context = D->getASTContext();
|
|
@@ -883,8 +849,9 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
|
|
return LV;
|
|
return LV;
|
|
}
|
|
}
|
|
|
|
|
|
-static LinkageInfo getLVForClassMember(const NamedDecl *D,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+LinkageInfo
|
|
|
|
+LinkageComputer::getLVForClassMember(const NamedDecl *D,
|
|
|
|
+ LVComputationKind computation) {
|
|
// Only certain class members have linkage. Note that fields don't
|
|
// Only certain class members have linkage. Note that fields don't
|
|
// really have linkage, but it's convenient to say they do for the
|
|
// really have linkage, but it's convenient to say they do for the
|
|
// purposes of calculating linkage of pointer-to-data-member
|
|
// purposes of calculating linkage of pointer-to-data-member
|
|
@@ -1041,15 +1008,13 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
|
|
|
|
|
|
void NamedDecl::anchor() { }
|
|
void NamedDecl::anchor() { }
|
|
|
|
|
|
-static LinkageInfo computeLVForDecl(const NamedDecl *D,
|
|
|
|
- LVComputationKind computation);
|
|
|
|
-
|
|
|
|
bool NamedDecl::isLinkageValid() const {
|
|
bool NamedDecl::isLinkageValid() const {
|
|
if (!hasCachedLinkage())
|
|
if (!hasCachedLinkage())
|
|
return true;
|
|
return true;
|
|
|
|
|
|
- return computeLVForDecl(this, LVForLinkageOnly).getLinkage() ==
|
|
|
|
- getCachedLinkage();
|
|
|
|
|
|
+ Linkage L =
|
|
|
|
+ LinkageComputer{}.computeLVForDecl(this, LVForLinkageOnly).getLinkage();
|
|
|
|
+ return L == getCachedLinkage();
|
|
}
|
|
}
|
|
|
|
|
|
ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const {
|
|
ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const {
|
|
@@ -1068,13 +1033,11 @@ ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const {
|
|
Linkage NamedDecl::getLinkageInternal() const {
|
|
Linkage NamedDecl::getLinkageInternal() const {
|
|
// We don't care about visibility here, so ask for the cheapest
|
|
// We don't care about visibility here, so ask for the cheapest
|
|
// possible visibility analysis.
|
|
// possible visibility analysis.
|
|
- return getLVForDecl(this, LVForLinkageOnly).getLinkage();
|
|
|
|
|
|
+ return LinkageComputer{}.getLVForDecl(this, LVForLinkageOnly).getLinkage();
|
|
}
|
|
}
|
|
|
|
|
|
LinkageInfo NamedDecl::getLinkageAndVisibility() const {
|
|
LinkageInfo NamedDecl::getLinkageAndVisibility() const {
|
|
- LVComputationKind computation =
|
|
|
|
- (usesTypeVisibility(this) ? LVForType : LVForValue);
|
|
|
|
- return getLVForDecl(this, computation);
|
|
|
|
|
|
+ return LinkageComputer{}.getDeclLinkageAndVisibility(this);
|
|
}
|
|
}
|
|
|
|
|
|
static Optional<Visibility>
|
|
static Optional<Visibility>
|
|
@@ -1152,8 +1115,9 @@ NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
|
|
return getExplicitVisibilityAux(this, kind, false);
|
|
return getExplicitVisibilityAux(this, kind, false);
|
|
}
|
|
}
|
|
|
|
|
|
-static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+LinkageInfo LinkageComputer::getLVForClosure(const DeclContext *DC,
|
|
|
|
+ Decl *ContextDecl,
|
|
|
|
+ LVComputationKind computation) {
|
|
// This lambda has its linkage/visibility determined by its owner.
|
|
// This lambda has its linkage/visibility determined by its owner.
|
|
if (ContextDecl) {
|
|
if (ContextDecl) {
|
|
if (isa<ParmVarDecl>(ContextDecl))
|
|
if (isa<ParmVarDecl>(ContextDecl))
|
|
@@ -1170,8 +1134,8 @@ static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
|
|
return LinkageInfo::external();
|
|
return LinkageInfo::external();
|
|
}
|
|
}
|
|
|
|
|
|
-static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
|
|
|
|
+ LVComputationKind computation) {
|
|
if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
|
|
if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
|
|
if (Function->isInAnonymousNamespace() &&
|
|
if (Function->isInAnonymousNamespace() &&
|
|
!Function->isInExternCContext())
|
|
!Function->isInExternCContext())
|
|
@@ -1264,8 +1228,8 @@ getOutermostEnclosingLambda(const CXXRecordDecl *Record) {
|
|
return Ret;
|
|
return Ret;
|
|
}
|
|
}
|
|
|
|
|
|
-static LinkageInfo computeLVForDecl(const NamedDecl *D,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
|
|
+LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D,
|
|
|
|
+ LVComputationKind computation) {
|
|
// Internal_linkage attribute overrides other considerations.
|
|
// Internal_linkage attribute overrides other considerations.
|
|
if (D->hasAttr<InternalLinkageAttr>())
|
|
if (D->hasAttr<InternalLinkageAttr>())
|
|
return getInternalLinkageFor(D);
|
|
return getInternalLinkageFor(D);
|
|
@@ -1384,56 +1348,51 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
|
|
return LinkageInfo::none();
|
|
return LinkageInfo::none();
|
|
}
|
|
}
|
|
|
|
|
|
-namespace clang {
|
|
|
|
-class LinkageComputer {
|
|
|
|
-public:
|
|
|
|
- static LinkageInfo getLVForDecl(const NamedDecl *D,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
- // Internal_linkage attribute overrides other considerations.
|
|
|
|
- if (D->hasAttr<InternalLinkageAttr>())
|
|
|
|
- return getInternalLinkageFor(D);
|
|
|
|
|
|
+/// getLVForDecl - Get the linkage and visibility for the given declaration.
|
|
|
|
+LinkageInfo LinkageComputer::getLVForDecl(const NamedDecl *D,
|
|
|
|
+ LVComputationKind computation) {
|
|
|
|
+ // Internal_linkage attribute overrides other considerations.
|
|
|
|
+ if (D->hasAttr<InternalLinkageAttr>())
|
|
|
|
+ return getInternalLinkageFor(D);
|
|
|
|
|
|
- if (computation == LVForLinkageOnly && D->hasCachedLinkage())
|
|
|
|
- return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false);
|
|
|
|
|
|
+ if (computation == LVForLinkageOnly && D->hasCachedLinkage())
|
|
|
|
+ return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false);
|
|
|
|
|
|
- LinkageInfo LV = computeLVForDecl(D, computation);
|
|
|
|
- if (D->hasCachedLinkage())
|
|
|
|
- assert(D->getCachedLinkage() == LV.getLinkage());
|
|
|
|
|
|
+ LinkageInfo LV = computeLVForDecl(D, computation);
|
|
|
|
+ if (D->hasCachedLinkage())
|
|
|
|
+ assert(D->getCachedLinkage() == LV.getLinkage());
|
|
|
|
|
|
- D->setCachedLinkage(LV.getLinkage());
|
|
|
|
|
|
+ D->setCachedLinkage(LV.getLinkage());
|
|
|
|
|
|
#ifndef NDEBUG
|
|
#ifndef NDEBUG
|
|
- // In C (because of gnu inline) and in c++ with microsoft extensions an
|
|
|
|
- // static can follow an extern, so we can have two decls with different
|
|
|
|
- // linkages.
|
|
|
|
- const LangOptions &Opts = D->getASTContext().getLangOpts();
|
|
|
|
- if (!Opts.CPlusPlus || Opts.MicrosoftExt)
|
|
|
|
- return LV;
|
|
|
|
|
|
+ // In C (because of gnu inline) and in c++ with microsoft extensions an
|
|
|
|
+ // static can follow an extern, so we can have two decls with different
|
|
|
|
+ // linkages.
|
|
|
|
+ const LangOptions &Opts = D->getASTContext().getLangOpts();
|
|
|
|
+ if (!Opts.CPlusPlus || Opts.MicrosoftExt)
|
|
|
|
+ return LV;
|
|
|
|
|
|
- // We have just computed the linkage for this decl. By induction we know
|
|
|
|
- // that all other computed linkages match, check that the one we just
|
|
|
|
- // computed also does.
|
|
|
|
- NamedDecl *Old = nullptr;
|
|
|
|
- for (auto I : D->redecls()) {
|
|
|
|
- auto *T = cast<NamedDecl>(I);
|
|
|
|
- if (T == D)
|
|
|
|
- continue;
|
|
|
|
- if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
|
|
|
|
- Old = T;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ // We have just computed the linkage for this decl. By induction we know
|
|
|
|
+ // that all other computed linkages match, check that the one we just
|
|
|
|
+ // computed also does.
|
|
|
|
+ NamedDecl *Old = nullptr;
|
|
|
|
+ for (auto I : D->redecls()) {
|
|
|
|
+ auto *T = cast<NamedDecl>(I);
|
|
|
|
+ if (T == D)
|
|
|
|
+ continue;
|
|
|
|
+ if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
|
|
|
|
+ Old = T;
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
- assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage());
|
|
|
|
|
|
+ }
|
|
|
|
+ assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage());
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- return LV;
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
|
|
+ return LV;
|
|
}
|
|
}
|
|
|
|
|
|
-static LinkageInfo getLVForDecl(const NamedDecl *D,
|
|
|
|
- LVComputationKind computation) {
|
|
|
|
- return clang::LinkageComputer::getLVForDecl(D, computation);
|
|
|
|
|
|
+LinkageInfo LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) {
|
|
|
|
+ return getLVForDecl(D, usesTypeVisibility(D) ? LVForType : LVForValue);
|
|
}
|
|
}
|
|
|
|
|
|
void NamedDecl::printName(raw_ostream &os) const {
|
|
void NamedDecl::printName(raw_ostream &os) const {
|