diff options
| author | Joel E. Denny <jdenny.ornl@gmail.com> | 2018-12-18 00:03:03 +0000 |
|---|---|---|
| committer | Joel E. Denny <jdenny.ornl@gmail.com> | 2018-12-18 00:03:03 +0000 |
| commit | 7df86967b46b4e857033b8a3d4a3db8ee9882351 (patch) | |
| tree | 5ad33a94d08bd89980fd909e06a400f4c3ab2420 /llvm/utils/FileCheck | |
| parent | 0e7e3fa0e9a5dac6bf42f4771768968460ab48a8 (diff) | |
| download | bcm5719-llvm-7df86967b46b4e857033b8a3d4a3db8ee9882351.tar.gz bcm5719-llvm-7df86967b46b4e857033b8a3d4a3db8ee9882351.zip | |
[FileCheck] Annotate input dump (5/7)
This patch implements input annotations for diagnostics enabled by -v,
which report good matches for directives. These annotations mark
match ranges using `^~~`.
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 good match (reported if -v)
- !~~ marks bad match, such as:
- CHECK-NEXT on same line as previous match (error)
- CHECK-NOT found (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 success, error, fuzzy match, unmatched input
If you are not seeing color above or in input dumps, try: -color
$ FileCheck -v -dump-input=always check3 < input3 |& sed -n '/^<<<</,$p'
<<<<<<
1: abc foobar def
check:1 ^~~
not:2 !~~~~~ error: no match expected
check:3 ^~~
>>>>>>
$ cat check3
CHECK: abc
CHECK-NOT: foobar
CHECK: def
$ cat input3
abc foobar def
```
-vv enables these annotations for FileCheck's implicit EOF patterns as
well. For an example where EOF patterns become relevant, see patch 7
in this series.
If colors are enabled, `^~~` is green to suggest success.
-v plus color enables highlighting of input text that has no final
match for any expected pattern. The highlight uses a cyan background
to suggest a cold section. This highlighting can make it easier to
spot text that was intended to be matched but that failed to be
matched in a long series of good matches.
CHECK-COUNT-<num> good matches are another case where there can be
multiple match results for the same directive.
Reviewed By: george.karpenkov, probinson
Differential Revision: https://reviews.llvm.org/D53897
llvm-svn: 349422
Diffstat (limited to 'llvm/utils/FileCheck')
| -rw-r--r-- | llvm/utils/FileCheck/FileCheck.cpp | 83 |
1 files changed, 68 insertions, 15 deletions
diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp index 1f6caeee2e1..6248453a754 100644 --- a/llvm/utils/FileCheck/FileCheck.cpp +++ b/llvm/utils/FileCheck/FileCheck.cpp @@ -137,12 +137,15 @@ struct MarkerStyle { /// A note to follow the marker, or empty string if none. std::string Note; MarkerStyle() {} - MarkerStyle(char Lead, raw_ostream::Colors Color, const std::string &Note) + MarkerStyle(char Lead, raw_ostream::Colors Color, + const std::string &Note = "") : Lead(Lead), Color(Color), Note(Note) {} }; static MarkerStyle GetMarker(FileCheckDiag::MatchType MatchTy) { switch (MatchTy) { + case FileCheckDiag::MatchFinalAndExpected: + return MarkerStyle('^', raw_ostream::GREEN); case FileCheckDiag::MatchFinalButExcluded: return MarkerStyle('!', raw_ostream::RED, "error: no match expected"); case FileCheckDiag::MatchFinalButWrongLine: @@ -181,6 +184,9 @@ static void DumpInputAnnotationHelp(raw_ostream &OS) { // Markers on annotation lines. OS << " - "; + WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "^~~"; + OS << " marks good match (reported if -v)\n" + << " - "; WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "!~~"; OS << " marks bad match, such as:\n" << " - CHECK-NEXT on same line as previous match (error)\n" @@ -195,9 +201,13 @@ static void DumpInputAnnotationHelp(raw_ostream &OS) { // Colors. OS << " - colors "; + WithColor(OS, raw_ostream::GREEN, true) << "success"; + OS << ", "; WithColor(OS, raw_ostream::RED, true) << "error"; OS << ", "; WithColor(OS, raw_ostream::MAGENTA, true) << "fuzzy match"; + OS << ", "; + WithColor(OS, raw_ostream::CYAN, true, true) << "unmatched input"; OS << "\n\n" << "If you are not seeing color above or in input dumps, try: -color\n"; } @@ -222,6 +232,8 @@ struct InputAnnotation { unsigned InputStartCol, InputEndCol; /// The marker to use. MarkerStyle Marker; + /// Whether this annotation represents a final match for an expected pattern. + bool FinalAndExpectedMatch; }; /// Get an abbreviation for the check type. @@ -289,6 +301,8 @@ static void BuildInputAnnotations(const std::vector<FileCheckDiag> &Diags, MarkerStyle Marker = GetMarker(DiagItr->MatchTy); A.Marker = Marker; + A.FinalAndExpectedMatch = + DiagItr->MatchTy == FileCheckDiag::MatchFinalAndExpected; // Compute the mark location, and break annotation into multiple // annotations if it spans multiple lines. @@ -328,15 +342,17 @@ static void BuildInputAnnotations(const std::vector<FileCheckDiag> &Diags, B.Marker.Note = ""; } else B.InputEndCol = DiagItr->InputEndCol; + B.FinalAndExpectedMatch = A.FinalAndExpectedMatch; Annotations.push_back(B); } } } } -static void DumpAnnotatedInput( - raw_ostream &OS, StringRef InputFileText, - std::vector<InputAnnotation> &Annotations, unsigned LabelWidth) { +static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req, + StringRef InputFileText, + std::vector<InputAnnotation> &Annotations, + unsigned LabelWidth) { OS << "Full input was:\n<<<<<<\n"; // Sort annotations. @@ -359,9 +375,15 @@ static void DumpAnnotatedInput( return A.InputLine < B.InputLine; if (A.CheckLine != B.CheckLine) return A.CheckLine < B.CheckLine; - assert(A.CheckDiagIndex != B.CheckDiagIndex && - "expected diagnostic indices to be unique within a " - " check line"); + // FIXME: Sometimes CHECK-LABEL reports its match twice with + // other diagnostics in between, and then diag index incrementing + // fails to work properly, and then this assert fails. We should + // suppress one of those diagnostics or do a better job of + // computing this index. For now, we just produce a redundant + // CHECK-LABEL annotation. + // assert(A.CheckDiagIndex != B.CheckDiagIndex && + // "expected diagnostic indices to be unique within a " + // " check line"); return A.CheckDiagIndex < B.CheckDiagIndex; }); @@ -393,14 +415,45 @@ static void DumpAnnotatedInput( WithColor(OS, raw_ostream::BLACK, true) << format_decimal(Line, LabelWidth) << ": "; - // Print numbered line. + // For case where -v and colors are enabled, find the annotations for final + // matches for expected patterns in order to highlight everything else in + // the line. There are no such annotations if -v is disabled. + std::vector<InputAnnotation> FinalAndExpectedMatches; + if (Req.Verbose && WithColor(OS).colorsEnabled()) { + for (auto I = AnnotationItr; I != AnnotationEnd && I->InputLine == Line; + ++I) { + if (I->FinalAndExpectedMatch) + FinalAndExpectedMatches.push_back(*I); + } + } + + // Print numbered line with highlighting where there are no matches for + // expected patterns. bool Newline = false; - while (InputFilePtr != InputFileEnd && !Newline) { - if (*InputFilePtr == '\n') - Newline = true; - else - OS << *InputFilePtr; - ++InputFilePtr; + { + WithColor COS(OS); + bool InMatch = false; + if (Req.Verbose) + COS.changeColor(raw_ostream::CYAN, true, true); + for (unsigned Col = 1; InputFilePtr != InputFileEnd && !Newline; ++Col) { + bool WasInMatch = InMatch; + InMatch = false; + for (auto M : FinalAndExpectedMatches) { + if (M.InputStartCol <= Col && Col < M.InputEndCol) { + InMatch = true; + break; + } + } + if (!WasInMatch && InMatch) + COS.resetColor(); + else if (WasInMatch && !InMatch) + COS.changeColor(raw_ostream::CYAN, true, true); + if (*InputFilePtr == '\n') + Newline = true; + else + COS << *InputFilePtr; + ++InputFilePtr; + } } OS << '\n'; unsigned InputLineWidth = InputFilePtr - InputFileLine - Newline; @@ -561,7 +614,7 @@ int main(int argc, char **argv) { std::vector<InputAnnotation> Annotations; unsigned LabelWidth; BuildInputAnnotations(Diags, Annotations, LabelWidth); - DumpAnnotatedInput(errs(), InputFileText, Annotations, LabelWidth); + DumpAnnotatedInput(errs(), Req, InputFileText, Annotations, LabelWidth); } return ExitCode; |

