aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/GeneratePCH.cpp22
-rw-r--r--lib/Frontend/PCHReader.cpp59
-rw-r--r--lib/Frontend/PCHWriter.cpp129
3 files changed, 156 insertions, 54 deletions
diff --git a/lib/Frontend/GeneratePCH.cpp b/lib/Frontend/GeneratePCH.cpp
index 8be88ce381..3b7715ad28 100644
--- a/lib/Frontend/GeneratePCH.cpp
+++ b/lib/Frontend/GeneratePCH.cpp
@@ -32,19 +32,24 @@ using namespace llvm;
namespace {
class VISIBILITY_HIDDEN PCHGenerator : public SemaConsumer {
const Preprocessor &PP;
+ const char *isysroot;
llvm::raw_ostream *Out;
Sema *SemaPtr;
MemorizeStatCalls *StatCalls; // owned by the FileManager
-
+
public:
- explicit PCHGenerator(const Preprocessor &PP, llvm::raw_ostream *Out);
+ explicit PCHGenerator(const Preprocessor &PP,
+ const char *isysroot,
+ llvm::raw_ostream *Out);
virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
virtual void HandleTranslationUnit(ASTContext &Ctx);
};
}
-PCHGenerator::PCHGenerator(const Preprocessor &PP, llvm::raw_ostream *OS)
- : PP(PP), Out(OS), SemaPtr(0), StatCalls(0) {
+PCHGenerator::PCHGenerator(const Preprocessor &PP,
+ const char *isysroot,
+ llvm::raw_ostream *OS)
+ : PP(PP), isysroot(isysroot), Out(OS), SemaPtr(0), StatCalls(0) {
// Install a stat() listener to keep track of all of the stat()
// calls.
@@ -56,14 +61,14 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
if (PP.getDiagnostics().hasErrorOccurred())
return;
- // Write the PCH contents into a buffer
+ // Write the PCH contents into a buffer
std::vector<unsigned char> Buffer;
BitstreamWriter Stream(Buffer);
PCHWriter Writer(Stream);
// Emit the PCH file
assert(SemaPtr && "No Sema?");
- Writer.WritePCH(*SemaPtr, StatCalls);
+ Writer.WritePCH(*SemaPtr, StatCalls, isysroot);
// Write the generated bitstream to "Out".
Out->write((char *)&Buffer.front(), Buffer.size());
@@ -73,6 +78,7 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
}
ASTConsumer *clang::CreatePCHGenerator(const Preprocessor &PP,
- llvm::raw_ostream *OS) {
- return new PCHGenerator(PP, OS);
+ llvm::raw_ostream *OS,
+ const char *isysroot) {
+ return new PCHGenerator(PP, isysroot, OS);
}
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 067cce9b30..bc0e7208d3 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -336,7 +336,8 @@ void PCHValidator::ReadCounter(unsigned Value) {
// PCH reader implementation
//===----------------------------------------------------------------------===//
-PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context)
+PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,
+ const char *isysroot)
: Listener(new PCHValidator(PP, *this)), SourceMgr(PP.getSourceManager()),
FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
SemaObj(0), PP(&PP), Context(Context), Consumer(0),
@@ -344,25 +345,31 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context)
IdentifierOffsets(0),
MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
TotalSelectorsInMethodPool(0), SelectorOffsets(0),
- TotalNumSelectors(0), Comments(0), NumComments(0),
+ TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot),
NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), NumStatementsRead(0),
NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
- NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0) { }
+ NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
+ CurrentlyLoadingTypeOrDecl(0) {
+ RelocatablePCH = false;
+}
PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
- Diagnostic &Diags)
+ Diagnostic &Diags, const char *isysroot)
: 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),
- TotalNumSelectors(0), NumStatHits(0), NumStatMisses(0),
+ TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot),
+ NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), NumStatementsRead(0),
NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
- CurrentlyLoadingTypeOrDecl(0) { }
+ CurrentlyLoadingTypeOrDecl(0) {
+ RelocatablePCH = false;
+}
PCHReader::~PCHReader() {}
@@ -652,8 +659,7 @@ bool PCHReader::CheckPredefinesBuffer(const char *PCHPredef,
/// \brief Read the line table in the source manager block.
/// \returns true if ther was an error.
-static bool ParseLineTable(SourceManager &SourceMgr,
- llvm::SmallVectorImpl<uint64_t> &Record) {
+bool PCHReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) {
unsigned Idx = 0;
LineTableInfo &LineTable = SourceMgr.getLineTable();
@@ -664,6 +670,7 @@ static bool ParseLineTable(SourceManager &SourceMgr,
unsigned FilenameLen = Record[Idx++];
std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
Idx += FilenameLen;
+ MaybeAddSystemRootToFilename(Filename);
FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
Filename.size());
}
@@ -859,7 +866,7 @@ PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
break;
case pch::SM_LINE_TABLE:
- if (ParseLineTable(SourceMgr, Record))
+ if (ParseLineTable(Record))
return Failure;
break;
@@ -912,10 +919,12 @@ PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {
return Failure;
case pch::SM_SLOC_FILE_ENTRY: {
- const FileEntry *File = FileMgr.getFile(BlobStart, BlobStart + BlobLen);
+ std::string Filename(BlobStart, BlobStart + BlobLen);
+ MaybeAddSystemRootToFilename(Filename);
+ const FileEntry *File = FileMgr.getFile(Filename);
if (File == 0) {
std::string ErrorStr = "could not find file '";
- ErrorStr.append(BlobStart, BlobLen);
+ ErrorStr += Filename;
ErrorStr += "' referenced by PCH file";
Error(ErrorStr.c_str());
return Failure;
@@ -1096,6 +1105,32 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {
}
}
+/// \brief If we are loading a relocatable PCH file, and the filename is
+/// not an absolute path, add the system root to the beginning of the file
+/// name.
+void PCHReader::MaybeAddSystemRootToFilename(std::string &Filename) {
+ // If this is not a relocatable PCH file, there's nothing to do.
+ if (!RelocatablePCH)
+ return;
+
+ if (Filename.empty() || Filename[0] == '/' || Filename[0] == '<')
+ return;
+
+ std::string FIXME = Filename;
+
+ if (isysroot == 0) {
+ // If no system root was given, default to '/'
+ Filename.insert(Filename.begin(), '/');
+ return;
+ }
+
+ unsigned Length = strlen(isysroot);
+ if (isysroot[Length - 1] != '/')
+ Filename.insert(Filename.begin(), '/');
+
+ Filename.insert(Filename.begin(), isysroot, isysroot + Length);
+}
+
PCHReader::PCHReadResult
PCHReader::ReadPCHBlock() {
if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
@@ -1208,6 +1243,7 @@ PCHReader::ReadPCHBlock() {
return IgnorePCH;
}
+ RelocatablePCH = Record[4];
if (Listener) {
std::string TargetTriple(BlobStart, BlobLen);
if (Listener->ReadTargetTriple(TargetTriple))
@@ -1338,6 +1374,7 @@ PCHReader::ReadPCHBlock() {
case pch::ORIGINAL_FILE_NAME:
OriginalFileName.assign(BlobStart, BlobLen);
+ MaybeAddSystemRootToFilename(OriginalFileName);
break;
case pch::COMMENT_RANGES:
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index fee2137314..566df350f6 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -476,11 +476,68 @@ void PCHWriter::WriteBlockInfoBlock() {
Stream.ExitBlock();
}
+/// \brief Adjusts the given filename to only write out the portion of the
+/// filename that is not part of the system root directory.
+///
+/// \param Filename the file name to adjust.
+///
+/// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and
+/// the returned filename will be adjusted by this system root.
+///
+/// \returns either the original filename (if it needs no adjustment) or the
+/// adjusted filename (which points into the @p Filename parameter).
+static const char *
+adjustFilenameForRelocatablePCH(const char *Filename, const char *isysroot) {
+ assert(Filename && "No file name to adjust?");
+
+ if (!isysroot)
+ return Filename;
+
+ // Verify that the filename and the system root have the same prefix.
+ unsigned Pos = 0;
+ for (; Filename[Pos] && isysroot[Pos]; ++Pos)
+ if (Filename[Pos] != isysroot[Pos])
+ return Filename; // Prefixes don't match.
+
+ // We hit the end of the filename before we hit the end of the system root.
+ if (!Filename[Pos])
+ return Filename;
+
+ // If the file name has a '/' at the current position, skip over the '/'.
+ // We distinguish sysroot-based includes from absolute includes by the
+ // absence of '/' at the beginning of sysroot-based includes.
+ if (Filename[Pos] == '/')
+ ++Pos;
+
+ return Filename + Pos;
+}
/// \brief Write the PCH metadata (e.g., i686-apple-darwin9).
-void PCHWriter::WriteMetadata(ASTContext &Context) {
+void PCHWriter::WriteMetadata(ASTContext &Context, const char *isysroot) {
using namespace llvm;
+ // Metadata
+ const TargetInfo &Target = Context.Target;
+ BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev();
+ MetaAbbrev->Add(BitCodeAbbrevOp(pch::METADATA));
+ MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH major
+ MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH minor
+ MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major
+ MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor
+ MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
+ MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple
+ unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
+
+ RecordData Record;
+ Record.push_back(pch::METADATA);
+ Record.push_back(pch::VERSION_MAJOR);
+ Record.push_back(pch::VERSION_MINOR);
+ Record.push_back(CLANG_VERSION_MAJOR);
+ Record.push_back(CLANG_VERSION_MINOR);
+ Record.push_back(isysroot != 0);
+ const char *Triple = Target.getTargetTriple();
+ Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, Triple, strlen(Triple));
+
// Original file name
SourceManager &SM = Context.getSourceManager();
if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
@@ -500,31 +557,14 @@ void PCHWriter::WriteMetadata(ASTContext &Context) {
MainFileName = MainFilePath.toString();
}
+ const char *MainFileNameStr = MainFileName.c_str();
+ MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr,
+ isysroot);
RecordData Record;
Record.push_back(pch::ORIGINAL_FILE_NAME);
- Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileName.c_str(),
- MainFileName.size());
+ Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr,
+ strlen(MainFileNameStr));
}
-
- // Metadata
- const TargetInfo &Target = Context.Target;
- BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev();
- MetaAbbrev->Add(BitCodeAbbrevOp(pch::METADATA));
- MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH major
- MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // PCH minor
- MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major
- MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor
- MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple
- unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
-
- RecordData Record;
- Record.push_back(pch::METADATA);
- Record.push_back(pch::VERSION_MAJOR);
- Record.push_back(pch::VERSION_MINOR);
- Record.push_back(CLANG_VERSION_MAJOR);
- Record.push_back(CLANG_VERSION_MINOR);
- const char *Triple = Target.getTargetTriple();
- Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, Triple, strlen(Triple));
}
/// \brief Write the LangOptions structure.
@@ -649,15 +689,19 @@ public:
} // end anonymous namespace
/// \brief Write the stat() system call cache to the PCH file.
-void PCHWriter::WriteStatCache(MemorizeStatCalls &StatCalls) {
+void PCHWriter::WriteStatCache(MemorizeStatCalls &StatCalls,
+ const char *isysroot) {
// Build the on-disk hash table containing information about every
// stat() call.
OnDiskChainedHashTableGenerator<PCHStatCacheTrait> Generator;
unsigned NumStatEntries = 0;
for (MemorizeStatCalls::iterator Stat = StatCalls.begin(),
StatEnd = StatCalls.end();
- Stat != StatEnd; ++Stat, ++NumStatEntries)
- Generator.insert(Stat->first(), Stat->second);
+ Stat != StatEnd; ++Stat, ++NumStatEntries) {
+ const char *Filename = Stat->first();
+ Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
+ Generator.insert(Filename, Stat->second);
+ }
// Create the on-disk hash table in a buffer.
llvm::SmallVector<char, 4096> StatCacheData;
@@ -753,7 +797,8 @@ static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &Stream) {
/// errors), we probably won't have to create file entries for any of
/// the files in the AST.
void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
- const Preprocessor &PP) {
+ const Preprocessor &PP,
+ const char *isysroot) {
RecordData Record;
// Enter the source manager block.
@@ -774,6 +819,7 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
// Emit the file name
const char *Filename = LineTable.getFilename(I);
+ Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
unsigned FilenameLen = Filename? strlen(Filename) : 0;
Record.push_back(FilenameLen);
if (FilenameLen)
@@ -850,9 +896,21 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
if (Content->Entry) {
// The source location entry is a file. The blob associated
// with this entry is the file name.
- Stream.EmitRecordWithBlob(SLocFileAbbrv, Record,
- Content->Entry->getName(),
- strlen(Content->Entry->getName()));
+
+ // 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));
+ std::string FilenameStr;
+ if (!FilePath.isAbsolute()) {
+ llvm::sys::Path P = llvm::sys::Path::GetCurrentDirectory();
+ P.appendComponent(FilePath.toString());
+ FilenameStr = P.toString();
+ Filename = FilenameStr.c_str();
+ }
+
+ Filename = adjustFilenameForRelocatablePCH(Filename, isysroot);
+ Stream.EmitRecordWithBlob(SLocFileAbbrv, Record, Filename,
+ strlen(Filename));
// FIXME: For now, preload all file source locations, so that
// we get the appropriate File entries in the reader. This is
@@ -1716,7 +1774,8 @@ PCHWriter::PCHWriter(llvm::BitstreamWriter &Stream)
NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0),
NumVisibleDeclContexts(0) { }
-void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls) {
+void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
+ const char *isysroot) {
using namespace llvm;
ASTContext &Context = SemaRef.Context;
@@ -1778,11 +1837,11 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls) {
// Write the remaining PCH contents.
RecordData Record;
Stream.EnterSubblock(pch::PCH_BLOCK_ID, 4);
- WriteMetadata(Context);
+ WriteMetadata(Context, isysroot);
WriteLanguageOptions(Context.getLangOptions());
- if (StatCalls)
- WriteStatCache(*StatCalls);
- WriteSourceManagerBlock(Context.getSourceManager(), PP);
+ if (StatCalls && !isysroot)
+ WriteStatCache(*StatCalls, isysroot);
+ WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
WritePreprocessor(PP);
WriteComments(Context);