vsk created this revision. This patch teaches the preprocessor to report more precise source ranges for code that is skipped due to conditional directives.
The new behavior includes the '#' from the opening directive and the full text of the line containing the closing directive in the skipped area. This matches up clang's behavior (we don't IRGen the code between the closing "endif" and the end of a line). This also affects the code coverage implementation. See llvm.org/PR34166 (this also happens to be rdar://problem/23224058). https://reviews.llvm.org/D36642 Files: lib/Lex/PPDirectives.cpp test/CoverageMapping/preprocessor.c test/Index/skipped-ranges.c Index: test/Index/skipped-ranges.c =================================================================== --- test/Index/skipped-ranges.c +++ test/Index/skipped-ranges.c @@ -20,6 +20,6 @@ #endif // cool // RUN: env CINDEXTEST_SHOW_SKIPPED_RANGES=1 c-index-test -test-annotate-tokens=%s:1:1:16:1 %s | FileCheck %s -// CHECK: Skipping: [5:2 - 6:7] -// CHECK: Skipping: [8:2 - 12:7] -// CHECK: Skipping: [14:2 - 20:7] +// CHECK: Skipping: [5:1 - 6:22] +// CHECK: Skipping: [8:1 - 12:27] +// CHECK: Skipping: [14:1 - 20:15] Index: test/CoverageMapping/preprocessor.c =================================================================== --- test/CoverageMapping/preprocessor.c +++ test/CoverageMapping/preprocessor.c @@ -3,7 +3,7 @@ // CHECK: func void func() { // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+5]]:2 = #0 int i = 0; -#ifdef MACRO // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+2]]:2 = 0 +#ifdef MACRO // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+2]]:7 = 0 int x = i; #endif } @@ -17,18 +17,18 @@ // CHECK: main int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0 int i = 0; -#if 0 // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+4]]:2 = 0 +# if 0 // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+4]]:29 = 0 if(i == 0) { i = 1; } -#endif +# endif // Mark me skipped! #if 1 // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0 if(i == 0) { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #1 i = 1; } -#else // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+5]]:2 = 0 +#else // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+5]]:7 = 0 if(i == 1) { i = 0; } Index: lib/Lex/PPDirectives.cpp =================================================================== --- lib/Lex/PPDirectives.cpp +++ lib/Lex/PPDirectives.cpp @@ -559,8 +559,28 @@ CurPPLexer->LexingRawMode = false; if (Callbacks) { + const auto &SM = getSourceManager(); SourceLocation BeginLoc = ElseLoc.isValid() ? ElseLoc : IfTokenLoc; - Callbacks->SourceRangeSkipped(SourceRange(BeginLoc, Tok.getLocation())); + + // The begin loc tells us the start location of the directive, but we want + // to include the hash ('#') at the start of the line. + SourceLocation HashBeginLoc = + BeginLoc.getLocWithOffset(-SM.getSpellingColumnNumber(BeginLoc) + 1); + + // We also want to skip the entire line containing the closing directive. + const char *TokStart = SM.getCharacterData(Tok.getLocation()); + const char *EndOfLine = TokStart; + while (true) { + char C = *EndOfLine; + // We'll warn about reaching the end of file later. + if (C == '\0' || C == '\r' || C == '\n') + break; + ++EndOfLine; + } + SourceLocation DirectiveEndLoc = + Tok.getLocation().getLocWithOffset(EndOfLine - TokStart); + + Callbacks->SourceRangeSkipped(SourceRange(HashBeginLoc, DirectiveEndLoc)); } }
Index: test/Index/skipped-ranges.c =================================================================== --- test/Index/skipped-ranges.c +++ test/Index/skipped-ranges.c @@ -20,6 +20,6 @@ #endif // cool // RUN: env CINDEXTEST_SHOW_SKIPPED_RANGES=1 c-index-test -test-annotate-tokens=%s:1:1:16:1 %s | FileCheck %s -// CHECK: Skipping: [5:2 - 6:7] -// CHECK: Skipping: [8:2 - 12:7] -// CHECK: Skipping: [14:2 - 20:7] +// CHECK: Skipping: [5:1 - 6:22] +// CHECK: Skipping: [8:1 - 12:27] +// CHECK: Skipping: [14:1 - 20:15] Index: test/CoverageMapping/preprocessor.c =================================================================== --- test/CoverageMapping/preprocessor.c +++ test/CoverageMapping/preprocessor.c @@ -3,7 +3,7 @@ // CHECK: func void func() { // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+5]]:2 = #0 int i = 0; -#ifdef MACRO // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+2]]:2 = 0 +#ifdef MACRO // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+2]]:7 = 0 int x = i; #endif } @@ -17,18 +17,18 @@ // CHECK: main int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0 int i = 0; -#if 0 // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+4]]:2 = 0 +# if 0 // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+4]]:29 = 0 if(i == 0) { i = 1; } -#endif +# endif // Mark me skipped! #if 1 // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0 if(i == 0) { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #1 i = 1; } -#else // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+5]]:2 = 0 +#else // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+5]]:7 = 0 if(i == 1) { i = 0; } Index: lib/Lex/PPDirectives.cpp =================================================================== --- lib/Lex/PPDirectives.cpp +++ lib/Lex/PPDirectives.cpp @@ -559,8 +559,28 @@ CurPPLexer->LexingRawMode = false; if (Callbacks) { + const auto &SM = getSourceManager(); SourceLocation BeginLoc = ElseLoc.isValid() ? ElseLoc : IfTokenLoc; - Callbacks->SourceRangeSkipped(SourceRange(BeginLoc, Tok.getLocation())); + + // The begin loc tells us the start location of the directive, but we want + // to include the hash ('#') at the start of the line. + SourceLocation HashBeginLoc = + BeginLoc.getLocWithOffset(-SM.getSpellingColumnNumber(BeginLoc) + 1); + + // We also want to skip the entire line containing the closing directive. + const char *TokStart = SM.getCharacterData(Tok.getLocation()); + const char *EndOfLine = TokStart; + while (true) { + char C = *EndOfLine; + // We'll warn about reaching the end of file later. + if (C == '\0' || C == '\r' || C == '\n') + break; + ++EndOfLine; + } + SourceLocation DirectiveEndLoc = + Tok.getLocation().getLocWithOffset(EndOfLine - TokStart); + + Callbacks->SourceRangeSkipped(SourceRange(HashBeginLoc, DirectiveEndLoc)); } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits