aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-10-24 17:26:36 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-10-24 17:26:36 +0000
commit7b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8 (patch)
tree534ddbf567967924e8defe105d20f1d749813927
parent134db1fff5653c164ef41c898943521c49f6ebab (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117235 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/ASTConsumer.h8
-rw-r--r--include/clang/AST/ASTContext.h15
-rw-r--r--include/clang/AST/ASTMutationListener.h30
-rw-r--r--include/clang/AST/DeclBase.h3
-rw-r--r--include/clang/Serialization/ASTBitCodes.h15
-rw-r--r--include/clang/Serialization/ASTDeserializationListener.h5
-rw-r--r--include/clang/Serialization/ASTReader.h8
-rw-r--r--include/clang/Serialization/ASTWriter.h18
-rw-r--r--lib/AST/ASTContext.cpp3
-rw-r--r--lib/AST/DeclBase.cpp4
-rw-r--r--lib/AST/DeclCXX.cpp1
-rw-r--r--lib/Frontend/FrontendAction.cpp2
-rw-r--r--lib/Serialization/ASTReader.cpp23
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp29
-rw-r--r--lib/Serialization/ASTWriter.cpp50
-rw-r--r--lib/Serialization/GeneratePCH.cpp8
16 files changed, 197 insertions, 25 deletions
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 84833c099f..08ee4ef40d 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -19,6 +19,7 @@ namespace clang {
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 @@ public:
/// 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.
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 0a960ab34c..33f522f91b 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -45,6 +45,7 @@ namespace clang {
class Diagnostic;
class Expr;
class ExternalASTSource;
+ class ASTMutationListener;
class IdentifierTable;
class SelectorTable;
class SourceManager;
@@ -297,6 +298,7 @@ public:
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 @@ public:
/// 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; }
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
new file mode 100644
index 0000000000..ea09b0c202
--- /dev/null
+++ b/include/clang/AST/ASTMutationListener.h
@@ -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
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 83100178d5..073efa6902 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -43,6 +43,7 @@ class DeclarationName;
class CompoundStmt;
class StoredDeclsMap;
class DependentDiagnostic;
+class ASTMutationListener;
}
namespace llvm {
@@ -625,6 +626,8 @@ public:
private:
const Attr *getAttrsImpl() const;
+protected:
+ ASTMutationListener *getASTMutationListener() const;
};
/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index da27cde29f..7370db1fc4 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -141,7 +141,10 @@ namespace clang {
/// \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 @@ namespace clang {
/// \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.
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
index 00860cd39b..f8cdebe5a9 100644
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -29,8 +29,9 @@ protected:
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,
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index b5766b14eb..324e093e73 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -401,6 +401,14 @@ private:
/// = 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;
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index b2eccf393e..f1a66fcbc7 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -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 @@ class TargetInfo;
/// 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 @@ private:
/// 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 @@ private:
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 @@ public:
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 @@ public:
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 @@ class PCHGenerator : public SemaConsumer {
std::vector<unsigned char> Buffer;
llvm::BitstreamWriter Stream;
ASTWriter Writer;
+ bool Chaining;
protected:
ASTWriter &getWriter() { return Writer; }
@@ -518,6 +529,7 @@ public:
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();
};
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index c7b014efb5..313c2ea96b 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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 @@ ExternalASTSource::~ExternalASTSource() { }
void ExternalASTSource::PrintStats() { }
+ASTMutationListener::~ASTMutationListener() { }
+
//===----------------------------------------------------------------------===//
// Builtin Type Computation
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index d60a06749d..483352f2d6 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -210,6 +210,10 @@ ASTContext &Decl::getASTContext() const {
return getTranslationUnitDecl()->getASTContext();
}
+ASTMutationListener *Decl::getASTMutationListener() const {
+ return getASTContext().getASTMutationListener();
+}
+
bool Decl::isUsed(bool CheckUsedAttr) const {
if (Used)
return true;
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 8e1de4d027..f37151439f 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -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"
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 97188919f9..26ae4b1f7f 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -167,6 +167,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
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!");
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 162fa26e2d..38e786bff1 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -454,8 +454,6 @@ void PCHValidator::ReadCounter(unsigned Value) {
void
ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
DeserializationListener = Listener;
- if (DeserializationListener)
- DeserializationListener->SetReader(this);
}
@@ -1716,6 +1714,13 @@ ASTReader::ReadASTBlock(PerFileData &F) {
}
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 @@ ASTReader::ReadASTBlock(PerFileData &F) {
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 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
if (Context)
InitializeContext(*Context);
+ if (DeserializationListener)
+ DeserializationListener->ReaderInitialized(this);
+
return Success;
}
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 750e7236ef..acc4dc144d 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -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 @@ namespace clang {
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 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
}
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 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
return D;
}
+
+void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) {
+ // No update is tracked yet.
+}
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 4d0ec99074..e258fcc2a2 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2474,17 +2474,6 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
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 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
if (!AdditionalTemplateSpecializations.empty())
WriteAdditionalTemplateSpecializations();
+ WriteDeclChangeSetBlocks();
+
Record.clear();
Record.push_back(NumStatements);
Record.push_back(NumMacros);
@@ -2717,6 +2708,27 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
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 @@ TypeIdx ASTWriter::getTypeIdx(QualType T) const {
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::AddCXXBaseOrMemberInitializers(
}
}
-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 @@ void ASTWriter::SetReader(ASTReader *Reader) {
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) {
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index 5329b6cbd4..0d8ec736b6 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -30,7 +30,7 @@ PCHGenerator::PCHGenerator(const Preprocessor &PP,
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 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
Buffer.clear();
}
+ASTMutationListener *PCHGenerator::GetASTMutationListener() {
+ if (Chaining)
+ return &Writer;
+ return 0;
+}
+
ASTDeserializationListener *PCHGenerator::GetASTDeserializationListener() {
return &Writer;
}