[cfe-commits] [PATCH] PR6101: Preprocessor doesn't honor #line directives

Jordy Rose jediknil at belkadan.com
Mon Apr 12 23:33:07 PDT 2010


On Mon, 12 Apr 2010 21:33:20 -0700, Chris Lattner <clattner at apple.com>
wrote:
> On Apr 12, 2010, at 9:12 PM, Jordy Rose wrote:
>> If !IsLineDirective (either of those cases), adding 1 to
>> UserLoc.getLine()
>> is incorrect -- we're actually entering or exiting a file instead of
just
>> reading a directive. Special-casing the main file isn't correct either;
>> it
>> also affects #includes.
>> 
>> I certainly don't like these contortions, but without adding an
>> IsLineDirective parameter to the method, I'm not sure if there's a
better
>> way.
> 
> Is it possible to change the linemarker code to pass in the right
> location?  I tried for a couple hours and couldn't get it right... I
> stopped caring, and decided that this was a big enough improvement in
the
> status quo :)
> 
> -Chris

This seems to do it: passing the location /after/ the directive to the
callback, instead of the location of the digit token. I think this still
makes semantic sense: the "new file" starts after the line. And this is
just for PPCallbacks; the real compiler still makes line notes the same way
as before.

The one problem is when the very last line of a file is a #line directive
or the return from an #include, and the file has no final newline. In these
cases the emitted linemarker is off by one (since the lexer position can't
advance to the next line). I included an XFAILing test case for this, but
it probably doesn't matter: if we're at EOF, the directive won't affect any
real code anyway!

Jordy

-------------- next part --------------
Index: test/Preprocessor/line-directive-at-eof.c
===================================================================
--- test/Preprocessor/line-directive-at-eof.c	(revision 0)
+++ test/Preprocessor/line-directive-at-eof.c	(revision 0)
@@ -0,0 +1,8 @@
+// XFAIL: *
+// RUN: %clang_cc1 -E %s 2>&1 | FileCheck %s -strict-whitespace
+
+// CHECK: # 5 "{{.*}}line-directive-at-eof.c"
+#line 5
+int x;
+// CHECK: # 8 "{{.*}}line-directive-at-eof.c"
+#line 8
\ No newline at end of file
Index: test/Preprocessor/line-directive-output.c
===================================================================
--- test/Preprocessor/line-directive-output.c	(revision 101109)
+++ test/Preprocessor/line-directive-output.c	(working copy)
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -E %s 2>&1 | FileCheck %s -strict-whitespace
 // PR6101
 int a;
-// CHECK: # 2 "{{.*}}line-directive-output.c"
+// CHECK: # 1 "{{.*}}line-directive-output.c"
 // CHECK: int a;
 
 // CHECK-NEXT: # 50 "{{.*}}line-directive-output.c"
Index: lib/Frontend/PrintPreprocessedOutput.cpp
===================================================================
--- lib/Frontend/PrintPreprocessedOutput.cpp	(revision 101109)
+++ lib/Frontend/PrintPreprocessedOutput.cpp	(working copy)
@@ -218,7 +218,7 @@
   SourceManager &SourceMgr = SM;
   
   PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
-  unsigned NewLine = UserLoc.getLine()+1;
+  unsigned NewLine = UserLoc.getLine();
   
   if (Reason == PPCallbacks::EnterFile) {
     SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
Index: lib/Lex/PPDirectives.cpp
===================================================================
--- lib/Lex/PPDirectives.cpp	(revision 101109)
+++ lib/Lex/PPDirectives.cpp	(working copy)
@@ -716,7 +716,8 @@
   SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID);
 
   if (Callbacks)
-    Callbacks->FileChanged(DigitTok.getLocation(), PPCallbacks::RenameFile,
+    Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
+                           PPCallbacks::RenameFile,
                            SrcMgr::C_User);
 }
 
@@ -865,7 +866,7 @@
     else if (IsSystemHeader)
       FileKind = SrcMgr::C_System;
 
-    Callbacks->FileChanged(DigitTok.getLocation(), Reason, FileKind);
+    Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
   }
 }
 


More information about the cfe-commits mailing list