mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[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
This commit is contained in:
parent
f066782da1
commit
00108cdc64
@ -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 @@ public:
|
||||
///
|
||||
/// 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();
|
||||
|
||||
|
@ -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()));
|
||||
|
@ -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:{{.}}
|
||||
|
@ -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,7 +294,10 @@ std::string GetCheckTypeAbbreviation(Check::FileCheckType Ty) {
|
||||
llvm_unreachable("unknown FileCheckType");
|
||||
}
|
||||
|
||||
static void BuildInputAnnotations(const std::vector<FileCheckDiag> &Diags,
|
||||
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?
|
||||
@ -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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user