diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-15 12:49:13 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-15 12:49:13 +0000 |
commit | 90cc390c4955029dd56d125af5512e68efa0c2b2 (patch) | |
tree | 3bf3b81e51818ea75a6b6258ceae15fd9f2e14f0 | |
parent | 72fdc8947e54be1a8dd36b03e24f112aba1241e1 (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.h | 4 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 11 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 25 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 3 |
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; } |