Remove hasExternalLinkageUncached.

It was being used correctly, but it is a very dangerous API to have around.
Instead, move the logic from the filtering to when we are deciding if we should
link two decls.

llvm-svn: 179523
This commit is contained in:
Rafael Espindola 2013-04-15 12:49:13 +00:00
parent 7332acac4c
commit 5bddd6a92a
5 changed files with 23 additions and 24 deletions

View File

@ -219,10 +219,6 @@ public:
return getLinkage() == ExternalLinkage;
}
/// \brief True if this decl has external linkage. Don't cache the linkage,
/// because we are not finished setting up the redecl chain for the decl.
bool hasExternalLinkageUncached() const;
/// \brief Determines the visibility of this entity.
Visibility getVisibility() const {
return getLinkageAndVisibility().getVisibility();

View File

@ -203,6 +203,17 @@ class Sema {
static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD);
static bool
shouldLinkPossiblyHiddenDecl(const NamedDecl *Old, const NamedDecl *New) {
// We are about to link these. It is now safe to compute the linkage of
// the new decl. If the new decl has external linkage, we will
// link it with the hidden decl (which also has external linkage) and
// it will keep having external linkage. If it has internal linkage, we
// will not link it. Since it has no previous decls, it will remain
// with internal linkage.
return !Old->isHidden() || New->hasExternalLinkage();
}
public:
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
typedef OpaquePtr<TemplateName> TemplateTy;

View File

@ -866,10 +866,6 @@ bool NamedDecl::isLinkageValid() const {
Linkage(CachedLinkage);
}
bool NamedDecl::hasExternalLinkageUncached() const {
return getLVForDecl(this, LVForExplicitValue).getLinkage() == ExternalLinkage;
}
Linkage NamedDecl::getLinkage() const {
if (HasCachedLinkage)
return Linkage(CachedLinkage);

View File

@ -1613,20 +1613,7 @@ static void filterNonConflictingPreviousDecls(ASTContext &context,
if (!old->isHidden())
continue;
// If either has no-external linkage, ignore the old declaration.
// If this declaration would have external linkage if it were the first
// declaration of this name, then it may in fact be a redeclaration of
// some hidden declaration, so include those too. We don't need to worry
// about some previous visible declaration giving this declaration external
// linkage, because in that case, we'll mark this declaration as a redecl
// of the visible decl, and that decl will already be a redecl of the
// hidden declaration if that's appropriate.
//
// Don't cache this linkage computation, because it's not yet correct: we
// may later give this declaration a previous declaration which changes
// its linkage.
if (old->getLinkage() != ExternalLinkage ||
!decl->hasExternalLinkageUncached())
if (old->getLinkage() != ExternalLinkage)
filter.erase();
}
@ -2881,6 +2868,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
return New->setInvalidDecl();
}
if (!shouldLinkPossiblyHiddenDecl(Old, New))
return;
// C++ [class.mem]p1:
// A member shall not be declared twice in the member-specification [...]
//
@ -6687,8 +6677,11 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// there's no more work to do here; we'll just add the new
// function to the scope.
if (!AllowOverloadingOfFunction(Previous, Context)) {
Redeclaration = true;
OldDecl = Previous.getFoundDecl();
NamedDecl *Candidate = Previous.getFoundDecl();
if (shouldLinkPossiblyHiddenDecl(Candidate, NewFD)) {
Redeclaration = true;
OldDecl = Candidate;
}
} else {
switch (CheckOverload(S, NewFD, Previous, OldDecl,
/*NewIsUsingDecl*/ false)) {

View File

@ -940,6 +940,9 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
continue;
}
if (!shouldLinkPossiblyHiddenDecl(*I, New))
continue;
Match = *I;
return Ovl_Match;
}