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:
parent
6b4391aa69
commit
393f8b76c0
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue