summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-08-20 23:35:55 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-08-20 23:35:55 +0000
commitd32ee89ea2c2eeb944a40a527fb7b621a51037ea (patch)
tree38377ceac05800b2e96eb075cf5beac01db255e0 /clang/lib/Serialization
parentb155b21195e1fe6a8dbda20b5b30d6dd8a127663 (diff)
downloadbcm5719-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.cpp67
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp5
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
OpenPOWER on IntegriCloud