[cfe-commits] r117235 - in /cfe/trunk: include/clang/AST/ include/clang/Serialization/ lib/AST/ lib/Frontend/ lib/Serialization/

Argyrios Kyrtzidis akyrtzi at gmail.com
Sun Oct 24 10:26:37 PDT 2010


Author: akirtzidis
Date: Sun Oct 24 12:26:36 2010
New Revision: 117235

URL: http://llvm.org/viewvc/llvm-project?rev=117235&view=rev
Log:
Put the mechanism in place to track modifications in an AST entity that were committed after
its initial creation/deserialization and store the changes in a chained PCH.

The idea is that the AST entities call methods on the ASTMutationListener to give notifications
of changes; the PCHWriter implements the ASTMutationListener interface and stores the incremental changes
of the updated entity. WIP

Added:
    cfe/trunk/include/clang/AST/ASTMutationListener.h
Modified:
    cfe/trunk/include/clang/AST/ASTConsumer.h
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Frontend/FrontendAction.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/GeneratePCH.cpp

Modified: cfe/trunk/include/clang/AST/ASTConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTConsumer.h?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTConsumer.h (original)
+++ cfe/trunk/include/clang/AST/ASTConsumer.h Sun Oct 24 12:26:36 2010
@@ -19,6 +19,7 @@
   class CXXRecordDecl;
   class DeclGroupRef;
   class HandleTagDeclDefinition;
+  class ASTMutationListener;
   class ASTDeserializationListener; // layering violation because void* is ugly
   class SemaConsumer; // layering violation required for safe SemaConsumer
   class TagDecl;
@@ -86,10 +87,13 @@
   /// it was actually used.
   virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
 
+  /// \brief If the consumer is interested in entities getting modified after
+  /// their initial creation, it should return a pointer to
+  /// a GetASTMutationListener here.
+  virtual ASTMutationListener *GetASTMutationListener() { return 0; }
+
   /// \brief If the consumer is interested in entities being deserialized from
   /// AST files, it should return a pointer to a ASTDeserializationListener here
-  ///
-  /// The return type is void* because ASTDS lives in Frontend.
   virtual ASTDeserializationListener *GetASTDeserializationListener() { return 0; }
 
   /// PrintStats - If desired, print any statistics.

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sun Oct 24 12:26:36 2010
@@ -45,6 +45,7 @@
   class Diagnostic;
   class Expr;
   class ExternalASTSource;
+  class ASTMutationListener;
   class IdentifierTable;
   class SelectorTable;
   class SourceManager;
@@ -297,6 +298,7 @@
   Builtin::Context &BuiltinInfo;
   DeclarationNameTable DeclarationNames;
   llvm::OwningPtr<ExternalASTSource> ExternalSource;
+  ASTMutationListener *Listener;
   clang::PrintingPolicy PrintingPolicy;
 
   // Typedefs which may be provided defining the structure of Objective-C
@@ -412,6 +414,19 @@
   /// with this AST context, if any.
   ExternalASTSource *getExternalSource() const { return ExternalSource.get(); }
 
+  /// \brief Attach an AST mutation listener to the AST context.
+  ///
+  /// The AST mutation listener provides the ability to track modifications to
+  /// the abstract syntax tree entities committed after they were initially
+  /// created.
+  void setASTMutationListener(ASTMutationListener *Listener) {
+    this->Listener = Listener;
+  }
+
+  /// \brief Retrieve a pointer to the AST mutation listener associated
+  /// with this AST context, if any.
+  ASTMutationListener *getASTMutationListener() const { return Listener; }
+
   void PrintStats() const;
   const std::vector<Type*>& getTypes() const { return Types; }
 

