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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits