diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-07-21 23:54:07 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-07-21 23:54:07 +0000 |
| commit | a534a31c5e73163eaa61560cd4e0c4c19bcbcfb1 (patch) | |
| tree | 7e27c06c168865d3d0d300b93a015c414ba38bcc /clang/lib/Serialization | |
| parent | 159e5ed9dc8f8107cbd32521e4e2436254f2b07e (diff) | |
| download | bcm5719-llvm-a534a31c5e73163eaa61560cd4e0c4c19bcbcfb1.tar.gz bcm5719-llvm-a534a31c5e73163eaa61560cd4e0c4c19bcbcfb1.zip | |
[modules] In C++, stop serializing and deserializing a list of declarations in
the identifier table. This is redundant, since the TU-scope lookups are also
serialized as part of the TU DeclContext, and wasteful in a number of ways. We
still emit the decls for PCH / preamble builds, since for those we want
identical results, not merely semantically equivalent ones.
llvm-svn: 242855
Diffstat (limited to 'clang/lib/Serialization')
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 19 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 43 |
2 files changed, 37 insertions, 25 deletions
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 |

