diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-08-24 00:50:09 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-08-24 00:50:09 +0000 |
commit | 1d1e42b17da6a53391d50b08068ecde04311e368 (patch) | |
tree | c519cdc29c2ce590b0aa7f5e73c9aa1ccbd12799 /lib/Serialization/ASTWriter.cpp | |
parent | e1dde811b38e779894150cb1093d57f8411a84f7 (diff) |
Write visible update blocks. No regressions in normal PCH functionality, but no tests for the chain yet.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111881 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index f47ad3c4d7..dc9f4d409a 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2013,7 +2013,7 @@ public: /// visible from the given DeclContext. /// /// \returns the offset of the DECL_CONTEXT_VISIBLE block within the -/// bistream, or 0 if no block was written. +/// bitstream, or 0 if no block was written. uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC) { if (DC->getPrimaryContext() != DC) @@ -2080,6 +2080,64 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, return Offset; } +/// \brief Write an UPDATE_VISIBLE block for the given context. +/// +/// UPDATE_VISIBLE blocks contain the declarations that are added to an existing +/// DeclContext in a dependent AST file. As such, they only exist for the TU +/// (in C++) and for namespaces. +void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { + assert((DC->isTranslationUnit() || DC->isNamespace()) && + "Only TU and namespaces should have visible decl updates."); + + // Make the context build its lookup table, but don't make it load external + // decls. + DC->lookup(DeclarationName()); + + StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr()); + if (!Map || Map->empty()) + return; + + OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator; + ASTDeclContextNameLookupTrait Trait(*this); + + // Create the hash table. + llvm::SmallVector<NamedDecl *, 16> Decls; + for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end(); + D != DEnd; ++D) { + DeclarationName Name = D->first; + DeclContext::lookup_result Result = D->second.getLookupResult(); + // Need to filter these results to only include decls that are not from + // an existing PCH. + Decls.clear(); + for (; Result.first != Result.second; ++Result.first) { + if ((*Result.first)->getPCHLevel() == 0) + Decls.push_back(*Result.first); + } + if (!Decls.empty()) { + Result.first = Decls.data(); + Result.second = Result.first + Decls.size(); + Generator.insert(Name, Result, Trait); + } + } + + // Create the on-disk hash table in a buffer. + llvm::SmallString<4096> LookupTable; + uint32_t BucketOffset; + { + llvm::raw_svector_ostream Out(LookupTable); + // Make sure that no bucket is at offset 0 + clang::io::Emit32(Out, 0); + BucketOffset = Generator.Emit(Out, Trait); + } + + // Write the lookup table + RecordData Record; + Record.push_back(UPDATE_VISIBLE); + Record.push_back(getDeclID(cast<Decl>(DC))); + Record.push_back(BucketOffset); + Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str()); +} + //===----------------------------------------------------------------------===// // General Serialization Routines //===----------------------------------------------------------------------===// @@ -2406,6 +2464,16 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, reinterpret_cast<const char*>(NewGlobalDecls.data()), NewGlobalDecls.size() * sizeof(DeclID)); + // And in C++, a visible updates block for the TU. + if (Context.getLangOptions().CPlusPlus) { + Abv = new llvm::BitCodeAbbrev(); + Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); + UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv); + WriteDeclContextVisibleUpdate(TU); + } // Build a record containing all of the new tentative definitions in this // file, in TentativeDefinitions order. @@ -2572,6 +2640,13 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, if (!SemaDeclRefs.empty()) Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); + // Write the updates to C++ namespaces. + for (llvm::SmallPtrSet<const NamespaceDecl *, 16>::iterator + I = UpdatedNamespaces.begin(), + E = UpdatedNamespaces.end(); + I != E; ++I) + WriteDeclContextVisibleUpdate(*I); + Record.clear(); Record.push_back(NumStatements); Record.push_back(NumMacros); |