]> granicus.if.org Git - clang/commitdiff
Add a callback interface that allows interested parties to get notified whenever...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 14 Jul 2010 23:45:08 +0000 (23:45 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 14 Jul 2010 23:45:08 +0000 (23:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108383 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/ASTConsumers.h
include/clang/Frontend/PCHDeserializationListener.h [new file with mode: 0644]
include/clang/Frontend/PCHReader.h
include/clang/Frontend/PCHWriter.h
lib/Frontend/FrontendActions.cpp
lib/Frontend/GeneratePCH.cpp
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp

index 5718979ba1db0ae05481c33fab6a897ed8383f74..2d1df44cc968afd6a97f7f5a7baa0ab37d21a3f2 100644 (file)
@@ -63,7 +63,7 @@ ASTConsumer *CreateDeclContextPrinter();
 // times.
 ASTConsumer *CreatePCHGenerator(const Preprocessor &PP,
                                 llvm::raw_ostream *OS,
-                                const PCHReader *Chain,
+                                PCHReader *Chain,
                                 const char *isysroot = 0);
 
 // Inheritance viewer: for C++ code, creates a graph of the inheritance
diff --git a/include/clang/Frontend/PCHDeserializationListener.h b/include/clang/Frontend/PCHDeserializationListener.h
new file mode 100644 (file)
index 0000000..c9b90e2
--- /dev/null
@@ -0,0 +1,36 @@
+//===- PCHDeserializationListener.h - Decl/Type PCH Read Events -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the PCHDeserializationListener class, which is notified
+//  by the PCHReader whenever a type or declaration is deserialized.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_PCH_DESERIALIZATION_LISTENER_H
+#define LLVM_CLANG_FRONTEND_PCH_DESERIALIZATION_LISTENER_H
+
+#include "clang/Frontend/PCHBitCodes.h"
+
+namespace clang {
+
+class Decl;
+class QualType;
+
+class PCHDeserializationListener {
+protected:
+  ~PCHDeserializationListener() {}
+
+public:
+  virtual void TypeRead(pch::TypeID ID, QualType T) = 0;
+  virtual void DeclRead(pch::DeclID ID, const Decl *D) = 0;
+};
+
+}
+
+#endif
index 41322061b17259078a3877a150112b22fc7001d6..47e871f50aeba9405979da487ba4b2e8afb32337 100644 (file)
@@ -59,6 +59,7 @@ class GotoStmt;
 class LabelStmt;
 class MacroDefinition;
 class NamedDecl;
+class PCHDeserializationListener;
 class Preprocessor;
 class Sema;
 class SwitchCase;
@@ -100,10 +101,7 @@ public:
 
   /// \brief Receives the contents of the predefines buffer.
   ///
-  /// \param PCHPredef The start of the predefines buffer in the PCH
-  /// file.
-  ///
-  /// \param PCHBufferID The FileID for the PCH predefines buffer.
+  /// \param Buffers Information about the predefines buffers.
   ///
   /// \param OriginalFileName The original file name for the PCH, which will
   /// appear as an entry in the predefines buffer.
@@ -172,9 +170,12 @@ public:
   enum PCHReadResult { Success, Failure, IgnorePCH };
   friend class PCHValidator;
 private:
-  /// \ brief The receiver of some callbacks invoked by PCHReader.
+  /// \brief The receiver of some callbacks invoked by PCHReader.
   llvm::OwningPtr<PCHReaderListener> Listener;
 
+  /// \brief The receiver of deserialization events.
+  PCHDeserializationListener *DeserializationListener;
+
   SourceManager &SourceMgr;
   FileManager &FileMgr;
   Diagnostic &Diags;
@@ -577,6 +578,10 @@ public:
     Listener.reset(listener);
   }
 
+  void setDeserializationListener(PCHDeserializationListener *Listener) {
+    DeserializationListener = Listener;
+  }
+
   /// \brief Set the Preprocessor to use.
   void setPreprocessor(Preprocessor &pp);
 
index 860ef56a58ffb8620cd77780668e06f809aa7528..70ad1d7c7e78ae5ae23577b79fbb5b43535cb00d 100644 (file)
@@ -19,6 +19,7 @@
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/Frontend/PCHBitCodes.h"
+#include "clang/Frontend/PCHDeserializationListener.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include <map>
@@ -71,7 +72,7 @@ struct UnsafeQualTypeDenseMapInfo {
 /// representation of a given abstract syntax tree and its supporting
 /// data structures. This bitstream can be de-serialized via an
 /// instance of the PCHReader class.
-class PCHWriter {
+class PCHWriter : public PCHDeserializationListener {
 public:
   typedef llvm::SmallVector<uint64_t, 64> RecordData;
 
@@ -79,6 +80,9 @@ private:
   /// \brief The bitstream writer used to emit this precompiled header.
   llvm::BitstreamWriter &Stream;
 
+  /// \brief The reader of existing PCH files, if we're chaining.
+  PCHReader *Chain;
+
   /// \brief Stores a declaration or a type to be written to the PCH file.
   class DeclOrType {
   public:
@@ -220,7 +224,7 @@ private:
   void WriteSubStmt(Stmt *S);
 
   void WriteBlockInfoBlock();
-  void WriteMetadata(ASTContext &Context, const PCHReader *Chain, const char *isysroot);
+  void WriteMetadata(ASTContext &Context, const char *isysroot);
   void WriteLanguageOptions(const LangOptions &LangOpts);
   void WriteStatCache(MemorizeStatCalls &StatCalls);
   void WriteSourceManagerBlock(SourceManager &SourceMgr,
@@ -242,12 +246,12 @@ private:
   void WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
                     const char* isysroot);
   void WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
-                     const PCHReader *Chain, const char* isysroot);
+                     const char* isysroot);
   
 public:
   /// \brief Create a new precompiled header writer that outputs to
   /// the given bitstream.
-  PCHWriter(llvm::BitstreamWriter &Stream);
+  PCHWriter(llvm::BitstreamWriter &Stream, PCHReader *Chain);
 
   /// \brief Write a precompiled header for the given semantic analysis.
   ///
@@ -263,7 +267,7 @@ public:
   /// \param PPRec Record of the preprocessing actions that occurred while
   /// preprocessing this file, e.g., macro instantiations
   void WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
-                const PCHReader *Chain, const char* isysroot);
+                const char* isysroot);
 
   /// \brief Emit a source location.
   void AddSourceLocation(SourceLocation Loc, RecordData &Record);
@@ -393,6 +397,10 @@ public:
   unsigned GetLabelID(LabelStmt *S);
 
   unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; }
