[llvm] b5a2461 - [FileCheck] Fix --dump-input implicit pattern location
Joel E. Denny via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 12:40:50 PDT 2020
Author: Joel E. Denny
Date: 2020-04-16T15:39:35-04:00
New Revision: b5a24610fad6d68f65bd6ec8db52b6e480c56d6c
URL: https://github.com/llvm/llvm-project/commit/b5a24610fad6d68f65bd6ec8db52b6e480c56d6c
DIFF: https://github.com/llvm/llvm-project/commit/b5a24610fad6d68f65bd6ec8db52b6e480c56d6c.diff
LOG: [FileCheck] Fix --dump-input implicit pattern location
Currently, `--dump-input` implies that all `--implicit-check-not`
patterns appear on line 1 by printing annotations like:
```
1: foo bar baz
not:1 !~~ error: no match expected
```
This patch changes that to:
```
1: foo bar baz
not:imp1 !~~ error: no match expected
```
`imp1` indicates the first `--implicit-check-not` pattern.
Reviewed By: thopre
Differential Revision: https://reviews.llvm.org/D77605
Added:
Modified:
llvm/include/llvm/Support/FileCheck.h
llvm/lib/Support/FileCheck.cpp
llvm/test/FileCheck/dump-input-annotations.txt
llvm/utils/FileCheck/FileCheck.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/FileCheck.h b/llvm/include/llvm/Support/FileCheck.h
index d218ef042257..1150882b0b3e 100644
--- a/llvm/include/llvm/Support/FileCheck.h
+++ b/llvm/include/llvm/Support/FileCheck.h
@@ -88,7 +88,7 @@ struct FileCheckDiag {
/// What is the FileCheck directive for this diagnostic?
Check::FileCheckType CheckTy;
/// Where is the FileCheck directive for this diagnostic?
- unsigned CheckLine, CheckCol;
+ SMLoc CheckLoc;
/// What type of match result does this diagnostic describe?
///
/// A directive's supplied pattern is said to be either expected or excluded
@@ -160,7 +160,13 @@ class FileCheck {
///
/// Only expected strings whose prefix is one of those listed in \p PrefixRE
/// are recorded. \returns true in case of an error, false otherwise.
- bool readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE);
+ ///
+ /// If \p ImpPatBufferIDRange, then the range (inclusive start, exclusive end)
+ /// of IDs for source buffers added to \p SM for implicit patterns are
+ /// recorded in it. The range is empty if there are none.
+ bool
+ readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
+ std::pair<unsigned, unsigned> *ImpPatBufferIDRange = nullptr);
bool ValidateCheckPrefixes();
diff --git a/llvm/lib/Support/FileCheck.cpp b/llvm/lib/Support/FileCheck.cpp
index 71b1e8356137..7b70112e3978 100644
--- a/llvm/lib/Support/FileCheck.cpp
+++ b/llvm/lib/Support/FileCheck.cpp
@@ -1069,16 +1069,13 @@ FileCheckDiag::FileCheckDiag(const SourceMgr &SM,
const Check::FileCheckType &CheckTy,
SMLoc CheckLoc, MatchType MatchTy,
SMRange InputRange)
- : CheckTy(CheckTy), MatchTy(MatchTy) {
+ : CheckTy(CheckTy), CheckLoc(CheckLoc), MatchTy(MatchTy) {
auto Start = SM.getLineAndColumn(InputRange.Start);
auto End = SM.getLineAndColumn(InputRange.End);
InputStartLine = Start.first;
InputStartCol = Start.second;
InputEndLine = End.first;
InputEndCol = End.second;
- Start = SM.getLineAndColumn(CheckLoc);
- CheckLine = Start.first;
- CheckCol = Start.second;
}
static bool IsPartOfWord(char c) {
@@ -1269,8 +1266,12 @@ FileCheck::FileCheck(FileCheckRequest Req)
FileCheck::~FileCheck() = default;
-bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
- Regex &PrefixRE) {
+bool FileCheck::readCheckFile(
+ SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
+ std::pair<unsigned, unsigned> *ImpPatBufferIDRange) {
+ if (ImpPatBufferIDRange)
+ ImpPatBufferIDRange->first = ImpPatBufferIDRange->second = 0;
+
Error DefineError =
PatternContext->defineCmdlineVariables(Req.GlobalDefines, SM);
if (DefineError) {
@@ -1291,7 +1292,17 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer,
StringRef PatternInBuffer =
CmdLine->getBuffer().substr(Prefix.size(), PatternString.size());
- SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
+ unsigned BufferID = SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc());
+ if (ImpPatBufferIDRange) {
+ if (ImpPatBufferIDRange->first == ImpPatBufferIDRange->second) {
+ ImpPatBufferIDRange->first = BufferID;
+ ImpPatBufferIDRange->second = BufferID + 1;
+ } else {
+ assert(BufferID == ImpPatBufferIDRange->second &&
+ "expected consecutive source buffer IDs");
+ ++ImpPatBufferIDRange->second;
+ }
+ }
ImplicitNegativeChecks.push_back(
Pattern(Check::CheckNot, PatternContext.get()));
diff --git a/llvm/test/FileCheck/dump-input-annotations.txt b/llvm/test/FileCheck/dump-input-annotations.txt
index a9072ddcf423..a0fce27b42b0 100644
--- a/llvm/test/FileCheck/dump-input-annotations.txt
+++ b/llvm/test/FileCheck/dump-input-annotations.txt
@@ -494,3 +494,64 @@
; LAB-NEXT: label:3'0 ~~~
; LAB-NEXT: >>>>>>
; LAB-NOT: {{.}}
+
+;--------------------------------------------------
+; --implicit-check-not
+;
+; The first two --implicit-check-not patterns have no match (success). The
+; third has an unexpected match (error). To check per-input-line annotation
+; sorting, all of those plus the CHECK directives have annotations on the same
+; input line.
+;--------------------------------------------------
+
+; RUN: echo 'hello world again!' > %t.in
+
+; RUN: echo 'CHECK: hel' > %t.chk
+; RUN: echo 'CHECK: wor' >> %t.chk
+; RUN: echo 'CHECK: !' >> %t.chk
+
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input=always -input-file=%t.in %t.chk 2>&1 \
+; RUN: --implicit-check-not='goodbye' \
+; RUN: --implicit-check-not='world' \
+; RUN: --implicit-check-not='again' \
+; RUN: | FileCheck -match-full-lines %s -check-prefix=IMPNOT \
+; RUN: -implicit-check-not='remark:'
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input=always -input-file=%t.in %t.chk -v 2>&1 \
+; RUN: --implicit-check-not='goodbye' \
+; RUN: --implicit-check-not='world' \
+; RUN: --implicit-check-not='again' \
+; RUN: | FileCheck -match-full-lines %s -check-prefixes=IMPNOT,IMPNOT-V \
+; RUN: -implicit-check-not='remark:'
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input=always -input-file=%t.in %t.chk -vv 2>&1 \
+; RUN: --implicit-check-not='goodbye' \
+; RUN: --implicit-check-not='world' \
+; RUN: --implicit-check-not='again' \
+; RUN: | FileCheck -match-full-lines %s \
+; RUN: -check-prefixes=IMPNOT,IMPNOT-V,IMPNOT-VV \
+; RUN: -implicit-check-not='remark:'
+
+; Verbose diagnostics are suppressed but not errors.
+; IMPNOT:{{.*}}error:{{.*}}
+
+; FIXME: All occurrences of imp1, imp2, and imp3 are sorting after the first
+; directive. They should instead be sorted by when they execute.
+
+; IMPNOT:<<<<<<
+; IMPNOT-NEXT: 1: hello world again!
+; IMPNOT-V-NEXT:check:1 ^~~
+; IMPNOT-VV-NEXT:not:imp1 X
+; IMPNOT-VV-NEXT:not:imp2 X
+; IMPNOT-VV-NEXT:not:imp3 X
+; IMPNOT-VV-NEXT:not:imp1 X~~
+; IMPNOT-VV-NEXT:not:imp2 X~~
+; IMPNOT-VV-NEXT:not:imp3 X~~
+; IMPNOT-VV-NEXT:not:imp1 X~~~~~~~
+; IMPNOT-VV-NEXT:not:imp2 X~~~~~~~
+; IMPNOT-NEXT:not:imp3 !~~~~ error: no match expected
+; IMPNOT-V-NEXT:check:2 ^~~
+; IMPNOT-V-NEXT:check:3 ^
+; IMPNOT-NEXT:>>>>>>
+; IMPNOT-NOT:{{.}}
diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp
index 539bc13f946a..6cfd0fd75878 100644
--- a/llvm/utils/FileCheck/FileCheck.cpp
+++ b/llvm/utils/FileCheck/FileCheck.cpp
@@ -193,14 +193,15 @@ static void DumpInputAnnotationHelp(raw_ostream &OS) {
// Labels for annotation lines.
OS << " - ";
WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "T:L";
- OS << " labels the only match result for a pattern of type T from "
- << "line L of\n"
- << " the check file\n";
+ OS << " labels the only match result for either (1) a pattern of type T"
+ << " from\n"
+ << " line L of the check file if L is an integer or (2) the"
+ << " I-th implicit\n"
+ << " pattern if L is \"imp\" followed by an integer "
+ << "I (index origin one)\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";
+ OS << " labels the Nth match result for such a pattern\n";
// Markers on annotation lines.
OS << " - ";
@@ -293,9 +294,12 @@ std::string GetCheckTypeAbbreviation(Check::FileCheckType Ty) {
llvm_unreachable("unknown FileCheckType");
}
-static void BuildInputAnnotations(const std::vector<FileCheckDiag> &Diags,
- std::vector<InputAnnotation> &Annotations,
- unsigned &LabelWidth) {
+static void
+BuildInputAnnotations(const SourceMgr &SM, unsigned CheckFileBufferID,
+ const std::pair<unsigned, unsigned> &ImpPatBufferIDRange,
+ 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?
@@ -305,14 +309,24 @@ static void BuildInputAnnotations(const std::vector<FileCheckDiag> &Diags,
InputAnnotation A;
// Build label, which uniquely identifies this check result.
- A.CheckLine = DiagItr->CheckLine;
+ unsigned CheckBufferID = SM.FindBufferContainingLoc(DiagItr->CheckLoc);
+ auto CheckLineAndCol =
+ SM.getLineAndColumn(DiagItr->CheckLoc, CheckBufferID);
+ A.CheckLine = CheckLineAndCol.first;
llvm::raw_string_ostream Label(A.Label);
- Label << GetCheckTypeAbbreviation(DiagItr->CheckTy) << ":"
- << DiagItr->CheckLine;
+ Label << GetCheckTypeAbbreviation(DiagItr->CheckTy) << ":";
+ if (CheckBufferID == CheckFileBufferID)
+ Label << CheckLineAndCol.first;
+ else if (ImpPatBufferIDRange.first <= CheckBufferID &&
+ CheckBufferID < ImpPatBufferIDRange.second)
+ Label << "imp" << (CheckBufferID - ImpPatBufferIDRange.first + 1);
+ else
+ llvm_unreachable("expected diagnostic's check location to be either in "
+ "the check file or for an implicit pattern");
A.CheckDiagIndex = UINT_MAX;
auto DiagNext = std::next(DiagItr);
if (DiagNext != DiagEnd && DiagItr->CheckTy == DiagNext->CheckTy &&
- DiagItr->CheckLine == DiagNext->CheckLine)
+ DiagItr->CheckLoc == DiagNext->CheckLoc)
A.CheckDiagIndex = CheckDiagCount++;
else if (CheckDiagCount) {
A.CheckDiagIndex = CheckDiagCount;
@@ -606,11 +620,13 @@ int main(int argc, char **argv) {
SmallString<4096> CheckFileBuffer;
StringRef CheckFileText = FC.CanonicalizeFile(CheckFile, CheckFileBuffer);
- SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
- CheckFileText, CheckFile.getBufferIdentifier()),
- SMLoc());
+ unsigned CheckFileBufferID =
+ SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
+ CheckFileText, CheckFile.getBufferIdentifier()),
+ SMLoc());
- if (FC.readCheckFile(SM, CheckFileText, PrefixRE))
+ std::pair<unsigned, unsigned> ImpPatBufferIDRange;
+ if (FC.readCheckFile(SM, CheckFileText, PrefixRE, &ImpPatBufferIDRange))
return 2;
// Open the file to check and add it to SourceMgr.
@@ -658,7 +674,8 @@ int main(int argc, char **argv) {
<< "\n";
std::vector<InputAnnotation> Annotations;
unsigned LabelWidth;
- BuildInputAnnotations(Diags, Annotations, LabelWidth);
+ BuildInputAnnotations(SM, CheckFileBufferID, ImpPatBufferIDRange, Diags,
+ Annotations, LabelWidth);
DumpAnnotatedInput(errs(), Req, InputFileText, Annotations, LabelWidth);
}
More information about the llvm-commits
mailing list