diff options
Diffstat (limited to 'lib/Frontend')
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 11 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 10 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 22 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 32 |
4 files changed, 60 insertions, 15 deletions
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 16afabbb7e..e55605b274 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -1774,6 +1774,17 @@ PCHReader::ReadPCHBlock(PerFileData &F) { F.NumPreallocatedPreprocessingEntities = Record[0]; F.LocalNumMacroDefinitions = Record[1]; break; + + case pch::DECL_REPLACEMENTS: { + if (Record.size() % 2 != 0) { + Error("invalid DECL_REPLACEMENTS block in PCH file"); + return Failure; + } + for (unsigned I = 0, N = Record.size(); I != N; I += 2) + ReplacedDecls[static_cast<pch::DeclID>(Record[I])] = + std::make_pair(&F, Record[I+1]); + break; + } } First = false; } diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 212eaa1332..aa5ce7aad6 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -1307,7 +1307,13 @@ static bool isConsumerInterestedIn(Decl *D) { } /// \brief Get the correct cursor and offset for loading a type. -PCHReader::RecordLocation PCHReader::DeclCursorForIndex(unsigned Index) { +PCHReader::RecordLocation +PCHReader::DeclCursorForIndex(unsigned Index, pch::DeclID ID) { + // See if there's an override. + DeclReplacementMap::iterator It = ReplacedDecls.find(ID); + if (It != ReplacedDecls.end()) + return RecordLocation(&It->second.first->DeclsCursor, It->second.second); + PerFileData *F = 0; for (unsigned I = 0, N = Chain.size(); I != N; ++I) { F = Chain[N - I - 1]; @@ -1321,7 +1327,7 @@ PCHReader::RecordLocation PCHReader::DeclCursorForIndex(unsigned Index) { /// \brief Read the declaration at the given offset from the PCH file. Decl *PCHReader::ReadDeclRecord(unsigned Index, pch::DeclID ID) { - RecordLocation Loc = DeclCursorForIndex(Index); + RecordLocation Loc = DeclCursorForIndex(Index, ID); llvm::BitstreamCursor &DeclsCursor = *Loc.first; // Keep track of where we are in the stream, then jump back there // after reading this declaration. diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index d7da4fc41c..a86bdb9278 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -2414,6 +2414,8 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, I != E; ++I) { if ((*I)->getPCHLevel() == 0) NewGlobalDecls.push_back(GetDeclRef(*I)); + else if ((*I)->isChangedSinceDeserialization()) + (void)GetDeclRef(*I); // Make sure it's written, but don't record it. } // We also need to write a lexical updates block for the TU. llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev(); @@ -2596,10 +2598,24 @@ void PCHWriter::WritePCHChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, Record.push_back(NumMacros); Record.push_back(NumLexicalDeclContexts); Record.push_back(NumVisibleDeclContexts); + WriteDeclUpdateBlock(); Stream.EmitRecord(pch::STATISTICS, Record); Stream.ExitBlock(); } +void PCHWriter::WriteDeclUpdateBlock() { + if (ReplacedDecls.empty()) + return; + + RecordData Record; + for (llvm::SmallVector<std::pair<pch::DeclID, uint64_t>, 16>::iterator + I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) { + Record.push_back(I->first); + Record.push_back(I->second); + } + Stream.EmitRecord(pch::DECL_REPLACEMENTS, Record); +} + void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) { Record.push_back(Loc.getRawEncoding()); } @@ -2817,6 +2833,12 @@ pch::DeclID PCHWriter::GetDeclRef(const Decl *D) { // enqueue it in the list of declarations to emit. ID = NextDeclID++; DeclTypesToEmit.push(const_cast<Decl *>(D)); + } else if (ID < FirstDeclID && D->isChangedSinceDeserialization()) { + // We don't add it to the replacement collection here, because we don't + // have the offset yet. + DeclTypesToEmit.push(const_cast<Decl *>(D)); + // Reset the flag, so that we don't add this decl multiple times. + const_cast<Decl *>(D)->setChangedSinceDeserialization(false); } return ID; diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index 13e5239fe7..9893d254e9 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -1126,18 +1126,24 @@ void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) { } // Determine the ID for this declaration - pch::DeclID &ID = DeclIDs[D]; - if (ID == 0) - ID = NextDeclID++; - - unsigned Index = ID - FirstDeclID; - - // Record the offset for this declaration - if (DeclOffsets.size() == Index) - DeclOffsets.push_back(Stream.GetCurrentBitNo()); - else if (DeclOffsets.size() < Index) { - DeclOffsets.resize(Index+1); - DeclOffsets[Index] = Stream.GetCurrentBitNo(); + pch::DeclID &IDR = DeclIDs[D]; + if (IDR == 0) + IDR = NextDeclID++; + pch::DeclID ID = IDR; + + if (ID < FirstDeclID) { + // We're replacing a decl in a previous file. + ReplacedDecls.push_back(std::make_pair(ID, Stream.GetCurrentBitNo())); + } else { + unsigned Index = ID - FirstDeclID; + + // Record the offset for this declaration + if (DeclOffsets.size() == Index) + DeclOffsets.push_back(Stream.GetCurrentBitNo()); + else if (DeclOffsets.size() < Index) { + DeclOffsets.resize(Index+1); + DeclOffsets[Index] = Stream.GetCurrentBitNo(); + } } // Build and emit a record for this declaration @@ -1164,5 +1170,5 @@ void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) { // // FIXME: This should be renamed, the predicate is much more complicated. if (isRequiredDecl(D, Context)) - ExternalDefinitions.push_back(Index + 1); + ExternalDefinitions.push_back(ID); } |