diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-20 23:35:55 +0000 |
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-08-20 23:35:55 +0000 |
| commit | d32ee89ea2c2eeb944a40a527fb7b621a51037ea (patch) | |
| tree | 38377ceac05800b2e96eb075cf5beac01db255e0 /clang/lib/Serialization | |
| parent | b155b21195e1fe6a8dbda20b5b30d6dd8a127663 (diff) | |
| download | bcm5719-llvm-d32ee89ea2c2eeb944a40a527fb7b621a51037ea.tar.gz bcm5719-llvm-d32ee89ea2c2eeb944a40a527fb7b621a51037ea.zip | |
Fix an issue with writing to PCH another included PCH, introduced by the "using an AST on-disk hash table for name lookup" commit.
When including a PCH and later re-emitting to another PCH, the name lookup tables of DeclContexts
may be incomplete, since we now lazily deserialize the visible decls of a particular name.
Fix the issue by iterating over the un-deserialized visible decls and completing the lookup tables
of DeclContexts before writing them out.
llvm-svn: 111698
Diffstat (limited to 'clang/lib/Serialization')
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 67 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 5 |
2 files changed, 71 insertions, 1 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index b24b35309a6..6e5638b3c86 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -790,6 +790,44 @@ public: return Key; } + external_key_type GetExternalKey(const internal_key_type& Key) const { + ASTContext *Context = Reader.getContext(); + switch (Key.Kind) { + case DeclarationName::Identifier: + return DeclarationName((IdentifierInfo*)Key.Data); + + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + return DeclarationName(Selector(Key.Data)); + + case DeclarationName::CXXConstructorName: + return Context->DeclarationNames.getCXXConstructorName( + Context->getCanonicalType(Reader.GetType(Key.Data))); + + case DeclarationName::CXXDestructorName: + return Context->DeclarationNames.getCXXDestructorName( + Context->getCanonicalType(Reader.GetType(Key.Data))); + + case DeclarationName::CXXConversionFunctionName: + return Context->DeclarationNames.getCXXConversionFunctionName( + Context->getCanonicalType(Reader.GetType(Key.Data))); + + case DeclarationName::CXXOperatorName: + return Context->DeclarationNames.getCXXOperatorName( + (OverloadedOperatorKind)Key.Data); + + case DeclarationName::CXXLiteralOperatorName: + return Context->DeclarationNames.getCXXLiteralOperatorName( + (IdentifierInfo*)Key.Data); + + case DeclarationName::CXXUsingDirective: + return DeclarationName::getUsingDirectiveName(); + } + + llvm_unreachable("Invalid Name Kind ?"); + } + static std::pair<unsigned, unsigned> ReadKeyDataLength(const unsigned char*& d) { using namespace clang::io; @@ -3197,6 +3235,35 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, return const_cast<DeclContext*>(DC)->lookup(Name); } +void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) { + assert(DC->hasExternalVisibleStorage() && + "DeclContext has no visible decls in storage"); + + llvm::SmallVector<NamedDecl *, 64> Decls; + // There might be visible decls in multiple parts of the chain, for the TU + // and namespaces. + DeclContextInfos &Infos = DeclContextOffsets[DC]; + for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end(); + I != E; ++I) { + if (!I->NameLookupTableData) + continue; + + ASTDeclContextNameLookupTable *LookupTable = + (ASTDeclContextNameLookupTable*)I->NameLookupTableData; + for (ASTDeclContextNameLookupTable::item_iterator + ItemI = LookupTable->item_begin(), + ItemEnd = LookupTable->item_end() ; ItemI != ItemEnd; ++ItemI) { + ASTDeclContextNameLookupTable::item_iterator::value_type Val + = *ItemI; + ASTDeclContextNameLookupTrait::data_type Data = Val.second; + Decls.clear(); + for (; Data.first != Data.second; ++Data.first) + Decls.push_back(cast<NamedDecl>(GetDecl(*Data.first))); + MaterializeVisibleDeclsForName(DC, Val.first, Decls); + } + } +} + void ASTReader::PassInterestingDeclsToConsumer() { assert(Consumer); while (!InterestingDecls.empty()) { diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 5deaf3d475d..f47ad3c4d74 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2032,7 +2032,10 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, return 0; // Force the DeclContext to build a its name-lookup table. - DC->lookup(DeclarationName()); + if (DC->hasExternalVisibleStorage()) + DC->MaterializeVisibleDeclsFromExternalStorage(); + else + DC->lookup(DeclarationName()); // Serialize the contents of the mapping used for lookup. Note that, // although we have two very different code paths, the serialized |

