]> granicus.if.org Git - clang/commitdiff
Fix off-by-one error in #pragma clang system_header.
authorJordan Rose <jordan_rose@apple.com>
Wed, 17 Apr 2013 19:09:18 +0000 (19:09 +0000)
committerJordan Rose <jordan_rose@apple.com>
Wed, 17 Apr 2013 19:09:18 +0000 (19:09 +0000)
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

lib/Frontend/PrintPreprocessedOutput.cpp
lib/Lex/Pragma.cpp
test/Preprocessor/pragma_sysheader.c

index 180c1774446c79678ad630124992b2f8e4e8e16f..61f2b9e288420a976448225fc37714afa02dc197 100644 (file)
@@ -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;
index bc77c5adcf960a87769bf31118f43783805c4305..b5a76fd3cb223563db26007508f43451053123b0 100644 (file)
@@ -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.
index 075c9803a507f4f810f076478a6fbc902e9dea28..3c94363152af7076a07e2c68820d0aed376a4760 100644 (file)
@@ -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