diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 45 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 26 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 19 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 43 |
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 |

