Implement handling of file entry/exit notifications from GNU
line markers, including maintenance of the virtual include stack.
For something like this:
# 42 "bar.c" 1
# 142 "bar2.c" 1
#warning zappa
# 92 "bar.c" 2
#warning gonzo
# 102 "foo.c" 2
#warning bonkta
we now produce these three warnings:
#1:
In file included from foo.c:3:
In file included from bar.c:42:
bar2.c:143:2: warning: #warning zappa
#warning zappa
^
#2:
In file included from foo.c:3:
bar.c:92:2: warning: #warning gonzo
#warning gonzo
^
#3:
foo.c:102:2: warning: #warning bonkta
#warning bonkta
^
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63722 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index a77f853..cc75b87 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -76,13 +76,20 @@
/// Flags - Set the 0 if no flags, 1 if a system header,
SrcMgr::CharacteristicKind FileKind;
+ /// IncludeOffset - This is the offset of the virtual include stack location,
+ /// which is manipulated by GNU linemarker directives. If this is 0 then
+ /// there is no virtual #includer.
+ unsigned IncludeOffset;
+
static LineEntry get(unsigned Offs, unsigned Line, int Filename,
- SrcMgr::CharacteristicKind FileKind) {
+ SrcMgr::CharacteristicKind FileKind,
+ unsigned IncludeOffset) {
LineEntry E;
E.FileOffset = Offs;
E.LineNo = Line;
E.FilenameID = Filename;
E.FileKind = FileKind;
+ E.IncludeOffset = IncludeOffset;
return E;
}
};
@@ -164,6 +171,7 @@
"Adding line entries out of order!");
SrcMgr::CharacteristicKind Kind = SrcMgr::C_User;
+ unsigned IncludeOffset = 0;
if (!Entries.empty()) {
// If this is a '#line 4' after '#line 42 "foo.h"', make sure to remember
@@ -171,12 +179,14 @@
if (FilenameID == -1)
FilenameID = Entries.back().FilenameID;
- // If we are after a line marker that switched us to system header mode,
- // preserve it.
+ // If we are after a line marker that switched us to system header mode, or
+ // that set #include information, preserve it.
Kind = Entries.back().FileKind;
+ IncludeOffset = Entries.back().IncludeOffset;
}
- Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind));
+ Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, Kind,
+ IncludeOffset));
}
/// AddLineNote This is the same as the previous version of AddLineNote, but is
@@ -195,10 +205,24 @@
assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
"Adding line entries out of order!");
+ unsigned IncludeOffset = 0;
+ if (EntryExit == 0) { // No #include stack change.
+ IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
+ } else if (EntryExit == 1) {
+ IncludeOffset = Offset-1;
+ } else if (EntryExit == 2) {
+ assert(!Entries.empty() && Entries.back().IncludeOffset &&
+ "PPDirectives should have caught case when popping empty include stack");
+
+ // Get the include loc of the last entries' include loc as our include loc.
+ IncludeOffset = 0;
+ if (const LineEntry *PrevEntry =
+ FindNearestLineEntry(FID, Entries.back().IncludeOffset))
+ IncludeOffset = PrevEntry->IncludeOffset;
+ }
- // TODO: Handle EntryExit.
-
- Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind));
+ Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind,
+ IncludeOffset));
}
@@ -831,6 +855,12 @@
LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
// Note that column numbers are not molested by line markers.
+
+ // Handle virtual #include manipulation.
+ if (Entry->IncludeOffset) {
+ IncludeLoc = getLocForStartOfFile(LocInfo.first);
+ IncludeLoc = IncludeLoc.getFileLocWithOffset(Entry->IncludeOffset);
+ }
}
}