summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp45
-rw-r--r--clang/lib/Sema/SemaLookup.cpp26
-rw-r--r--clang/lib/Serialization/ASTReader.cpp19
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp43
4 files changed, 63 insertions, 70 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;
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 1f47f57f41a..cddbd62eb63 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -735,12 +735,14 @@ ASTIdentifierLookupTraitBase::ReadKey(const unsigned char* d, unsigned n) {
}
/// \brief Whether the given identifier is "interesting".
-static bool isInterestingIdentifier(IdentifierInfo &II, bool IsModule) {
+static bool isInterestingIdentifier(ASTReader &Reader, IdentifierInfo &II,
+ bool IsModule) {
return II.hadMacroDefinition() ||
II.isPoisoned() ||
(IsModule ? II.hasRevertedBuiltin() : II.getObjCOrBuiltinID()) ||
II.hasRevertedTokenIDToIdentifier() ||
- II.getFETokenInfo<void>();
+ (!(IsModule && Reader.getContext().getLangOpts().CPlusPlus) &&
+ II.getFETokenInfo<void>());
}
static bool readBit(unsigned &Bits) {
@@ -767,7 +769,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
}
if (!II->isFromAST()) {
II->setIsFromAST();
- if (isInterestingIdentifier(*II, F.isModule()))
+ if (isInterestingIdentifier(Reader, *II, F.isModule()))
II->setChangedSinceDeserialization();
}
Reader.markIdentifierUpToDate(II);
@@ -5883,10 +5885,13 @@ void ASTReader::CompleteRedeclChain(const Decl *D) {
if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC) ||
isa<CXXRecordDecl>(DC) || isa<EnumDecl>(DC)) {
if (DeclarationName Name = cast<NamedDecl>(D)->getDeclName()) {
- auto *II = Name.getAsIdentifierInfo();
- if (isa<TranslationUnitDecl>(DC) && II) {
+ if (!getContext().getLangOpts().CPlusPlus &&
+ isa<TranslationUnitDecl>(DC)) {
// Outside of C++, we don't have a lookup table for the TU, so update
- // the identifier instead. In C++, either way should work fine.
+ // the identifier instead. (For C++ modules, we don't store decls
+ // in the serialized identifier table, so we do the lookup in the TU.)
+ auto *II = Name.getAsIdentifierInfo();
+ assert(II && "non-identifier name in C?");
if (II->isOutOfDate())
updateOutOfDateIdentifier(*II);
} else
@@ -8443,7 +8448,7 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
// Remove any fake results before adding any real ones.
auto It = PendingFakeLookupResults.find(II);
if (It != PendingFakeLookupResults.end()) {
- for (auto *ND : PendingFakeLookupResults[II])
+ for (auto *ND : It->second)
SemaObj->IdResolver.RemoveDecl(ND);
// FIXME: this works around module+PCH performance issue.
// Rather than erase the result from the map, which is O(n), just clear
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 1c08cbf53a7..ba42cd3173d 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -3103,6 +3103,7 @@ class ASTIdentifierTableTrait {
Preprocessor &PP;
IdentifierResolver &IdResolver;
bool IsModule;
+ bool NeedDecls;
/// \brief Determines whether this is an "interesting" identifier that needs a
/// full IdentifierInfo structure written into the hash table. Notably, this
@@ -3113,7 +3114,7 @@ class ASTIdentifierTableTrait {
II->isPoisoned() ||
(IsModule ? II->hasRevertedBuiltin() : II->getObjCOrBuiltinID()) ||
II->hasRevertedTokenIDToIdentifier() ||
- II->getFETokenInfo<void>())
+ (NeedDecls && II->getFETokenInfo<void>()))
return true;
return false;
@@ -3131,7 +3132,8 @@ public:
ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP,
IdentifierResolver &IdResolver, bool IsModule)
- : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule) {}
+ : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule),
+ NeedDecls(!IsModule || !Writer.getLangOpts().CPlusPlus) {}
static hash_value_type ComputeHash(const IdentifierInfo* II) {
return llvm::HashString(II->getName());
@@ -3152,10 +3154,12 @@ public:
if (MacroOffset)
DataLen += 4; // MacroDirectives offset.
- for (IdentifierResolver::iterator D = IdResolver.begin(II),
- DEnd = IdResolver.end();
- D != DEnd; ++D)
- DataLen += 4;
+ if (NeedDecls) {
+ for (IdentifierResolver::iterator D = IdResolver.begin(II),
+ DEnd = IdResolver.end();
+ D != DEnd; ++D)
+ DataLen += 4;
+ }
}
using namespace llvm::support;
endian::Writer<little> LE(Out);
@@ -3205,18 +3209,21 @@ public:
if (HadMacroDefinition)
LE.write<uint32_t>(MacroOffset);
- // Emit the declaration IDs in reverse order, because the
- // IdentifierResolver provides the declarations as they would be
- // visible (e.g., the function "stat" would come before the struct
- // "stat"), but the ASTReader adds declarations to the end of the list
- // (so we need to see the struct "stat" before the function "stat").
- // Only emit declarations that aren't from a chained PCH, though.
- SmallVector<NamedDecl *, 16> Decls(IdResolver.begin(II), IdResolver.end());
- for (SmallVectorImpl<NamedDecl *>::reverse_iterator D = Decls.rbegin(),
- DEnd = Decls.rend();
- D != DEnd; ++D)
- LE.write<uint32_t>(
- Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), *D)));
+ if (NeedDecls) {
+ // Emit the declaration IDs in reverse order, because the
+ // IdentifierResolver provides the declarations as they would be
+ // visible (e.g., the function "stat" would come before the struct
+ // "stat"), but the ASTReader adds declarations to the end of the list
+ // (so we need to see the struct "stat" before the function "stat").
+ // Only emit declarations that aren't from a chained PCH, though.
+ SmallVector<NamedDecl *, 16> Decls(IdResolver.begin(II),
+ IdResolver.end());
+ for (SmallVectorImpl<NamedDecl *>::reverse_iterator D = Decls.rbegin(),
+ DEnd = Decls.rend();
+ D != DEnd; ++D)
+ LE.write<uint32_t>(
+ Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), *D)));
+ }
}
};
} // end anonymous namespace
OpenPOWER on IntegriCloud