Added: cfe/trunk/include/clang/AST/ASTMutationListener.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTMutationListener.h?rev=117235&view=auto
==============================================================================
--- cfe/trunk/include/clang/AST/ASTMutationListener.h (added)
+++ cfe/trunk/include/clang/AST/ASTMutationListener.h Sun Oct 24 12:26:36 2010
@@ -0,0 +1,30 @@
+//===--- ASTMutationListener.h - AST Mutation Interface --------*- 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 ASTMutationListener interface.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
+#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
+
+namespace clang {
+  class CXXRecordDecl;
+  class CXXMethodDecl;
+
+/// \brief An abstract interface that should be implemented by listeners
+/// that want to be notified when an AST entity gets modified after its
+/// initial creation.
+class ASTMutationListener {
+public:
+  virtual ~ASTMutationListener();
+};
+
+} // end namespace clang
+
+#endif

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Sun Oct 24 12:26:36 2010
@@ -43,6 +43,7 @@
 class CompoundStmt;
 class StoredDeclsMap;
 class DependentDiagnostic;
+class ASTMutationListener;
 }
 
 namespace llvm {
@@ -625,6 +626,8 @@
 private:
   const Attr *getAttrsImpl() const;
 
+protected:
+  ASTMutationListener *getASTMutationListener() const;
 };
 
 /// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Sun Oct 24 12:26:36 2010
@@ -141,7 +141,10 @@
 
       /// \brief The block containing the definitions of all of the
       /// types and decls used within the AST file.
-      DECLTYPES_BLOCK_ID
+      DECLTYPES_BLOCK_ID,
+
+      /// \brief The block containing DECL_UPDATES records.
+      DECL_UPDATES_BLOCK_ID
     };
 
     /// \brief Record types that occur within the AST block itself.
@@ -326,7 +329,15 @@
 
       /// \brief Record code for template specializations introduced after
       /// serializations of the original template decl.
-      ADDITIONAL_TEMPLATE_SPECIALIZATIONS = 35
+      ADDITIONAL_TEMPLATE_SPECIALIZATIONS = 35,
+
+      /// \brief Record for offsets of DECL_UPDATES records for declarations
+      /// that were modified after being deserialized and need updates.
+      DECL_UPDATE_OFFSETS = 36,
+
+      /// \brief Record of updates for a declaration that was modified after
+      /// being deserialized.
+      DECL_UPDATES = 37
     };
 
     /// \brief Record types used within a source manager block.

Modified: cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h Sun Oct 24 12:26:36 2010
@@ -29,8 +29,9 @@
   virtual ~ASTDeserializationListener();
 
 public:
