From 1476ed40ef6ef144937821da888c7e4d9ea0acd7 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Fri, 16 Jul 2010 16:36:56 +0000 Subject: [PATCH] Add a little more data to chained PCHs. WIP git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108528 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Frontend/PCHDeserializationListener.h | 3 + include/clang/Frontend/PCHWriter.h | 16 ++-- lib/Frontend/GeneratePCH.cpp | 5 +- lib/Frontend/PCHReader.cpp | 5 +- lib/Frontend/PCHWriter.cpp | 81 +++++++++++-------- 5 files changed, 69 insertions(+), 41 deletions(-) diff --git a/include/clang/Frontend/PCHDeserializationListener.h b/include/clang/Frontend/PCHDeserializationListener.h index c9b90e22c8..627ec497bd 100644 --- a/include/clang/Frontend/PCHDeserializationListener.h +++ b/include/clang/Frontend/PCHDeserializationListener.h @@ -27,7 +27,10 @@ protected: ~PCHDeserializationListener() {} public: + /// \brief A type was deserialized from the PCH. The ID here has the qualifier + /// bits already removed, and T is guaranteed to be locally unqualified virtual void TypeRead(pch::TypeID ID, QualType T) = 0; + /// \brief A decl was deserialized from the PCH. virtual void DeclRead(pch::DeclID ID, const Decl *D) = 0; }; diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index 70ad1d7c7e..f2f3ed4a91 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -106,12 +106,15 @@ private: void *Stored; bool IsType; }; - + /// \brief The declarations and types to emit. std::queue DeclTypesToEmit; - + + /// \brief The first ID number we can use for our own declarations. + pch::DeclID FirstDeclID; + /// \brief Map that provides the ID numbers of each declaration within - /// the output stream. + /// the output stream, as well as those deserialized from a chained PCH. /// /// The ID numbers of declarations are consecutive (in order of /// discovery) and start at 2. 1 is reserved for the translation @@ -122,8 +125,11 @@ private: /// the declaration's ID. std::vector DeclOffsets; + /// \brief The first ID number we can use for our own types. + pch::TypeID FirstTypeID; + /// \brief Map that provides the ID numbers of each type within the - /// output stream. + /// output stream, plus those deserialized from a chained PCH. /// /// The ID numbers of types are consecutive (in order of discovery) /// and start at 1. 0 is reserved for NULL. When types are actually @@ -234,7 +240,7 @@ private: void WriteType(QualType T); uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC); - + void WriteTypeDeclOffsets(); void WriteMethodPool(Sema &SemaRef); void WriteIdentifierTable(Preprocessor &PP); void WriteAttributeRecord(const Attr *Attr); diff --git a/lib/Frontend/GeneratePCH.cpp b/lib/Frontend/GeneratePCH.cpp index 2f3df9479d..422a4b6264 100644 --- a/lib/Frontend/GeneratePCH.cpp +++ b/lib/Frontend/GeneratePCH.cpp @@ -54,7 +54,10 @@ PCHGenerator::PCHGenerator(const Preprocessor &PP, // Install a stat() listener to keep track of all of the stat() // calls. StatCalls = new MemorizeStatCalls; - PP.getFileManager().addStatCache(StatCalls, /*AtBeginning=*/true); + // If we have a chain, we want new stat calls only, so install the memorizer + // *after* the already installed PCHReader's stat cache. + PP.getFileManager().addStatCache(StatCalls, + /*AtBeginning=*/!Chain); } void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 9c132f40eb..c0ad12f699 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -2632,7 +2632,8 @@ QualType PCHReader::GetType(pch::TypeID ID) { TypesLoaded[Index] = ReadTypeRecord(TypeOffsets[Index]); TypesLoaded[Index]->setFromPCH(); if (DeserializationListener) - DeserializationListener->TypeRead(ID, TypesLoaded[Index]); + DeserializationListener->TypeRead(ID >> Qualifiers::FastWidth, + TypesLoaded[Index]); } return TypesLoaded[Index].withFastQualifiers(FastQuals); @@ -2682,7 +2683,7 @@ TranslationUnitDecl *PCHReader::GetTranslationUnitDecl() { if (!DeclsLoaded[0]) { ReadDeclRecord(DeclOffsets[0], 0); if (DeserializationListener) - DeserializationListener->DeclRead(0, DeclsLoaded[0]); + DeserializationListener->DeclRead(1, DeclsLoaded[0]); } return cast(DeclsLoaded[0]); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 093c1e334a..d8ce4e3b6e 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -1501,6 +1501,37 @@ uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context, return Offset; } +void PCHWriter::WriteTypeDeclOffsets() { + using namespace llvm; + RecordData Record; + + // Write the type offsets array + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(pch::TYPE_OFFSET)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block + unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev); + Record.clear(); + Record.push_back(pch::TYPE_OFFSET); + Record.push_back(TypeOffsets.size()); + Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, + (const char *)&TypeOffsets.front(), + TypeOffsets.size() * sizeof(TypeOffsets[0])); + + // Write the declaration offsets array + Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(pch::DECL_OFFSET)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block + unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev); + Record.clear(); + Record.push_back(pch::DECL_OFFSET); + Record.push_back(DeclOffsets.size()); + Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, + (const char *)&DeclOffsets.front(), + DeclOffsets.size() * sizeof(DeclOffsets[0])); +} + //===----------------------------------------------------------------------===// // Global Method Pool and Selector Serialization //===----------------------------------------------------------------------===// @@ -2074,11 +2105,16 @@ void PCHWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { } PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream, PCHReader *Chain) - : Stream(Stream), Chain(Chain), NextTypeID(pch::NUM_PREDEF_TYPE_IDS), + : Stream(Stream), Chain(Chain), FirstDeclID(1), + FirstTypeID(pch::NUM_PREDEF_TYPE_IDS), CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), NumVisibleDeclContexts(0) { - if (Chain) + if (Chain) { Chain->setDeserializationListener(this); + FirstDeclID += Chain->getTotalNumDecls(); + FirstTypeID += Chain->getTotalNumTypes(); + } + NextTypeID = FirstTypeID; } void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls, @@ -2211,31 +2247,7 @@ void PCHWriter::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, WriteMethodPool(SemaRef); WriteIdentifierTable(PP); - // Write the type offsets array - BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); - Abbrev->Add(BitCodeAbbrevOp(pch::TYPE_OFFSET)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block - unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbrev); - Record.clear(); - Record.push_back(pch::TYPE_OFFSET); - Record.push_back(TypeOffsets.size()); - Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, - (const char *)&TypeOffsets.front(), - TypeOffsets.size() * sizeof(TypeOffsets[0])); - - // Write the declaration offsets array - Abbrev = new BitCodeAbbrev(); - Abbrev->Add(BitCodeAbbrevOp(pch::DECL_OFFSET)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block - unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbrev); - Record.clear(); - Record.push_back(pch::DECL_OFFSET); - Record.push_back(DeclOffsets.size()); - Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, - (const char *)&DeclOffsets.front(), - DeclOffsets.size() * sizeof(DeclOffsets[0])); + WriteTypeDeclOffsets(); // Write the record containing external, unnamed definitions. if (!ExternalDefinitions.empty()) @@ -2283,12 +2295,15 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, ASTContext &Context = SemaRef.Context; Preprocessor &PP = SemaRef.PP; (void)PP; - + RecordData Record; Stream.EnterSubblock(pch::PCH_BLOCK_ID, 5); WriteMetadata(Context, isysroot); - // FIXME: StatCache - // FIXME: Source manager block + if (StatCalls && !isysroot) + WriteStatCache(*StatCalls); + // FIXME: Source manager block should only write new stuff, which could be + // done by tracking the largest ID in the chain + WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); // The special types are in the chained PCH. @@ -2302,7 +2317,6 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, for (DeclContext::decl_iterator I = TU->decls_begin(), E = TU->decls_end(); I != E; ++I) { if ((*I)->getPCHLevel() == 0) { - (*I)->dump(); DeclTypesToEmit.push(*I); } } @@ -2322,8 +2336,7 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, // FIXME: Preprocessor // FIXME: Method pool // FIXME: Identifier table - // FIXME: Type offsets - // FIXME: Declaration offsets + WriteTypeDeclOffsets(); // FIXME: External unnamed definitions // FIXME: Tentative definitions // FIXME: Unused static functions @@ -2741,8 +2754,10 @@ void PCHWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, } void PCHWriter::TypeRead(pch::TypeID ID, QualType T) { + TypeIDs[T] = ID; } void PCHWriter::DeclRead(pch::DeclID ID, const Decl *D) { + DeclIDs[D] = ID; }