summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp45
-rw-r--r--clang/lib/Sema/SemaLookup.cpp26
2 files changed, 26 insertions, 45 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 042cffc8b4a..22803653edf 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1796,37 +1796,6 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
return New;
}
-/// \brief Filter out any previous declarations that the given declaration
-/// should not consider because they are not permitted to conflict, e.g.,
-/// because they come from hidden sub-modules and do not refer to the same
-/// entity.
-static void filterNonConflictingPreviousDecls(Sema &S,
- NamedDecl *decl,
- LookupResult &previous){
- // This is only interesting when modules are enabled.
- if ((!S.getLangOpts().Modules && !S.getLangOpts().ModulesLocalVisibility) ||
- !S.getLangOpts().ModulesHideInternalLinkage)
- return;
-
- // Empty sets are uninteresting.
- if (previous.empty())
- return;
-
- LookupResult::Filter filter = previous.makeFilter();
- while (filter.hasNext()) {
- NamedDecl *old = filter.next();
-
- // Non-hidden declarations are never ignored.
- if (S.isVisible(old))
- continue;
-
- if (!old->isExternallyVisible())
- filter.erase();
- }
-
- filter.done();
-}
-
/// Typedef declarations don't have linkage, but they still denote the same
/// entity if their types are the same.
/// FIXME: This is notionally doing the same thing as ASTReaderDecl's
@@ -4801,6 +4770,13 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
ForRedeclaration);
+ // If we're hiding internal-linkage symbols in modules from redeclaration
+ // lookup, let name lookup know.
+ if ((getLangOpts().Modules || getLangOpts().ModulesLocalVisibility) &&
+ getLangOpts().ModulesHideInternalLinkage &&
+ D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef)
+ Previous.setAllowHiddenInternal(false);
+
// See if this is a redefinition of a variable in the same scope.
if (!D.getCXXScopeSpec().isSet()) {
bool IsLinkageLookup = false;
@@ -6500,9 +6476,6 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) {
checkForConflictWithNonVisibleExternC(*this, NewVD, Previous))
Previous.setShadowed();
- // Filter out any non-conflicting previous declarations.
- filterNonConflictingPreviousDecls(*this, NewVD, Previous);
-
if (!Previous.empty()) {
MergeVarDecl(NewVD, Previous);
return true;
@@ -8058,9 +8031,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
bool MergeTypeWithPrevious = !getLangOpts().CPlusPlus &&
!Previous.isShadowed();
- // Filter out any non-conflicting previous declarations.
- filterNonConflictingPreviousDecls(*this, NewFD, Previous);
-
bool Redeclaration = false;
NamedDecl *OldDecl = nullptr;
@@ -8114,7 +8084,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// Check for a previous extern "C" declaration with this name.
if (!Redeclaration &&
checkForConflictWithNonVisibleExternC(*this, NewFD, Previous)) {
- filterNonConflictingPreviousDecls(*this, NewFD, Previous);
if (!Previous.empty()) {
// This is an extern "C" declaration with the same name as a previous
// declaration, and thus redeclares that entity...
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 3fd1f21ba3f..99b945597bc 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -378,7 +378,7 @@ void LookupResult::resolveKind() {
// Don't do any extra resolution if we've already resolved as ambiguous.
if (ResultKind == Ambiguous) return;
- llvm::SmallPtrSet<NamedDecl*, 16> Unique;
+ llvm::SmallDenseMap<NamedDecl*, unsigned, 16> Unique;
llvm::SmallPtrSet<QualType, 16> UniqueTypes;
bool Ambiguous = false;
@@ -414,14 +414,26 @@ void LookupResult::resolveKind() {
}
}
- if (!Unique.insert(D).second) {
+ auto UniqueResult = Unique.insert(std::make_pair(D, I));
+ if (!UniqueResult.second) {
// If it's not unique, pull something off the back (and
// continue at this index).
- // FIXME: This is wrong. We need to take the more recent declaration in
- // order to get the right type, default arguments, etc. We also need to
- // prefer visible declarations to hidden ones (for redeclaration lookup
- // in modules builds).
- Decls[I] = Decls[--N];
+ auto ExistingI = UniqueResult.first->second;
+ auto *Existing = Decls[ExistingI]->getUnderlyingDecl();
+ for (Decl *Prev = Decls[I]->getUnderlyingDecl()->getPreviousDecl(); /**/;
+ Prev = Prev->getPreviousDecl()) {
+ if (Prev == Existing) {
+ // Existing result is older. Replace it with the new one.
+ Decls[ExistingI] = Decls[I];
+ Decls[I] = Decls[--N];
+ break;
+ }
+ if (!Prev) {
+ // New decl is older. Keep the existing one.
+ Decls[I] = Decls[--N];
+ break;
+ }
+ }
continue;
}
OpenPOWER on IntegriCloud