aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-04-15 12:49:13 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-04-15 12:49:13 +0000
commit90cc390c4955029dd56d125af5512e68efa0c2b2 (patch)
tree3bf3b81e51818ea75a6b6258ceae15fd9f2e14f0
parent72fdc8947e54be1a8dd36b03e24f112aba1241e1 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179523 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Decl.h4
-rw-r--r--include/clang/Sema/Sema.h11
-rw-r--r--lib/AST/Decl.cpp4
-rw-r--r--lib/Sema/SemaDecl.cpp25
-rw-r--r--lib/Sema/SemaOverload.cpp3
5 files changed, 23 insertions, 24 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index f0832dc7bf..4260ab0bb2 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -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();
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 9e9fda791f..67dacfc8c7 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -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;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index bf807aeb1d..9505d299ab 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -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);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9b3083a4ec..a17e9d0cda 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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)) {
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 22b2a4a57d..dec4938622 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -940,6 +940,9 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
continue;
}
+ if (!shouldLinkPossiblyHiddenDecl(*I, New))
+ continue;
+
Match = *I;
return Ovl_Match;
}