diff --git a/clang/include/clang/Frontend/PCHReader.h b/clang/include/clang/Frontend/PCHReader.h index be0e1d4e027e..9ec7ea40d5ab 100644 --- a/clang/include/clang/Frontend/PCHReader.h +++ b/clang/include/clang/Frontend/PCHReader.h @@ -233,6 +233,16 @@ private: /// \brief The number of declarations in this PCH file. unsigned LocalNumDecls; + + /// \brief Actual data for the on-disk hash table. + /// + // This pointer points into a memory buffer, where the on-disk hash + // table for identifiers actually lives. + const char *IdentifierTableData; + + /// \brief A pointer to an on-disk hash table of opaque type + /// IdentifierHashTable. + void *IdentifierLookupTable; }; /// \brief The chain of PCH files. The first entry is the one named by the @@ -276,16 +286,6 @@ private: /// DeclContext. DeclContextOffsetsMap DeclContextOffsets; - /// \brief Actual data for the on-disk hash table. - /// - // This pointer points into a memory buffer, where the on-disk hash - // table for identifiers actually lives. - const char *IdentifierTableData; - - /// \brief A pointer to an on-disk hash table of opaque type - /// IdentifierHashTable. - void *IdentifierLookupTable; - /// \brief Offsets into the identifier table data. /// /// This array is indexed by the identifier ID (-1), and provides @@ -534,8 +534,8 @@ private: PCHReadResult ReadPCHCore(llvm::StringRef FileName); PCHReadResult ReadPCHBlock(PerFileData &F); bool CheckPredefinesBuffers(); - bool ParseLineTable(llvm::SmallVectorImpl &Record); - PCHReadResult ReadSourceManagerBlock(); + bool ParseLineTable(PerFileData &F, llvm::SmallVectorImpl &Record); + PCHReadResult ReadSourceManagerBlock(PerFileData &F); PCHReadResult ReadSLocEntryRecord(unsigned ID); bool ParseLanguageOptions(const llvm::SmallVectorImpl &Record); diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 6111037c9df1..aa92701abd6d 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -418,8 +418,7 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context, : Listener(new PCHValidator(PP, *this)), DeserializationListener(0), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context), - Consumer(0), IdentifierTableData(0), IdentifierLookupTable(0), - IdentifierOffsets(0), + Consumer(0), IdentifierOffsets(0), MethodPoolLookupTable(0), MethodPoolLookupTableData(0), TotalSelectorsInMethodPool(0), SelectorOffsets(0), TotalNumSelectors(0), MacroDefinitionOffsets(0), @@ -436,7 +435,6 @@ PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr, Diagnostic &Diags, const char *isysroot) : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr), Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0), - IdentifierTableData(0), IdentifierLookupTable(0), IdentifierOffsets(0), MethodPoolLookupTable(0), MethodPoolLookupTableData(0), TotalSelectorsInMethodPool(0), SelectorOffsets(0), @@ -456,7 +454,7 @@ PCHReader::~PCHReader() { } PCHReader::PerFileData::PerFileData() - : StatCache(0) + : StatCache(0), IdentifierTableData(0), IdentifierLookupTable(0) {} @@ -730,10 +728,14 @@ bool PCHReader::CheckPredefinesBuffers() { /// \brief Read the line table in the source manager block. /// \returns true if ther was an error. -bool PCHReader::ParseLineTable(llvm::SmallVectorImpl &Record) { +bool PCHReader::ParseLineTable(PerFileData &F, + llvm::SmallVectorImpl &Record) { unsigned Idx = 0; LineTableInfo &LineTable = SourceMgr.getLineTable(); + // FIXME: Handle multiple tables! + (void)F; + // Parse the file names std::map FileIDs; for (int I = 0, N = Record[Idx++]; I != N; ++I) { @@ -881,20 +883,20 @@ public: } // end anonymous namespace -/// \brief Read the source manager block -PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() { +/// \brief Read a source manager block +PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock(PerFileData &F) { using namespace SrcMgr; - llvm::BitstreamCursor &SLocEntryCursor = Chain[0]->SLocEntryCursor; + llvm::BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor; // Set the source-location entry cursor to the current position in // the stream. This cursor will be used to read the contents of the // source manager block initially, and then lazily read // source-location entries as needed. - SLocEntryCursor = Chain[0]->Stream; + SLocEntryCursor = F.Stream; // The stream itself is going to skip over the source manager block. - if (Chain[0]->Stream.SkipBlock()) { + if (F.Stream.SkipBlock()) { Error("malformed block record in PCH file"); return Failure; } @@ -940,7 +942,7 @@ PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() { break; case pch::SM_LINE_TABLE: - if (ParseLineTable(Record)) + if (ParseLineTable(F, Record)) return Failure; break; @@ -1378,6 +1380,7 @@ PCHReader::ReadPCHBlock(PerFileData &F) { // Read all of the records and blocks for the PCH file. RecordData Record; + bool First = true; while (!Stream.AtEndOfStream()) { unsigned Code = Stream.ReadCode(); if (Code == llvm::bitc::END_BLOCK) { @@ -1417,7 +1420,7 @@ PCHReader::ReadPCHBlock(PerFileData &F) { break; case pch::SOURCE_MANAGER_BLOCK_ID: - switch (ReadSourceManagerBlock()) { + switch (ReadSourceManagerBlock(F)) { case Success: break; @@ -1430,6 +1433,7 @@ PCHReader::ReadPCHBlock(PerFileData &F) { } break; } + First = false; continue; } @@ -1464,6 +1468,10 @@ PCHReader::ReadPCHBlock(PerFileData &F) { } case pch::CHAINED_METADATA: { + if (!First) { + Error("CHAINED_METADATA is not first record in block"); + return Failure; + } if (Record[0] != pch::VERSION_MAJOR) { Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old : diag::warn_pch_version_too_new); @@ -1504,13 +1512,13 @@ PCHReader::ReadPCHBlock(PerFileData &F) { break; case pch::IDENTIFIER_TABLE: - IdentifierTableData = BlobStart; + F.IdentifierTableData = BlobStart; if (Record[0]) { - IdentifierLookupTable + F.IdentifierLookupTable = PCHIdentifierLookupTable::Create( - (const unsigned char *)IdentifierTableData + Record[0], - (const unsigned char *)IdentifierTableData, - PCHIdentifierLookupTrait(*this)); + (const unsigned char *)F.IdentifierTableData + Record[0], + (const unsigned char *)F.IdentifierTableData, + PCHIdentifierLookupTrait(*this)); if (PP) PP->getIdentifierTable().setExternalIdentifierLookup(this); } @@ -1669,6 +1677,7 @@ PCHReader::ReadPCHBlock(PerFileData &F) { MacroDefinitionsLoaded.resize(Record[1]); break; } + First = false; } Error("premature end of bitstream in PCH file"); return Failure; @@ -1706,7 +1715,7 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) { Id != IdEnd; ++Id) Identifiers.push_back(Id->second); PCHIdentifierLookupTable *IdTable - = (PCHIdentifierLookupTable *)IdentifierLookupTable; + = (PCHIdentifierLookupTable *)Chain[0]->IdentifierLookupTable; for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) { IdentifierInfo *II = Identifiers[I]; // Look in the on-disk hash table for an entry for @@ -3018,7 +3027,7 @@ void PCHReader::InitializeSema(Sema &S) { IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) { // Try to find this name within our on-disk hash table PCHIdentifierLookupTable *IdTable - = (PCHIdentifierLookupTable *)IdentifierLookupTable; + = (PCHIdentifierLookupTable *)Chain[0]->IdentifierLookupTable; std::pair Key(NameStart, NameEnd - NameStart); PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key); if (Pos == IdTable->end()) @@ -3104,7 +3113,7 @@ IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) { if (ID == 0) return 0; - if (!IdentifierTableData || IdentifiersLoaded.empty()) { + if (!Chain[0]->IdentifierTableData || IdentifiersLoaded.empty()) { Error("no identifier table in PCH file"); return 0; } @@ -3112,7 +3121,7 @@ IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) { assert(PP && "Forgot to set Preprocessor ?"); if (!IdentifiersLoaded[ID - 1]) { uint32_t Offset = IdentifierOffsets[ID - 1]; - const char *Str = IdentifierTableData + Offset; + const char *Str = Chain[0]->IdentifierTableData + Offset; // All of the strings in the PCH file are preceded by a 16-bit // length. Extract that 16-bit length to avoid having to execute