Redo how PCH handles its implicit include. Instead of treating this specially in
the front-end (as far as the preprocessor goes), follow the usual logic of
inserting the (original include path) name into the predefines buffer. This
pushes the responsibility for handling this to PCH instead of the front-end. In
PCH this requires being a little more clever when we diff the predefines
buffers.
Neither of these solutions are particularly great, I think what we eventually
should do is something like gcc where we insert a special marker to indicate the
PCH file, but then run the preprocessor as usual. This would be clearer and
would allow us to drop the overly clever predefines handling.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86806 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index b5e6558..82786aa 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -68,6 +68,7 @@
virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef,
FileID PCHBufferID,
+ llvm::StringRef OriginalFileName,
std::string &SuggestedPredefines) {
Predefines = PCHPredef;
return false;
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 42aa43b..9363824 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -156,17 +156,34 @@
bool PCHValidator::ReadPredefinesBuffer(llvm::StringRef PCHPredef,
FileID PCHBufferID,
+ llvm::StringRef OriginalFileName,
std::string &SuggestedPredefines) {
- // If the two predefines buffers compare equal, we're done!
- if (PP.getPredefines() == PCHPredef)
+ // We are in the context of an implicit include, so the predefines buffer
+ // will have a #include entry for the PCH file itself. Find it and skip over
+ // it in the checking below.
+ llvm::SmallString<256> PCHInclude;
+ PCHInclude += "#include \"";
+ PCHInclude += OriginalFileName;
+ PCHInclude += "\"\n";
+ std::pair<llvm::StringRef,llvm::StringRef> Split =
+ llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
+ llvm::StringRef Left = Split.first, Right = Split.second;
+ assert(Left != PP.getPredefines() && "Missing PCH include entry!");
+
+ // If the predefines is equal to the joined left and right halves, we're done!
+ if (Left.size() + Right.size() == PCHPredef.size() &&
+ PCHPredef.startswith(Left) && PCHPredef.endswith(Right))
return false;
SourceManager &SourceMgr = PP.getSourceManager();
// The predefines buffers are different. Determine what the differences are,
// and whether they require us to reject the PCH file.
- std::vector<llvm::StringRef> CmdLineLines = splitLines(PP.getPredefines());
std::vector<llvm::StringRef> PCHLines = splitLines(PCHPredef);
+ std::vector<llvm::StringRef> CmdLineLines = splitLines(Left);
+ std::vector<llvm::StringRef> CmdLineLinesRight = splitLines(Right);
+ CmdLineLines.insert(CmdLineLines.end(),
+ CmdLineLinesRight.begin(), CmdLineLinesRight.end());
// Sort both sets of predefined buffer lines, since we allow some extra
// definitions and they may appear at any point in the output.
@@ -624,6 +641,7 @@
FileID PCHBufferID) {
if (Listener)
return Listener->ReadPredefinesBuffer(PCHPredef, PCHBufferID,
+ ActualOriginalFileName,
SuggestedPredefines);
return false;
}
@@ -1333,7 +1351,8 @@
break;
case pch::ORIGINAL_FILE_NAME:
- OriginalFileName.assign(BlobStart, BlobLen);
+ ActualOriginalFileName.assign(BlobStart, BlobLen);
+ OriginalFileName = ActualOriginalFileName;
MaybeAddSystemRootToFilename(OriginalFileName);
break;