diff options
author | Joel E. Denny <jdenny.ornl@gmail.com> | 2020-07-28 18:09:05 -0400 |
---|---|---|
committer | Joel E. Denny <jdenny.ornl@gmail.com> | 2020-07-28 19:15:18 -0400 |
commit | d680711b94e94e9387076a0daf2a329e304e6751 (patch) | |
tree | 5935efba27b72116c3a4e694ca27e54c79a26255 /llvm/lib/Support/FileCheck.cpp | |
parent | 2cb926a447d22166dac0d6e6dceaf5b3616ef6a1 (diff) | |
download | llvm-d680711b94e94e9387076a0daf2a329e304e6751.zip llvm-d680711b94e94e9387076a0daf2a329e304e6751.tar.gz llvm-d680711b94e94e9387076a0daf2a329e304e6751.tar.bz2 |
[FileCheck] Extend -dump-input with substitutions
Substitutions are already reported in the diagnostics appearing before
the input dump in the case of failed directives, and they're reported
in traces (produced by `-vv -dump-input=never`) in the case of
successful directives. However, those reports are not always
convenient to view while investigating the input dump, so this patch
adds the substitution report to the input dump too. For example:
```
$ cat check
CHECK: hello [[WHAT:[a-z]+]]
CHECK: [[VERB]] [[WHAT]]
$ FileCheck -vv -DVERB=goodbye check < input |& tail -8
<<<<<<
1: hello world
check:1 ^~~~~~~~~~~
2: goodbye word
check:2'0 X~~~~~~~~~~~ error: no match found
check:2'1 with "VERB" equal to "goodbye"
check:2'2 with "WHAT" equal to "world"
>>>>>>
```
Without this patch, the location reported for a substitution for a
directive match is the directive's full match range. This location is
misleading as it implies the substitution itself matches that range.
This patch changes the reported location to just the match range start
to suggest the substitution is known at the start of the match. (As
in the above example, input dumps don't mark any range for
substitutions. The location info in that case simply identifies the
right line for the annotation.)
Reviewed By: mehdi_amini, thopre
Differential Revision: https://reviews.llvm.org/D83650
Diffstat (limited to 'llvm/lib/Support/FileCheck.cpp')
-rw-r--r-- | llvm/lib/Support/FileCheck.cpp | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/llvm/lib/Support/FileCheck.cpp b/llvm/lib/Support/FileCheck.cpp index d0e79c6..fd426a1 100644 --- a/llvm/lib/Support/FileCheck.cpp +++ b/llvm/lib/Support/FileCheck.cpp @@ -1247,7 +1247,9 @@ unsigned Pattern::computeMatchDistance(StringRef Buffer) const { } void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer, - SMRange MatchRange) const { + SMRange Range, + FileCheckDiag::MatchType MatchTy, + std::vector<FileCheckDiag> *Diags) const { // Print what we know about substitutions. if (!Substitutions.empty()) { for (const auto &Substitution : Substitutions) { @@ -1280,12 +1282,15 @@ void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer, OS.write_escaped(*MatchedValue) << "\""; } - if (MatchRange.isValid()) - SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, OS.str(), - {MatchRange}); + // We report only the start of the match/search range to suggest we are + // reporting the substitutions as set at the start of the match/search. + // Indicating a non-zero-length range might instead seem to imply that the + // substitution matches or was captured from exactly that range. + if (Diags) + Diags->emplace_back(SM, CheckTy, getLoc(), MatchTy, + SMRange(Range.Start, Range.Start), OS.str()); else - SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), - SourceMgr::DK_Note, OS.str()); + SM.PrintMessage(Range.Start, SourceMgr::DK_Note, OS.str()); } } } @@ -1295,14 +1300,17 @@ static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy, Check::FileCheckType CheckTy, StringRef Buffer, size_t Pos, size_t Len, std::vector<FileCheckDiag> *Diags, - bool AdjustPrevDiag = false) { + bool AdjustPrevDiags = false) { SMLoc Start = SMLoc::getFromPointer(Buffer.data() + Pos); SMLoc End = SMLoc::getFromPointer(Buffer.data() + Pos + Len); SMRange Range(Start, End); if (Diags) { - if (AdjustPrevDiag) - Diags->rbegin()->MatchTy = MatchTy; - else + if (AdjustPrevDiags) { + SMLoc CheckLoc = Diags->rbegin()->CheckLoc; + for (auto I = Diags->rbegin(), E = Diags->rend(); + I != E && I->CheckLoc == CheckLoc; ++I) + I->MatchTy = MatchTy; + } else Diags->emplace_back(SM, CheckTy, Loc, MatchTy, Range); } return Range; @@ -1455,8 +1463,8 @@ StringRef FileCheck::CanonicalizeFile(MemoryBuffer &MB, FileCheckDiag::FileCheckDiag(const SourceMgr &SM, const Check::FileCheckType &CheckTy, SMLoc CheckLoc, MatchType MatchTy, - SMRange InputRange) - : CheckTy(CheckTy), CheckLoc(CheckLoc), MatchTy(MatchTy) { + SMRange InputRange, StringRef Note) + : CheckTy(CheckTy), CheckLoc(CheckLoc), MatchTy(MatchTy), Note(Note) { auto Start = SM.getLineAndColumn(InputRange.Start); auto End = SM.getLineAndColumn(InputRange.End); InputStartLine = Start.first; @@ -1863,10 +1871,13 @@ static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM, // diagnostics. PrintDiag = !Diags; } - SMRange MatchRange = ProcessMatchResult( - ExpectedMatch ? FileCheckDiag::MatchFoundAndExpected - : FileCheckDiag::MatchFoundButExcluded, - SM, Loc, Pat.getCheckTy(), Buffer, MatchPos, MatchLen, Diags); + FileCheckDiag::MatchType MatchTy = ExpectedMatch + ? FileCheckDiag::MatchFoundAndExpected + : FileCheckDiag::MatchFoundButExcluded; + SMRange MatchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(), + Buffer, MatchPos, MatchLen, Diags); + if (Diags) + Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, Diags); if (!PrintDiag) return; @@ -1881,7 +1892,7 @@ static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM, Loc, ExpectedMatch ? SourceMgr::DK_Remark : SourceMgr::DK_Error, Message); SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, "found here", {MatchRange}); - Pat.printSubstitutions(SM, Buffer, MatchRange); + Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, nullptr); } static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM, @@ -1914,10 +1925,13 @@ static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM, // If the current position is at the end of a line, advance to the start of // the next line. Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r")); - SMRange SearchRange = ProcessMatchResult( - ExpectedMatch ? FileCheckDiag::MatchNoneButExpected - : FileCheckDiag::MatchNoneAndExcluded, - SM, Loc, Pat.getCheckTy(), Buffer, 0, Buffer.size(), Diags); + FileCheckDiag::MatchType MatchTy = ExpectedMatch + ? FileCheckDiag::MatchNoneButExpected + : FileCheckDiag::MatchNoneAndExcluded; + SMRange SearchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(), + Buffer, 0, Buffer.size(), Diags); + if (Diags) + Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, Diags); if (!PrintDiag) { consumeError(std::move(MatchErrors)); return; @@ -1945,7 +1959,7 @@ static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM, SM.PrintMessage(SearchRange.Start, SourceMgr::DK_Note, "scanning from here"); // Allow the pattern to print additional information if desired. - Pat.printSubstitutions(SM, Buffer); + Pat.printSubstitutions(SM, Buffer, SearchRange, MatchTy, nullptr); if (ExpectedMatch) Pat.printFuzzyMatch(SM, Buffer, Diags); @@ -2248,8 +2262,12 @@ size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer, SM.PrintMessage(OldStart, SourceMgr::DK_Note, "match discarded, overlaps earlier DAG match here", {OldRange}); - } else - Diags->rbegin()->MatchTy = FileCheckDiag::MatchFoundButDiscarded; + } else { + SMLoc CheckLoc = Diags->rbegin()->CheckLoc; + for (auto I = Diags->rbegin(), E = Diags->rend(); + I != E && I->CheckLoc == CheckLoc; ++I) + I->MatchTy = FileCheckDiag::MatchFoundButDiscarded; + } } MatchPos = MI->End; } |