Add a callback interface that allows interested parties to get notified whenever PCHReader deserializes a type or decl (and possibly other things in the future). Have PCHWriter implement these callbacks as noops and register to receive them if we're chaining PCHs. This will allow PCHWriter to track the IDs of these things, which it needs to write the dependent files. WIP
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108383 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index 670b6b8..3a53dee 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -80,7 +80,7 @@
if (!OS)
return 0;
- const PCHReader *Chain = CI.getInvocation().getFrontendOpts().ChainedPCH ?
+ PCHReader *Chain = CI.getInvocation().getFrontendOpts().ChainedPCH ?
CI.getPCHReader() : 0;
const char *isysroot = CI.getFrontendOpts().RelocatablePCH ?
Sysroot.c_str() : 0;
diff --git a/lib/Frontend/GeneratePCH.cpp b/lib/Frontend/GeneratePCH.cpp
index 9be103e..2f3df94 100644
--- a/lib/Frontend/GeneratePCH.cpp
+++ b/lib/Frontend/GeneratePCH.cpp
@@ -28,28 +28,28 @@
namespace {
class PCHGenerator : public SemaConsumer {
const Preprocessor &PP;
- const PCHReader *Chain;
const char *isysroot;
llvm::raw_ostream *Out;
Sema *SemaPtr;
MemorizeStatCalls *StatCalls; // owned by the FileManager
+ std::vector<unsigned char> Buffer;
+ llvm::BitstreamWriter Stream;
+ PCHWriter Writer;
public:
- explicit PCHGenerator(const Preprocessor &PP,
- const PCHReader *Chain,
- const char *isysroot,
- llvm::raw_ostream *Out);
+ PCHGenerator(const Preprocessor &PP, PCHReader *Chain,
+ const char *isysroot, llvm::raw_ostream *Out);
virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
virtual void HandleTranslationUnit(ASTContext &Ctx);
};
}
PCHGenerator::PCHGenerator(const Preprocessor &PP,
- const PCHReader *Chain,
+ PCHReader *Chain,
const char *isysroot,
llvm::raw_ostream *OS)
- : PP(PP), Chain(Chain), isysroot(isysroot), Out(OS), SemaPtr(0),
- StatCalls(0) {
+ : PP(PP), isysroot(isysroot), Out(OS), SemaPtr(0), StatCalls(0),
+ Stream(Buffer), Writer(Stream, Chain) {
// Install a stat() listener to keep track of all of the stat()
// calls.
@@ -61,25 +61,23 @@
if (PP.getDiagnostics().hasErrorOccurred())
return;
- // Write the PCH contents into a buffer
- std::vector<unsigned char> Buffer;
- llvm::BitstreamWriter Stream(Buffer);
- PCHWriter Writer(Stream);
-
// Emit the PCH file
assert(SemaPtr && "No Sema?");
- Writer.WritePCH(*SemaPtr, StatCalls, Chain, isysroot);
+ Writer.WritePCH(*SemaPtr, StatCalls, isysroot);
// Write the generated bitstream to "Out".
Out->write((char *)&Buffer.front(), Buffer.size());
// Make sure it hits disk now.
Out->flush();
+
+ // Free up some memory, in case the process is kept alive.
+ Buffer.clear();
}
ASTConsumer *clang::CreatePCHGenerator(const Preprocessor &PP,
llvm::raw_ostream *OS,
- const PCHReader *Chain,
+ PCHReader *Chain,
const char *isysroot) {
return new PCHGenerator(PP, Chain, isysroot, OS);
}
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 70a9a06..00aee49 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -13,6 +13,7 @@
#include "clang/Frontend/PCHReader.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/PCHDeserializationListener.h"
#include "clang/Frontend/Utils.h"
#include "../Sema/Sema.h" // FIXME: move Sema headers elsewhere
#include "clang/AST/ASTConsumer.h"
@@ -413,10 +414,10 @@
PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,
const char *isysroot)
- : Listener(new PCHValidator(PP, *this)), SourceMgr(PP.getSourceManager()),
- FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
- SemaObj(0), PP(&PP), Context(Context), StatCache(0), Consumer(0),
- IdentifierTableData(0), IdentifierLookupTable(0),
+ : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
+ SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
+ Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
+ StatCache(0), Consumer(0), IdentifierTableData(0), IdentifierLookupTable(0),
IdentifierOffsets(0),
MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
TotalSelectorsInMethodPool(0), SelectorOffsets(0),
@@ -432,8 +433,8 @@
PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
Diagnostic &Diags, const char *isysroot)
- : SourceMgr(SourceMgr), FileMgr(FileMgr), Diags(Diags),
- SemaObj(0), PP(0), Context(0), StatCache(0), Consumer(0),
+ : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
+ Diags(Diags), SemaObj(0), PP(0), Context(0), StatCache(0), Consumer(0),
IdentifierTableData(0), IdentifierLookupTable(0),
IdentifierOffsets(0),
MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
@@ -2629,6 +2630,8 @@
if (TypesLoaded[Index].isNull()) {
TypesLoaded[Index] = ReadTypeRecord(TypeOffsets[Index]);
TypesLoaded[Index]->setFromPCH();
+ if (DeserializationListener)
+ DeserializationListener->TypeRead(ID, TypesLoaded[Index]);
}
return TypesLoaded[Index].withFastQualifiers(FastQuals);
@@ -2675,8 +2678,11 @@
}
TranslationUnitDecl *PCHReader::GetTranslationUnitDecl() {
- if (!DeclsLoaded[0])
+ if (!DeclsLoaded[0]) {
ReadDeclRecord(DeclOffsets[0], 0);
+ if (DeserializationListener)
+ DeserializationListener->DeclRead(0, DeclsLoaded[0]);
+ }
return cast<TranslationUnitDecl>(DeclsLoaded[0]);
}
@@ -2691,8 +2697,11 @@
}
unsigned Index = ID - 1;
- if (!DeclsLoaded[Index])
+ if (!DeclsLoaded[Index]) {
ReadDeclRecord(DeclOffsets[Index], Index);
+ if (DeserializationListener)
+ DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
+ }
return DeclsLoaded[Index];
}
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index e863998..093c1e3 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -743,8 +743,7 @@
}
/// \brief Write the PCH metadata (e.g., i686-apple-darwin9).
-void PCHWriter::WriteMetadata(ASTContext &Context, const PCHReader *Chain,
- const char *isysroot) {
+void PCHWriter::WriteMetadata(ASTContext &Context, const char *isysroot) {
using namespace llvm;
// Metadata
@@ -2074,13 +2073,16 @@
SelectorOffsets[ID - 1] = Offset;
}
-PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
- : Stream(Stream), NextTypeID(pch::NUM_PREDEF_TYPE_IDS),
+PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream, PCHReader *Chain)
+ : Stream(Stream), Chain(Chain), NextTypeID(pch::NUM_PREDEF_TYPE_IDS),
CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0),
- NumLexicalDeclContexts(0), NumVisibleDeclContexts(0) { }
+ NumLexicalDeclContexts(0), NumVisibleDeclContexts(0) {
+ if (Chain)
+ Chain->setDeserializationListener(this);
+}
void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
- const PCHReader *Chain, const char *isysroot) {
+ const char *isysroot) {
// Emit the file header.
Stream.Emit((unsigned)'C', 8);
Stream.Emit((unsigned)'P', 8);
@@ -2090,7 +2092,7 @@
WriteBlockInfoBlock();
if (Chain)
- WritePCHChain(SemaRef, StatCalls, Chain, isysroot);
+ WritePCHChain(SemaRef, StatCalls, isysroot);
else
WritePCHCore(SemaRef, StatCalls, isysroot);
}
@@ -2164,7 +2166,7 @@
// Write the remaining PCH contents.
RecordData Record;
Stream.EnterSubblock(pch::PCH_BLOCK_ID, 5);
- WriteMetadata(Context, 0, isysroot);
+ WriteMetadata(Context, isysroot);
WriteLanguageOptions(Context.getLangOptions());
if (StatCalls && !isysroot)
WriteStatCache(*StatCalls);
@@ -2275,7 +2277,7 @@
}
void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
- const PCHReader *Chain, const char *isysroot) {
+ const char *isysroot) {
using namespace llvm;
ASTContext &Context = SemaRef.Context;
@@ -2284,7 +2286,7 @@
RecordData Record;
Stream.EnterSubblock(pch::PCH_BLOCK_ID, 5);
- WriteMetadata(Context, Chain, isysroot);
+ WriteMetadata(Context, isysroot);
// FIXME: StatCache
// FIXME: Source manager block
@@ -2737,3 +2739,10 @@
AddTypeRef(Base.getType(), Record);
AddSourceRange(Base.getSourceRange(), Record);
}
+
+void PCHWriter::TypeRead(pch::TypeID ID, QualType T) {
+}
+
+void PCHWriter::DeclRead(pch::DeclID ID, const Decl *D) {
+}
+