diff options
author | Joel E. Denny <jdenny.ornl@gmail.com> | 2018-12-18 00:02:04 +0000 |
---|---|---|
committer | Joel E. Denny <jdenny.ornl@gmail.com> | 2018-12-18 00:02:04 +0000 |
commit | 2c007c807d38af1c7ae3bd08bc6695627abcb724 (patch) | |
tree | 794bda8c8eb50009d8a639837aac8f6360265c15 /llvm/utils/FileCheck/FileCheck.cpp | |
parent | 3c5d267eb728556b8f25a145d3b006f9f5356589 (diff) | |
download | llvm-2c007c807d38af1c7ae3bd08bc6695627abcb724.zip llvm-2c007c807d38af1c7ae3bd08bc6695627abcb724.tar.gz llvm-2c007c807d38af1c7ae3bd08bc6695627abcb724.tar.bz2 |
[FileCheck] Annotate input dump (2/7)
This patch implements input annotations for diagnostics that suggest
fuzzy matches for directives for which no matches were found. Instead
of using the usual `^~~`, which is used by later patches for good
matches, these annotations use `?` so that fuzzy matches are visually
distinct. No tildes are included as these diagnostics (independently
of this patch) currently identify only the start of the match.
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
- X~~ marks search range when no match is found
- ? 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 check1 < input1 |& sed -n '/^<<<</,$p'
<<<<<<
1: ; abc def
2: ; ghI jkl
next:3'0 X~~~~~~~~ error: no match found
next:3'1 ? possible intended match
>>>>>>
$ cat check1
CHECK: abc
CHECK-SAME: def
CHECK-NEXT: ghi
CHECK-SAME: jkl
$ cat input1
; abc def
; ghI jkl
```
This patch introduces the concept of multiple "match results" per
directive. In the above example, the first match result for the
CHECK-NEXT directive is the failed match, for which the annotation
shows the search range. The second match result is the fuzzy match.
Later patches will introduce other cases of multiple match results per
directive.
When colors are enabled, `?` is colored magenta. That is, it doesn't
indicate the actual error, which a red `X~~` marker indicates, but its
color suggests it's closely related.
Reviewed By: george.karpenkov, probinson
Differential Revision: https://reviews.llvm.org/D53893
llvm-svn: 349419
Diffstat (limited to 'llvm/utils/FileCheck/FileCheck.cpp')
-rw-r--r-- | llvm/utils/FileCheck/FileCheck.cpp | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp index 3344914..c6846f7 100644 --- a/llvm/utils/FileCheck/FileCheck.cpp +++ b/llvm/utils/FileCheck/FileCheck.cpp @@ -145,6 +145,8 @@ static MarkerStyle GetMarker(FileCheckDiag::MatchType MatchTy) { switch (MatchTy) { case FileCheckDiag::MatchNoneButExpected: return MarkerStyle('X', raw_ostream::RED, "error: no match found"); + case FileCheckDiag::MatchFuzzy: + return MarkerStyle('?', raw_ostream::MAGENTA, "possible intended match"); case FileCheckDiag::MatchTypeCount: llvm_unreachable_internal("unexpected match type"); } @@ -164,18 +166,28 @@ static void DumpInputAnnotationHelp(raw_ostream &OS) { // Labels for annotation lines. OS << " - "; WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "T:L"; - OS << " labels the match result for a pattern of type T from " + OS << " labels the only match result for a pattern of type T from " << "line L of\n" << " the check file\n"; + OS << " - "; + WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "T:L'N"; + OS << " labels the Nth match result for a pattern of type T from line " + << "L of\n" + << " the check file\n"; // Markers on annotation lines. OS << " - "; 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\n" + << " - "; + WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "?"; + OS << " marks fuzzy match when no match is found\n"; // Colors. OS << " - colors "; WithColor(OS, raw_ostream::RED, true) << "error"; + OS << ", "; + WithColor(OS, raw_ostream::MAGENTA, true) << "fuzzy match"; OS << "\n\n" << "If you are not seeing color above or in input dumps, try: -color\n"; } @@ -185,6 +197,8 @@ struct InputAnnotation { /// The check file line (one-origin indexing) where the directive that /// produced this annotation is located. unsigned CheckLine; + /// The index of the match result for this check. + unsigned CheckDiagIndex; /// The label for this annotation. std::string Label; /// What input line (one-origin indexing) this annotation marks. This might @@ -234,6 +248,8 @@ std::string GetCheckTypeAbbreviation(Check::FileCheckType Ty) { static void BuildInputAnnotations(const std::vector<FileCheckDiag> &Diags, std::vector<InputAnnotation> &Annotations, unsigned &LabelWidth) { + // How many diagnostics has the current check seen so far? + unsigned CheckDiagCount = 0; // What's the widest label? LabelWidth = 0; for (auto DiagItr = Diags.begin(), DiagEnd = Diags.end(); DiagItr != DiagEnd; @@ -245,6 +261,19 @@ static void BuildInputAnnotations(const std::vector<FileCheckDiag> &Diags, llvm::raw_string_ostream Label(A.Label); Label << GetCheckTypeAbbreviation(DiagItr->CheckTy) << ":" << DiagItr->CheckLine; + A.CheckDiagIndex = UINT_MAX; + auto DiagNext = std::next(DiagItr); + if (DiagNext != DiagEnd && DiagItr->CheckTy == DiagNext->CheckTy && + DiagItr->CheckLine == DiagNext->CheckLine) + A.CheckDiagIndex = CheckDiagCount++; + else if (CheckDiagCount) { + A.CheckDiagIndex = CheckDiagCount; + CheckDiagCount = 0; + } + if (A.CheckDiagIndex != UINT_MAX) + Label << "'" << A.CheckDiagIndex; + else + A.CheckDiagIndex = 0; Label.flush(); LabelWidth = std::max((std::string::size_type)LabelWidth, A.Label.size()); @@ -278,6 +307,7 @@ static void BuildInputAnnotations(const std::vector<FileCheckDiag> &Diags, } InputAnnotation B; B.CheckLine = A.CheckLine; + B.CheckDiagIndex = A.CheckDiagIndex; B.Label = A.Label; B.InputLine = L; B.Marker = Marker; @@ -308,16 +338,21 @@ static void DumpAnnotatedInput( // // Second, for annotations for the same input line, sort in the order of the // FileCheck directive's line in the check file (where there's at most one - // directive per line). The rationale of this choice is that, for any input - // line, this sort establishes a total order of annotations that, with - // respect to match results, is consistent across multiple lines, thus - // making match results easier to track from one line to the next when they - // span multiple lines. + // directive per line) and then by the index of the match result for that + // directive. The rationale of this choice is that, for any input line, this + // sort establishes a total order of annotations that, with respect to match + // results, is consistent across multiple lines, thus making match results + // easier to track from one line to the next when they span multiple lines. std::sort(Annotations.begin(), Annotations.end(), [](const InputAnnotation &A, const InputAnnotation &B) { if (A.InputLine != B.InputLine) return A.InputLine < B.InputLine; - return A.CheckLine < B.CheckLine; + 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"); + return A.CheckDiagIndex < B.CheckDiagIndex; }); // Compute the width of the label column. |