diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-24 17:26:36 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-24 17:26:36 +0000 |
commit | 7b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8 (patch) | |
tree | 534ddbf567967924e8defe105d20f1d749813927 /lib | |
parent | 134db1fff5653c164ef41c898943521c49f6ebab (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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 3 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 4 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/FrontendAction.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 23 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 29 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 50 | ||||
-rw-r--r-- | lib/Serialization/GeneratePCH.cpp | 8 |
8 files changed, 104 insertions, 16 deletions
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; } |