aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-04-17 19:09:18 +0000
committerJordan Rose <jordan_rose@apple.com>2013-04-17 19:09:18 +0000
commit142b35e25b579e2a883d6ca37c3c1121f562f242 (patch)
tree1c63dfe94854deaac1a487b63654734f6d609bed
parent987c03085558277a5fe8cef8e1b628cabcc626dc (diff)
Fix off-by-one error in #pragma clang system_header.
The system_header pragma (from GCC) is implemented using line notes in the source manager. However, a line note's line number specifies the number not for the current line, but for the next line. This was making all line numbers appear off by one after the pragma. Reported by Andy Gibbs, uncovered during r179677. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179709 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp11
-rw-r--r--lib/Lex/Pragma.cpp5
-rw-r--r--test/Preprocessor/pragma_sysheader.c2
3 files changed, 10 insertions, 8 deletions
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 180c177444..61f2b9e288 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -270,11 +270,12 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
if (IncludeLoc.isValid())
MoveToLine(IncludeLoc);
} else if (Reason == PPCallbacks::SystemHeaderPragma) {
- MoveToLine(NewLine);
-
- // TODO GCC emits the # directive for this directive on the line AFTER the
- // directive and emits a bunch of spaces that aren't needed. Emulate this
- // strange behavior.
+ // GCC emits the # directive for this directive on the line AFTER the
+ // directive and emits a bunch of spaces that aren't needed. This is because
+ // otherwise we will emit a line marker for THIS line, which requires an
+ // extra blank line after the directive to avoid making all following lines
+ // off by one. We can do better by simply incrementing NewLine here.
+ NewLine += 1;
}
CurLine = NewLine;
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index bc77c5adcf..b5a76fd3cb 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -434,8 +434,9 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
// Emit a line marker. This will change any source locations from this point
// forward to realize they are in a system header.
// Create a line note with this information.
- SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine(), FilenameID,
- false, false, true, false);
+ SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine()+1,
+ FilenameID, /*IsEntry=*/false, /*IsExit=*/false,
+ /*IsSystem=*/true, /*IsExternC=*/false);
}
/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
diff --git a/test/Preprocessor/pragma_sysheader.c b/test/Preprocessor/pragma_sysheader.c
index 075c9803a5..3c94363152 100644
--- a/test/Preprocessor/pragma_sysheader.c
+++ b/test/Preprocessor/pragma_sysheader.c
@@ -7,7 +7,7 @@
// PR9861: Verify that line markers are not messed up in -E mode.
// CHECK: # 1 "{{.*}}pragma_sysheader.h" 1
-// CHECK-NEXT: # 1 "{{.*}}pragma_sysheader.h" 3
+// CHECK-NEXT: # 2 "{{.*}}pragma_sysheader.h" 3
// CHECK-NEXT: typedef int x;
// CHECK-NEXT: typedef int x;
// CHECK-NEXT: # 6 "{{.*}}pragma_sysheader.c" 2