-  /// \brief Tell the listener about the reader.
-  virtual void SetReader(ASTReader *Reader) { }
+
+  /// \brief The ASTReader was initialized.
+  virtual void ReaderInitialized(ASTReader *Reader) { }
 
   /// \brief An identifier was deserialized from the AST file.
   virtual void IdentifierRead(serialization::IdentID ID,

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Sun Oct 24 12:26:36 2010
@@ -401,6 +401,14 @@
   /// = I + 1 has already been loaded.
   std::vector<Decl *> DeclsLoaded;
 
+  typedef std::pair<PerFileData *, uint64_t> FileOffset;
+  typedef llvm::SmallVector<FileOffset, 2> FileOffsetsTy;
+  typedef llvm::DenseMap<serialization::DeclID, FileOffsetsTy>
+      DeclUpdateOffsetsMap;
+  /// \brief Declarations that have modifications residing in a later file
+  /// in the chain.
+  DeclUpdateOffsetsMap DeclUpdateOffsets;
+
   typedef llvm::DenseMap<serialization::DeclID,
                          std::pair<PerFileData *, uint64_t> >
       DeclReplacementMap;

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Sun Oct 24 12:26:36 2010
@@ -17,6 +17,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/TemplateBase.h"
+#include "clang/AST/ASTMutationListener.h"
 #include "clang/Serialization/ASTBitCodes.h"
 #include "clang/Serialization/ASTDeserializationListener.h"
 #include "clang/Sema/SemaConsumer.h"
@@ -55,9 +56,11 @@
 /// representation of a given abstract syntax tree and its supporting
 /// data structures. This bitstream can be de-serialized via an
 /// instance of the ASTReader class.
-class ASTWriter : public ASTDeserializationListener {
+class ASTWriter : public ASTDeserializationListener,
+                  public ASTMutationListener {
 public:
   typedef llvm::SmallVector<uint64_t, 64> RecordData;
+  typedef llvm::SmallVectorImpl<uint64_t> RecordDataImpl;
 
   friend class ASTDeclWriter;
 private:
@@ -187,6 +190,12 @@
   /// to the corresponding offsets within the preprocessor block.
   std::vector<uint32_t> MacroDefinitionOffsets;
 
+  typedef llvm::SmallVector<uint64_t, 2> UpdateRecord;
+  typedef llvm::DenseMap<const Decl *, UpdateRecord> DeclUpdateMap;
+  /// \brief Mapping from declarations that came from a chained PCH to the
+  /// record containing modifications to them.
+  DeclUpdateMap DeclUpdates;
+
   typedef llvm::DenseMap<Decl *, Decl *> FirstLatestDeclMap;
   /// \brief Map of first declarations from a chained PCH that point to the
   /// most recent declarations in another PCH.
@@ -280,6 +289,7 @@
   void WriteReferencedSelectorsPool(Sema &SemaRef);
   void WriteIdentifierTable(Preprocessor &PP);
   void WriteAttributes(const AttrVec &Attrs, RecordData &Record);
+  void WriteDeclChangeSetBlocks();
   void WriteDeclUpdateBlock();
   void WriteDeclContextVisibleUpdate(const DeclContext *DC);
   void WriteAdditionalTemplateSpecializations();
@@ -389,7 +399,7 @@
                               RecordData &Record);
 
   /// \brief Emit a reference to a declaration.
-  void AddDeclRef(const Decl *D, RecordData &Record);
+  void AddDeclRef(const Decl *D, RecordDataImpl &Record);
 
   /// \brief Force a declaration to be emitted and get its ID.
   serialization::DeclID GetDeclRef(const Decl *D);
@@ -489,7 +499,7 @@
   bool hasChain() const { return Chain; }
 
   // ASTDeserializationListener implementation
-  void SetReader(ASTReader *Reader);
+  void ReaderInitialized(ASTReader *Reader);
   void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II);
   void TypeRead(serialization::TypeIdx Idx, QualType T);
   void DeclRead(serialization::DeclID ID, const Decl *D);
@@ -508,6 +518,7 @@
   std::vector<unsigned char> Buffer;
   llvm::BitstreamWriter Stream;
   ASTWriter Writer;
+  bool Chaining;
 
 protected:
   ASTWriter &getWriter() { return Writer; }
@@ -518,6 +529,7 @@
                const char *isysroot, llvm::raw_ostream *Out);
   virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
   virtual void HandleTranslationUnit(ASTContext &Ctx);
+  virtual ASTMutationListener *GetASTMutationListener();
   virtual ASTDeserializationListener *GetASTDeserializationListener();
 };
 

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sun Oct 24 12:26:36 2010
@@ -20,6 +20,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/SourceManager.h"
@@ -5200,6 +5201,8 @@
 
 void ExternalASTSource::PrintStats() { }
 
+ASTMutationListener::~ASTMutationListener() { }
+
 
 //===----------------------------------------------------------------------===//
 //                          Builtin Type Computation

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Sun Oct 24 12:26:36 2010
@@ -210,6 +210,10 @@
   return getTranslationUnitDecl()->getASTContext();
 }
 
+ASTMutationListener *Decl::getASTMutationListener() const {
+  return getASTContext().getASTMutationListener();
+}
+
 bool Decl::isUsed(bool CheckUsedAttr) const { 
   if (Used)
     return true;

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Sun Oct 24 12:26:36 2010
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/TypeLoc.h"

Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendAction.cpp Sun Oct 24 12:26:36 2010
@@ -167,6 +167,8 @@
 
     llvm::OwningPtr<ASTConsumer> Consumer(CreateASTConsumer(CI, Filename));
 
+    CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
+
     /// Use PCH?
     if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
       assert(hasPCHSupport() && "This action does not have PCH support!");

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sun Oct 24 12:26:36 2010
@@ -454,8 +454,6 @@
 void
 ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
   DeserializationListener = Listener;
-  if (DeserializationListener)
-    DeserializationListener->SetReader(this);
 }
 
 
@@ -1716,6 +1714,13 @@
         }
         break;
 
+      case DECL_UPDATES_BLOCK_ID:
+        if (Stream.SkipBlock()) {
+          Error("malformed block record in AST file");
+          return Failure;
+        }
+        break;
+
       case PREPROCESSOR_BLOCK_ID:
         F.MacroCursor = Stream;
         if (PP)
@@ -2043,6 +2048,17 @@
       F.LocalNumMacroDefinitions = Record[1];
       break;
 
+    case DECL_UPDATE_OFFSETS: {
+      if (Record.size() % 2 != 0) {
+        Error("invalid DECL_UPDATE_OFFSETS block in AST file");
+        return Failure;
+      }
+      for (unsigned I = 0, N = Record.size(); I != N; I += 2)
+        DeclUpdateOffsets[static_cast<DeclID>(Record[I])]
+            .push_back(std::make_pair(&F, Record[I+1]));
+      break;
+    }
+
     case DECL_REPLACEMENTS: {
       if (Record.size() % 2 != 0) {
         Error("invalid DECL_REPLACEMENTS block in AST file");
@@ -2164,6 +2180,9 @@
   if (Context)
     InitializeContext(*Context);
 
+  if (DeserializationListener)
+    DeserializationListener->ReaderInitialized(this);
+
   return Success;
 }
 

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sun Oct 24 12:26:36 2010
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "ASTCommon.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -71,6 +72,8 @@
 
     void Visit(Decl *D);
 
+    void UpdateDecl(Decl *D, const RecordData &Record);
+
     void VisitDecl(Decl *D);
     void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
     void VisitNamedDecl(NamedDecl *ND);
@@ -1537,6 +1540,28 @@
   }
   assert(Idx == Record.size());
 
+  // The declaration may have been modified by files later in the chain.
+  // If this is the case, read the record containing the updates from each file
+  // and pass it to ASTDeclReader to make the modifications.
+  DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
+  if (UpdI != DeclUpdateOffsets.end()) {
+    FileOffsetsTy &UpdateOffsets = UpdI->second;
+    for (FileOffsetsTy::iterator
+           I = UpdateOffsets.begin(), E = UpdateOffsets.end(); I != E; ++I) {
+      PerFileData *F = I->first;
+      uint64_t Offset = I->second;
+      llvm::BitstreamCursor &Cursor = F->DeclsCursor;
+      SavedStreamPosition SavedPosition(Cursor);
+      Cursor.JumpToBit(Offset);
+      RecordData Record;
+      unsigned Code = Cursor.ReadCode();
+      unsigned RecCode = Cursor.ReadRecord(Code, Record);
+      (void)RecCode;
+      assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
+      Reader.UpdateDecl(D, Record);
+    }
+  }
+
   // If we have deserialized a declaration that has a definition the
   // AST consumer might need to know about, queue it.
   // We don't pass it to the consumer immediately because we may be in recursive
@@ -1546,3 +1571,7 @@
 
   return D;
 }
+
+void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) {
+  // No update is tracked yet.
+}

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sun Oct 24 12:26:36 2010
@@ -2474,17 +2474,6 @@
                               const char *isysroot) {
   using namespace llvm;
 
-  FirstDeclID += Chain->getTotalNumDecls();
-  FirstTypeID += Chain->getTotalNumTypes();
-  FirstIdentID += Chain->getTotalNumIdentifiers();
-  FirstSelectorID += Chain->getTotalNumSelectors();
-  FirstMacroID += Chain->getTotalNumMacroDefinitions();
-  NextDeclID = FirstDeclID;
-  NextTypeID = FirstTypeID;
-  NextIdentID = FirstIdentID;
-  NextSelectorID = FirstSelectorID;
-  NextMacroID = FirstMacroID;
-
   ASTContext &Context = SemaRef.Context;
   Preprocessor &PP = SemaRef.PP;
 
@@ -2707,6 +2696,8 @@
   if (!AdditionalTemplateSpecializations.empty())
     WriteAdditionalTemplateSpecializations();
 
+  WriteDeclChangeSetBlocks();
+
   Record.clear();
   Record.push_back(NumStatements);
   Record.push_back(NumMacros);
@@ -2717,6 +2708,27 @@
   Stream.ExitBlock();
 }
 
+void ASTWriter::WriteDeclChangeSetBlocks() {
+  if (DeclUpdates.empty())
+    return;
+
+  RecordData OffsetsRecord;
+  Stream.EnterSubblock(DECL_UPDATES_BLOCK_ID, 3);
+  for (DeclUpdateMap::iterator
+         I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) {
+    const Decl *D = I->first;
+    UpdateRecord &URec = I->second;
+
+    uint64_t Offset = Stream.GetCurrentBitNo();
+    Stream.EmitRecord(DECL_UPDATES, URec);
+
+    OffsetsRecord.push_back(GetDeclRef(D));
+    OffsetsRecord.push_back(Offset);
+  }
+  Stream.ExitBlock();
+  Stream.EmitRecord(DECL_UPDATE_OFFSETS, OffsetsRecord);
+}
+
 void ASTWriter::WriteDeclUpdateBlock() {
   if (ReplacedDecls.empty())
     return;
@@ -2891,7 +2903,7 @@
   return I->second;
 }
 
-void ASTWriter::AddDeclRef(const Decl *D, RecordData &Record) {
+void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
   Record.push_back(GetDeclRef(D));
 }
 
@@ -3190,8 +3202,9 @@
   }
 }
 
-void ASTWriter::SetReader(ASTReader *Reader) {
+void ASTWriter::ReaderInitialized(ASTReader *Reader) {
   assert(Reader && "Cannot remove chain");
+  assert(!Chain && "Cannot replace chain");
   assert(FirstDeclID == NextDeclID &&
          FirstTypeID == NextTypeID &&
          FirstIdentID == NextIdentID &&
@@ -3199,6 +3212,17 @@
          FirstMacroID == NextMacroID &&
          "Setting chain after writing has started.");
   Chain = Reader;
+
+  FirstDeclID += Chain->getTotalNumDecls();
+  FirstTypeID += Chain->getTotalNumTypes();
+  FirstIdentID += Chain->getTotalNumIdentifiers();
+  FirstSelectorID += Chain->getTotalNumSelectors();
+  FirstMacroID += Chain->getTotalNumMacroDefinitions();
+  NextDeclID = FirstDeclID;
+  NextTypeID = FirstTypeID;
+  NextIdentID = FirstIdentID;
+  NextSelectorID = FirstSelectorID;
+  NextMacroID = FirstMacroID;
 }
 
 void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {

Modified: cfe/trunk/lib/Serialization/GeneratePCH.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/GeneratePCH.cpp?rev=117235&r1=117234&r2=117235&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/GeneratePCH.cpp (original)
+++ cfe/trunk/lib/Serialization/GeneratePCH.cpp Sun Oct 24 12:26:36 2010
@@ -30,7 +30,7 @@
                            const char *isysroot,
                            llvm::raw_ostream *OS)
   : PP(PP), isysroot(isysroot), Out(OS), SemaPtr(0),
-    StatCalls(0), Stream(Buffer), Writer(Stream) {
+    StatCalls(0), Stream(Buffer), Writer(Stream), Chaining(Chaining) {
 
   // Install a stat() listener to keep track of all of the stat()
   // calls.
@@ -59,6 +59,12 @@
   Buffer.clear();
 }
 
+ASTMutationListener *PCHGenerator::GetASTMutationListener() {
+  if (Chaining)
+    return &Writer;
+  return 0;
+}
+
 ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {
   return &Writer;
 }





More information about the cfe-commits mailing list