+
+  // PCHDeserializationListener implementation
+  void TypeRead(pch::TypeID ID, QualType T);
+  void DeclRead(pch::DeclID ID, const Decl *D);
 };
 
 } // end namespace clang
index 670b6b8cead75fcc128e81a7101930d7f1aa7faf..3a53dee806148219f6a4ff5ad6ab9bd1d768109a 100644 (file)
@@ -80,7 +80,7 @@ ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
   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;
index 9be103e06eb0bc13c566ebceeefd091a8555f343..2f3df9479d934eac261637ec9a1b2f687f867d4a 100644 (file)
@@ -28,28 +28,28 @@ using namespace clang;
 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 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
   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);
 }
index 70a9a068e6193f3fe172792d012d43b96cc73fec..00aee491d644753f808ae74a08ad476ccdfd1b85 100644 (file)
@@ -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 @@ void PCHValidator::ReadCounter(unsigned Value) {
 
 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(Preprocessor &PP, ASTContext *Context,
 
 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 @@ QualType PCHReader::GetType(pch::TypeID ID) {
   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 @@ Decl *PCHReader::GetExternalDecl(uint32_t ID) {
 }
 
 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 @@ Decl *PCHReader::GetDecl(pch::DeclID ID) {
   }
 
   unsigned Index = ID - 1;
-  if (!DeclsLoaded[Index])
+  if (!DeclsLoaded[Index]) {
     ReadDeclRecord(DeclOffsets[Index], Index);
+    if (DeserializationListener)
+      DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
+  }
 
   return DeclsLoaded[Index];
 }
index e86399886c0b3a994b4719f07d1bbc5bcff3470b..093c1e334a3db2878fb9beed212c70ad7bc798b0 100644 (file)
@@ -743,8 +743,7 @@ adjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) {
 }
 
 /// \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 @@ void PCHWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
   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 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
   WriteBlockInfoBlock();
 
   if (Chain)
-    WritePCHChain(SemaRef, StatCalls, Chain, isysroot);
+    WritePCHChain(SemaRef, StatCalls, isysroot);
   else
     WritePCHCore(SemaRef, StatCalls, isysroot);
 }
@@ -2164,7 +2166,7 @@ void PCHWriter::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
   // 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::WritePCHCore(Sema &SemaRef, MemorizeStatCalls *StatCalls,
 }
 
 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 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
   
   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 @@ void PCHWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
   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) {
+}
+