Fix header-search problems with precompiled headers, where the
presence or absence of header map arguments when using the precompiled header would cause Clang to get confused about which headers had already been included/imported, along with their controlling macros. The fundamental problem is that the serialization of the header search information was relying on the UIDs of FileEntry objects at PCH generation time and PCH load time to be equivalent, which effectively means that we had to probe the same files in the same order. Differing header map arguments caused an extra FileEntry lookup, but it's easy to imagine other minor command-line arguments triggering this problem. Header-search information is now encoded along with the source-location entry for a file, so that we register information about a file's properties as a header at the same time we create the FileEntry for that file. Fixes <rdar://problem/7743243>. llvm-svn: 98636
This commit is contained in:
@@ -573,7 +573,6 @@ void PCHWriter::WriteBlockInfoBlock() {
|
||||
RECORD(SM_SLOC_BUFFER_BLOB);
|
||||
RECORD(SM_SLOC_INSTANTIATION_ENTRY);
|
||||
RECORD(SM_LINE_TABLE);
|
||||
RECORD(SM_HEADER_FILE_INFO);
|
||||
|
||||
// Preprocessor Block.
|
||||
BLOCK(PREPROCESSOR_BLOCK);
|
||||
@@ -918,6 +917,11 @@ static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) {
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
|
||||
// HeaderFileInfo fields.
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isImport
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // DirInfo
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumIncludes
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // ControllingMacro
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
|
||||
return Stream.EmitAbbrev(Abbrev);
|
||||
}
|
||||
@@ -1019,20 +1023,6 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
|
||||
Stream.EmitRecord(pch::SM_LINE_TABLE, Record);
|
||||
}
|
||||
|
||||
// Write out entries for all of the header files we know about.
|
||||
HeaderSearch &HS = PP.getHeaderSearchInfo();
|
||||
Record.clear();
|
||||
for (HeaderSearch::header_file_iterator I = HS.header_file_begin(),
|
||||
E = HS.header_file_end();
|
||||
I != E; ++I) {
|
||||
Record.push_back(I->isImport);
|
||||
Record.push_back(I->DirInfo);
|
||||
Record.push_back(I->NumIncludes);
|
||||
AddIdentifierRef(I->ControllingMacro, Record);
|
||||
Stream.EmitRecord(pch::SM_HEADER_FILE_INFO, Record);
|
||||
Record.clear();
|
||||
}
|
||||
|
||||
// Write out the source location entry table. We skip the first
|
||||
// entry, which is always the same dummy entry.
|
||||
std::vector<uint32_t> SLocEntryOffsets;
|
||||
@@ -1069,6 +1059,16 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
|
||||
// The source location entry is a file. The blob associated
|
||||
// with this entry is the file name.
|
||||
|
||||
// Emit header-search information associated with this file.
|
||||
HeaderFileInfo HFI;
|
||||
HeaderSearch &HS = PP.getHeaderSearchInfo();
|
||||
if (Content->Entry->getUID() < HS.header_file_size())
|
||||
HFI = HS.header_file_begin()[Content->Entry->getUID()];
|
||||
Record.push_back(HFI.isImport);
|
||||
Record.push_back(HFI.DirInfo);
|
||||
Record.push_back(HFI.NumIncludes);
|
||||
AddIdentifierRef(HFI.ControllingMacro, Record);
|
||||
|
||||
// Turn the file name into an absolute path, if it isn't already.
|
||||
const char *Filename = Content->Entry->getName();
|
||||
llvm::sys::Path FilePath(Filename, strlen(Filename));
|
||||
|
||||
Reference in New Issue
Block a user