Promote the identifier table to per-file data. Also, if a CHAINED_METADATA record exists, it has to be the first thing in the PCH file.

llvm-svn: 108748
This commit is contained in:
Sebastian Redl 2010-07-19 20:52:06 +00:00
parent 6b4391aa69
commit 393f8b76c0
2 changed files with 42 additions and 33 deletions

View File

@ -233,6 +233,16 @@ private:
/// \brief The number of declarations in this PCH file. /// \brief The number of declarations in this PCH file.
unsigned LocalNumDecls; 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 /// \brief The chain of PCH files. The first entry is the one named by the
@ -276,16 +286,6 @@ private:
/// DeclContext. /// DeclContext.
DeclContextOffsetsMap DeclContextOffsets; 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. /// \brief Offsets into the identifier table data.
/// ///
/// This array is indexed by the identifier ID (-1), and provides /// This array is indexed by the identifier ID (-1), and provides
@ -534,8 +534,8 @@ private:
PCHReadResult ReadPCHCore(llvm::StringRef FileName); PCHReadResult ReadPCHCore(llvm::StringRef FileName);
PCHReadResult ReadPCHBlock(PerFileData &F); PCHReadResult ReadPCHBlock(PerFileData &F);
bool CheckPredefinesBuffers(); bool CheckPredefinesBuffers();
bool ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record); bool ParseLineTable(PerFileData &F, llvm::SmallVectorImpl<uint64_t> &Record);
PCHReadResult ReadSourceManagerBlock(); PCHReadResult ReadSourceManagerBlock(PerFileData &F);
PCHReadResult ReadSLocEntryRecord(unsigned ID); PCHReadResult ReadSLocEntryRecord(unsigned ID);
bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record); bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record);

View File

@ -418,8 +418,7 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,
: Listener(new PCHValidator(PP, *this)), DeserializationListener(0), : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context), Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
Consumer(0), IdentifierTableData(0), IdentifierLookupTable(0), Consumer(0), IdentifierOffsets(0),
IdentifierOffsets(0),
MethodPoolLookupTable(0), MethodPoolLookupTableData(0), MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
TotalSelectorsInMethodPool(0), SelectorOffsets(0), TotalSelectorsInMethodPool(0), SelectorOffsets(0),
TotalNumSelectors(0), MacroDefinitionOffsets(0), TotalNumSelectors(0), MacroDefinitionOffsets(0),
@ -436,7 +435,6 @@ PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
Diagnostic &Diags, const char *isysroot) Diagnostic &Diags, const char *isysroot)
: DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr), : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0), Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
IdentifierTableData(0), IdentifierLookupTable(0),
IdentifierOffsets(0), IdentifierOffsets(0),
MethodPoolLookupTable(0), MethodPoolLookupTableData(0), MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
TotalSelectorsInMethodPool(0), SelectorOffsets(0), TotalSelectorsInMethodPool(0), SelectorOffsets(0),
@ -456,7 +454,7 @@ PCHReader::~PCHReader() {
} }
PCHReader::PerFileData::PerFileData() 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. /// \brief Read the line table in the source manager block.
/// \returns true if ther was an error. /// \returns true if ther was an error.
bool PCHReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) { bool PCHReader::ParseLineTable(PerFileData &F,
llvm::SmallVectorImpl<uint64_t> &Record) {
unsigned Idx = 0; unsigned Idx = 0;
LineTableInfo &LineTable = SourceMgr.getLineTable(); LineTableInfo &LineTable = SourceMgr.getLineTable();
// FIXME: Handle multiple tables!
(void)F;
// Parse the file names // Parse the file names
std::map<int, int> FileIDs; std::map<int, int> FileIDs;
for (int I = 0, N = Record[Idx++]; I != N; ++I) { for (int I = 0, N = Record[Idx++]; I != N; ++I) {
@ -881,20 +883,20 @@ public:
} // end anonymous namespace } // end anonymous namespace
/// \brief Read the source manager block /// \brief Read a source manager block
PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() { PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock(PerFileData &F) {
using namespace SrcMgr; 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 // Set the source-location entry cursor to the current position in
// the stream. This cursor will be used to read the contents of the // the stream. This cursor will be used to read the contents of the
// source manager block initially, and then lazily read // source manager block initially, and then lazily read
// source-location entries as needed. // source-location entries as needed.
SLocEntryCursor = Chain[0]->Stream; SLocEntryCursor = F.Stream;
// The stream itself is going to skip over the source manager block. // 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"); Error("malformed block record in PCH file");
return Failure; return Failure;
} }
@ -940,7 +942,7 @@ PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
break; break;
case pch::SM_LINE_TABLE: case pch::SM_LINE_TABLE:
if (ParseLineTable(Record)) if (ParseLineTable(F, Record))
return Failure; return Failure;
break; break;
@ -1378,6 +1380,7 @@ PCHReader::ReadPCHBlock(PerFileData &F) {
// Read all of the records and blocks for the PCH file. // Read all of the records and blocks for the PCH file.
RecordData Record; RecordData Record;
bool First = true;
while (!Stream.AtEndOfStream()) { while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode(); unsigned Code = Stream.ReadCode();
if (Code == llvm::bitc::END_BLOCK) { if (Code == llvm::bitc::END_BLOCK) {
@ -1417,7 +1420,7 @@ PCHReader::ReadPCHBlock(PerFileData &F) {
break; break;
case pch::SOURCE_MANAGER_BLOCK_ID: case pch::SOURCE_MANAGER_BLOCK_ID:
switch (ReadSourceManagerBlock()) { switch (ReadSourceManagerBlock(F)) {
case Success: case Success:
break; break;
@ -1430,6 +1433,7 @@ PCHReader::ReadPCHBlock(PerFileData &F) {
} }
break; break;
} }
First = false;
continue; continue;
} }
@ -1464,6 +1468,10 @@ PCHReader::ReadPCHBlock(PerFileData &F) {
} }
case pch::CHAINED_METADATA: { case pch::CHAINED_METADATA: {
if (!First) {
Error("CHAINED_METADATA is not first record in block");
return Failure;
}
if (Record[0] != pch::VERSION_MAJOR) { if (Record[0] != pch::VERSION_MAJOR) {
Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old
: diag::warn_pch_version_too_new); : diag::warn_pch_version_too_new);
@ -1504,13 +1512,13 @@ PCHReader::ReadPCHBlock(PerFileData &F) {
break; break;
case pch::IDENTIFIER_TABLE: case pch::IDENTIFIER_TABLE:
IdentifierTableData = BlobStart; F.IdentifierTableData = BlobStart;
if (Record[0]) { if (Record[0]) {
IdentifierLookupTable F.IdentifierLookupTable
= PCHIdentifierLookupTable::Create( = PCHIdentifierLookupTable::Create(
(const unsigned char *)IdentifierTableData + Record[0], (const unsigned char *)F.IdentifierTableData + Record[0],
(const unsigned char *)IdentifierTableData, (const unsigned char *)F.IdentifierTableData,
PCHIdentifierLookupTrait(*this)); PCHIdentifierLookupTrait(*this));
if (PP) if (PP)
PP->getIdentifierTable().setExternalIdentifierLookup(this); PP->getIdentifierTable().setExternalIdentifierLookup(this);
} }
@ -1669,6 +1677,7 @@ PCHReader::ReadPCHBlock(PerFileData &F) {
MacroDefinitionsLoaded.resize(Record[1]); MacroDefinitionsLoaded.resize(Record[1]);
break; break;
} }
First = false;
} }
Error("premature end of bitstream in PCH file"); Error("premature end of bitstream in PCH file");
return Failure; return Failure;
@ -1706,7 +1715,7 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
Id != IdEnd; ++Id) Id != IdEnd; ++Id)
Identifiers.push_back(Id->second); Identifiers.push_back(Id->second);
PCHIdentifierLookupTable *IdTable PCHIdentifierLookupTable *IdTable
= (PCHIdentifierLookupTable *)IdentifierLookupTable; = (PCHIdentifierLookupTable *)Chain[0]->IdentifierLookupTable;
for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) { for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
IdentifierInfo *II = Identifiers[I]; IdentifierInfo *II = Identifiers[I];
// Look in the on-disk hash table for an entry for // 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) { IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
// Try to find this name within our on-disk hash table // Try to find this name within our on-disk hash table
PCHIdentifierLookupTable *IdTable PCHIdentifierLookupTable *IdTable
= (PCHIdentifierLookupTable *)IdentifierLookupTable; = (PCHIdentifierLookupTable *)Chain[0]->IdentifierLookupTable;
std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart); std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key); PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
if (Pos == IdTable->end()) if (Pos == IdTable->end())
@ -3104,7 +3113,7 @@ IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
if (ID == 0) if (ID == 0)
return 0; return 0;
if (!IdentifierTableData || IdentifiersLoaded.empty()) { if (!Chain[0]->IdentifierTableData || IdentifiersLoaded.empty()) {
Error("no identifier table in PCH file"); Error("no identifier table in PCH file");
return 0; return 0;
} }
@ -3112,7 +3121,7 @@ IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
assert(PP && "Forgot to set Preprocessor ?"); assert(PP && "Forgot to set Preprocessor ?");
if (!IdentifiersLoaded[ID - 1]) { if (!IdentifiersLoaded[ID - 1]) {
uint32_t Offset = IdentifierOffsets[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 // 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 // length. Extract that 16-bit length to avoid having to execute