[FileCheck] Annotate input dump (3/7)

This patch implements input annotations for diagnostics that report
wrong-line matches for the directives CHECK-NEXT, CHECK-SAME, and
CHECK-EMPTY.  Instead of the usual `^~~`, which is used by later
patches for good matches, these annotations use `!~~` to mark the bad
match ranges so that this category of errors is visually distinct.
Because such matches are errors, these annotates are red when colors
are enabled.

For example:

```
$ FileCheck -dump-input=help
The following description was requested by -dump-input=help to
explain the input annotations printed by -dump-input=always and
-dump-input=fail:

  - L:     labels line number L of the input file
  - T:L    labels the only match result for a pattern of type T from line L of
           the check file
  - T:L'N  labels the Nth match result for a pattern of type T from line L of
           the check file
  - !~~    marks bad match, such as:
           - CHECK-NEXT on same line as previous match (error)
  - X~~    marks search range when no match is found, such as:
           - CHECK-NEXT not found (error)
  - ?      marks fuzzy match when no match is found
  - colors error, fuzzy match

If you are not seeing color above or in input dumps, try: -color

$ FileCheck -v -dump-input=always check2 < input2 |& sed -n '/^<<<</,$p'
<<<<<<
        1: foo bar
next:2         !~~ error: match on wrong line
>>>>>>

$ cat check2
CHECK: foo
CHECK-NEXT: bar

$ cat input2
foo bar
```

Reviewed By: george.karpenkov, probinson

Differential Revision: https://reviews.llvm.org/D53894

llvm-svn: 349420
This commit is contained in:
Joel E. Denny 2018-12-18 00:02:22 +00:00
parent 61415aec0d
commit dac11cd74f
4 changed files with 81 additions and 7 deletions

View File

@ -163,6 +163,9 @@ struct FileCheckDiag {
/// example, there might be a fuzzy match after a fail.
enum MatchType {
// TODO: More members will appear with later patches in this series.
/// Indicates the final match for an expected pattern, but the match is on
/// the wrong line.
MatchFinalButWrongLine,
/// Indicates no match for an expected pattern.
MatchNoneButExpected,
/// Indicates a possible intended match because there's no perfect match.

View File

@ -1047,17 +1047,27 @@ size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
// Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
// or CHECK-NOT
if (!IsLabelScanMode) {
StringRef SkippedRegion = Buffer.substr(LastPos, FirstMatchPos - LastPos);
size_t MatchPos = FirstMatchPos - LastPos;
StringRef MatchBuffer = Buffer.substr(LastPos);
StringRef SkippedRegion = Buffer.substr(LastPos, MatchPos);
// If this check is a "CHECK-NEXT", verify that the previous match was on
// the previous line (i.e. that there is one newline between them).
if (CheckNext(SM, SkippedRegion))
if (CheckNext(SM, SkippedRegion)) {
ProcessMatchResult(FileCheckDiag::MatchFinalButWrongLine, SM, Loc,
Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
Diags);
return StringRef::npos;
}
// If this check is a "CHECK-SAME", verify that the previous match was on
// the same line (i.e. that there is no newline between them).
if (CheckSame(SM, SkippedRegion))
if (CheckSame(SM, SkippedRegion)) {
ProcessMatchResult(FileCheckDiag::MatchFinalButWrongLine, SM, Loc,
Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
Diags);
return StringRef::npos;
}
// If this match had "not strings", verify that they don't exist in the
// skipped region.

View File

@ -90,7 +90,7 @@
; CNT-NOT: {{.}}
;--------------------------------------------------
; CHECK-NEXT (also: EOF search-range)
; CHECK-NEXT (also: EOF search-range, wrong-line match)
;--------------------------------------------------
; Good match and no match.
@ -117,8 +117,25 @@
; NXT-NEXT: >>>>>>
; NXT-NOT: {{.}}
; Wrong-line match.
; RUN: echo 'yonder' >> %t.in
; RUN: echo 'world' >> %t.in
; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk 2>&1 \
; RUN: | FileCheck -match-full-lines %s -check-prefix=NXT2
; NXT2: <<<<<<
; NXT2-NEXT: 1: hello
; NXT2-NEXT: 2: again
; NXT2-NEXT: 3: yonder
; NXT2-NEXT: 4: world
; NXT2-NEXT: next:3 !~~~~ error: match on wrong line
; NXT2-NEXT: >>>>>>
; NXT2-NOT: {{.}}
;--------------------------------------------------
; CHECK-SAME (also: single-char search range)
; CHECK-SAME (also: single-char search range, wrong-line match)
;--------------------------------------------------
; Good match and no match.
@ -142,8 +159,22 @@
; SAM-NEXT: >>>>>>
; SAM-NOT: {{.}}
; Wrong-line match.
; RUN: echo 'again' >> %t.in
; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -v 2>&1 \
; RUN: | FileCheck -match-full-lines %s -check-prefixes=SAM2
; SAM2: <<<<<<
; SAM2-NEXT: 1: hello world!
; SAM2-NEXT: 2: again
; SAM2-NEXT: same:3 !~~~~ error: match on wrong line
; SAM2-NEXT: >>>>>>
; SAM2-NOT: {{.}}
;--------------------------------------------------
; CHECK-EMPTY (also: search range ends at label)
; CHECK-EMPTY (also: search range ends at label, wrong-line match)
;--------------------------------------------------
; Good match and no match.
@ -180,6 +211,29 @@
; EMP-NEXT: >>>>>>
; EMP-NOT: {{.}}
; Wrong-line match.
; RUN: echo 'hello' > %t.in
; RUN: echo 'world' >> %t.in
; RUN: echo 'CHECK: hello' > %t.chk
; RUN: echo 'CHECK-EMPTY:' >> %t.chk
; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk 2>&1 \
; RUN: | FileCheck -match-full-lines %s -check-prefix=EMP2
; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -v 2>&1 \
; RUN: | FileCheck -match-full-lines %s -check-prefixes=EMP2,EMP2-V
; RUN: not FileCheck -dump-input=always -input-file %t.in %t.chk -vv 2>&1 \
; RUN: | FileCheck -match-full-lines %s -check-prefixes=EMP2,EMP2-V,EMP2-VV
; EMP2: <<<<<<
; EMP2-NEXT: 1: hello
; EMP2-NEXT: 2: world
; EMP2-NEXT: 3:
; EMP2-NEXT: empty:2 ! error: match on wrong line
; EMP2-NEXT: >>>>>>
; EMP2-NOT: {{.}}
;--------------------------------------------------
; CHECK-DAG
;--------------------------------------------------

View File

@ -143,6 +143,8 @@ struct MarkerStyle {
static MarkerStyle GetMarker(FileCheckDiag::MatchType MatchTy) {
switch (MatchTy) {
case FileCheckDiag::MatchFinalButWrongLine:
return MarkerStyle('!', raw_ostream::RED, "error: match on wrong line");
case FileCheckDiag::MatchNoneButExpected:
return MarkerStyle('X', raw_ostream::RED, "error: no match found");
case FileCheckDiag::MatchFuzzy:
@ -177,8 +179,13 @@ static void DumpInputAnnotationHelp(raw_ostream &OS) {
// Markers on annotation lines.
OS << " - ";
WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "!~~";
OS << " marks bad match, such as:\n"
<< " - CHECK-NEXT on same line as previous match (error)\n"
<< " - ";
WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "X~~";
OS << " marks search range when no match is found\n"
OS << " marks search range when no match is found, such as:\n"
<< " - CHECK-NEXT not found (error)\n"
<< " - ";
WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "?";
OS << " marks fuzzy match when no match is found\n";