[llvm] 4becd0c - [FileCheck][NFC] Introduce FileCheckDiagList for -dump-input (#195568)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 6 07:17:44 PDT 2026
Author: Joel E. Denny
Date: 2026-05-06T14:17:38Z
New Revision: 4becd0c44b01a83e172fd28c1b3a3b8dd598f3fc
URL: https://github.com/llvm/llvm-project/commit/4becd0c44b01a83e172fd28c1b3a3b8dd598f3fc
DIFF: https://github.com/llvm/llvm-project/commit/4becd0c44b01a83e172fd28c1b3a3b8dd598f3fc.diff
LOG: [FileCheck][NFC] Introduce FileCheckDiagList for -dump-input (#195568)
Problem
=======
`FileCheckDiag` and its `enum MatchType` have outgrown their original
purpose. The `-dump-input` presentation layer (in
`llvm/utils/FileCheck/FileCheck.cpp`) and the FileCheck library's
diagnostic emission (in `llvm/lib/FileCheck/FileCheck.cpp`) are too
tightly coupled. The interactions are subtle to understand and maintain.
It is difficult for the former to reason about the latter's emitted
diagnostics in order to present them in the most readable manner.
Solution
========
This patch is the first in an NFC series that removes `MatchType` from
`FileCheckDiag` and refactors `FileCheckDiag` as the base class of a
class hierarchy. That class hierarchy is designed to enable the
FileCheck library to focus on communicating FileCheck diagnostic
information clearly and completely without participating in the specific
presentation decisions of `-dump-input`. `-dump-input` and any future
diagnostic presentation layer that FileCheck might grow are then freer
to evolve more independently in the way they reason about emitted
diagnostics. Moreover, the hierarchy enables various `FileCheckDiag`
objects not to carry various data not needed for the diagnostics they
describe.
This Patch
==========
The main goal of this particular patch is to introduce the
`FileCheckDiagList` class and to separate mostly mechanical changes from
future patches to make them more readable. However, by itself, it does
offer some small improvements: it encapsulates the `adjustPrevDiags`
functionality, and it replaces the cryptic `ProcessMatchResult` function
with more readable code.
Why now?
========
FileCheck's input dumps have usability issues, including confusing
verbosity and the need to look in the test file to see directive
patterns. There has been a recent push in issue #77257 and in PRs linked
from there to address these issues. This patch series is a first step in
the most recent strategy discussed there. Actually, it is an older
strategy that was started in
[D126673](https://reviews.llvm.org/D126673) but never completed. The
current patch series updates D126673 and splits it apart to facilitate
the review. The actual usability improvements are implemented by patches
that build on this series.
Added:
Modified:
llvm/include/llvm/FileCheck/FileCheck.h
llvm/lib/FileCheck/FileCheck.cpp
llvm/lib/FileCheck/FileCheckImpl.h
llvm/unittests/FileCheck/FileCheckTest.cpp
llvm/utils/FileCheck/FileCheck.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/FileCheck/FileCheck.h b/llvm/include/llvm/FileCheck/FileCheck.h
index b44ed8ed3f839..ff3de0d4aef20 100644
--- a/llvm/include/llvm/FileCheck/FileCheck.h
+++ b/llvm/include/llvm/FileCheck/FileCheck.h
@@ -18,6 +18,7 @@
#include "llvm/Support/Regex.h"
#include "llvm/Support/SMLoc.h"
#include <bitset>
+#include <iterator>
#include <memory>
#include <string>
#include <vector>
@@ -174,6 +175,67 @@ struct FileCheckDiag {
StringRef Note = "");
};
+/// A \c FileCheckDiag series emitted by the FileCheck library.
+class FileCheckDiagList {
+private:
+ using vector_type = std::vector<std::unique_ptr<FileCheckDiag>>;
+ vector_type DiagList;
+
+public:
+ /// Emplace a new \c FileCheckDiag.
+ template <typename... ArgTys> void emplace_back(ArgTys &&...Args) {
+ DiagList.emplace_back(
+ std::make_unique<FileCheckDiag>(std::forward<ArgTys>(Args)...));
+ }
+ /// Adjust recent consecutive diagnostics of the same \c CheckLoc to have
+ /// \c MatchTy.
+ void adjustPrevDiags(FileCheckDiag::MatchType MatchTy) {
+ SMLoc CheckLoc = (*DiagList.rbegin())->CheckLoc;
+ for (auto I = DiagList.rbegin(), E = DiagList.rend();
+ I != E && (*I)->CheckLoc == CheckLoc; ++I)
+ (*I)->MatchTy = MatchTy;
+ }
+ class const_iterator {
+ friend FileCheckDiagList;
+
+ public:
+ using
diff erence_type = std::ptr
diff _t;
+ using value_type = FileCheckDiag;
+ using pointer = const FileCheckDiag *;
+ using reference = const FileCheckDiag &;
+ using iterator_category = std::forward_iterator_tag;
+
+ private:
+ vector_type::const_iterator Itr;
+ const_iterator(vector_type::const_iterator Itr) : Itr(Itr) {}
+
+ public:
+ reference operator*() const { return **Itr; }
+ pointer operator->() const { return &operator*(); }
+ const_iterator &operator++() {
+ ++Itr;
+ return *this;
+ }
+ const_iterator operator++(int) {
+ const_iterator Old = *this;
+ ++Itr;
+ return Old;
+ }
+ bool operator==(const const_iterator &Other) const {
+ return Itr == Other.Itr;
+ }
+ bool operator!=(const const_iterator &Other) const {
+ return Itr != Other.Itr;
+ }
+ };
+
+ using size_type = vector_type::size_type;
+ const_iterator begin() const { return const_iterator(DiagList.begin()); }
+ const_iterator end() const { return const_iterator(DiagList.end()); }
+ const FileCheckDiag &operator[](size_type I) const { return *DiagList[I]; }
+ size_type size() const { return DiagList.size(); }
+};
+
class FileCheckPatternContext;
struct FileCheckString;
@@ -211,7 +273,7 @@ class FileCheck {
///
/// \returns false if the input fails to satisfy the checks.
LLVM_ABI bool checkInput(SourceMgr &SM, StringRef Buffer,
- std::vector<FileCheckDiag> *Diags = nullptr);
+ FileCheckDiagList *Diags = nullptr);
};
} // namespace llvm
diff --git a/llvm/lib/FileCheck/FileCheck.cpp b/llvm/lib/FileCheck/FileCheck.cpp
index d50e5d9cb088b..7fd672b978e36 100644
--- a/llvm/lib/FileCheck/FileCheck.cpp
+++ b/llvm/lib/FileCheck/FileCheck.cpp
@@ -1261,7 +1261,7 @@ unsigned Pattern::computeMatchDistance(StringRef Buffer) const {
void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
SMRange Range,
FileCheckDiag::MatchType MatchTy,
- std::vector<FileCheckDiag> *Diags) const {
+ FileCheckDiagList *Diags) const {
// Print what we know about substitutions.
if (!Substitutions.empty()) {
for (const auto &Substitution : Substitutions) {
@@ -1295,7 +1295,7 @@ void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer,
void Pattern::printVariableDefs(const SourceMgr &SM,
FileCheckDiag::MatchType MatchTy,
- std::vector<FileCheckDiag> *Diags) const {
+ FileCheckDiagList *Diags) const {
if (VariableDefs.empty() && NumericVariableDefs.empty())
return;
// Build list of variable captures.
@@ -1346,29 +1346,18 @@ void Pattern::printVariableDefs(const SourceMgr &SM,
}
}
-static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy,
- const SourceMgr &SM, SMLoc Loc,
- Check::FileCheckType CheckTy,
- StringRef Buffer, size_t Pos, size_t Len,
- std::vector<FileCheckDiag> *Diags,
- 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 (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;
+static SMRange buildMatchRange(StringRef Buffer, size_t Pos, size_t Len) {
+ return SMRange(SMLoc::getFromPointer(Buffer.data() + Pos),
+ SMLoc::getFromPointer(Buffer.data() + Pos + Len));
+}
+
+static SMRange buildSearchRange(StringRef Buffer) {
+ return SMRange(SMLoc::getFromPointer(Buffer.data()),
+ SMLoc::getFromPointer(Buffer.data() + Buffer.size()));
}
void Pattern::printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
- std::vector<FileCheckDiag> *Diags) const {
+ FileCheckDiagList *Diags) const {
// Attempt to find the closest/best fuzzy match. Usually an error happens
// because some string in the output didn't exactly match. In these cases, we
// would like to show the user a best guess at what "should have" matched, to
@@ -1408,9 +1397,10 @@ void Pattern::printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
// reasonable and not equal to what we showed in the "scanning from here"
// line.
if (Best && Best != StringRef::npos && BestQuality < 50) {
- SMRange MatchRange =
- ProcessMatchResult(FileCheckDiag::MatchFuzzy, SM, getLoc(),
- getCheckTy(), Buffer, Best, 0, Diags);
+ SMRange MatchRange = buildMatchRange(Buffer, Best, 0);
+ if (Diags)
+ Diags->emplace_back(SM, getCheckTy(), getLoc(), FileCheckDiag::MatchFuzzy,
+ MatchRange);
SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note,
"possible intended match here");
@@ -2033,8 +2023,7 @@ static Error printMatch(bool ExpectedMatch, const SourceMgr &SM,
StringRef Prefix, SMLoc Loc, const Pattern &Pat,
int MatchedCount, StringRef Buffer,
Pattern::MatchResult MatchResult,
- const FileCheckRequest &Req,
- std::vector<FileCheckDiag> *Diags) {
+ const FileCheckRequest &Req, FileCheckDiagList *Diags) {
// Suppress some verbosity if there's no error.
bool HasError = !ExpectedMatch || MatchResult.TheError;
bool PrintDiag = true;
@@ -2053,10 +2042,10 @@ static Error printMatch(bool ExpectedMatch, const SourceMgr &SM,
FileCheckDiag::MatchType MatchTy = ExpectedMatch
? FileCheckDiag::MatchFoundAndExpected
: FileCheckDiag::MatchFoundButExcluded;
- SMRange MatchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(),
- Buffer, MatchResult.TheMatch->Pos,
- MatchResult.TheMatch->Len, Diags);
+ SMRange MatchRange = buildMatchRange(Buffer, MatchResult.TheMatch->Pos,
+ MatchResult.TheMatch->Len);
if (Diags) {
+ Diags->emplace_back(SM, Pat.getCheckTy(), Loc, MatchTy, MatchRange);
Pat.printSubstitutions(SM, Buffer, MatchRange, MatchTy, Diags);
Pat.printVariableDefs(SM, MatchTy, Diags);
}
@@ -2102,8 +2091,7 @@ static Error printMatch(bool ExpectedMatch, const SourceMgr &SM,
static Error printNoMatch(bool ExpectedMatch, const SourceMgr &SM,
StringRef Prefix, SMLoc Loc, const Pattern &Pat,
int MatchedCount, StringRef Buffer, Error MatchError,
- bool VerboseVerbose,
- std::vector<FileCheckDiag> *Diags) {
+ bool VerboseVerbose, FileCheckDiagList *Diags) {
// Print any pattern errors, and record them to be added to Diags later.
bool HasError = ExpectedMatch;
bool HasPatternError = false;
@@ -2141,9 +2129,9 @@ static Error printNoMatch(bool ExpectedMatch, const SourceMgr &SM,
// errors. The reason is that we need to attach pattern errors as notes
// somewhere in the input, and the input search range from the "not found"
// diagnostic is all we have to anchor them.
- SMRange SearchRange = ProcessMatchResult(MatchTy, SM, Loc, Pat.getCheckTy(),
- Buffer, 0, Buffer.size(), Diags);
+ SMRange SearchRange = buildSearchRange(Buffer);
if (Diags) {
+ Diags->emplace_back(SM, Pat.getCheckTy(), Loc, MatchTy, SearchRange);
SMRange NoteRange = SMRange(SearchRange.Start, SearchRange.Start);
for (StringRef ErrorMsg : ErrorMsgs)
Diags->emplace_back(SM, Pat.getCheckTy(), Loc, MatchTy, NoteRange,
@@ -2187,7 +2175,7 @@ static Error reportMatchResult(bool ExpectedMatch, const SourceMgr &SM,
int MatchedCount, StringRef Buffer,
Pattern::MatchResult MatchResult,
const FileCheckRequest &Req,
- std::vector<FileCheckDiag> *Diags) {
+ FileCheckDiagList *Diags) {
if (MatchResult.TheMatch)
return printMatch(ExpectedMatch, SM, Prefix, Loc, Pat, MatchedCount, Buffer,
std::move(MatchResult), Req, Diags);
@@ -2222,7 +2210,7 @@ static unsigned CountNumNewlinesBetween(StringRef Range,
size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
bool IsLabelScanMode, size_t &MatchLen,
FileCheckRequest &Req,
- std::vector<FileCheckDiag> *Diags) const {
+ FileCheckDiagList *Diags) const {
size_t LastPos = 0;
std::vector<const DagNotPrefixInfo *> NotStrings;
@@ -2276,18 +2264,30 @@ size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer,
// If this check is a "CHECK-NEXT", verify that the previous match was on
// the previous line (i.e. that there is one newline between them).
if (CheckNext(SM, SkippedRegion)) {
- ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc,
- Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
- Diags, Req.Verbose);
+ if (Diags) {
+ if (Req.Verbose) {
+ Diags->adjustPrevDiags(FileCheckDiag::MatchFoundButWrongLine);
+ } else {
+ Diags->emplace_back(SM, Pat.getCheckTy(), Loc,
+ FileCheckDiag::MatchFoundButWrongLine,
+ buildMatchRange(MatchBuffer, MatchPos, MatchLen));
+ }
+ }
return StringRef::npos;
}
// If this check is a "CHECK-SAME", verify that the previous match was on
// the same line (i.e. that there is no newline between them).
if (CheckSame(SM, SkippedRegion)) {
- ProcessMatchResult(FileCheckDiag::MatchFoundButWrongLine, SM, Loc,
- Pat.getCheckTy(), MatchBuffer, MatchPos, MatchLen,
- Diags, Req.Verbose);
+ if (Diags) {
+ if (Req.Verbose) {
+ Diags->adjustPrevDiags(FileCheckDiag::MatchFoundButWrongLine);
+ } else {
+ Diags->emplace_back(SM, Pat.getCheckTy(), Loc,
+ FileCheckDiag::MatchFoundButWrongLine,
+ buildMatchRange(MatchBuffer, MatchPos, MatchLen));
+ }
+ }
return StringRef::npos;
}
@@ -2364,7 +2364,7 @@ bool FileCheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const {
bool FileCheckString::CheckNot(
const SourceMgr &SM, StringRef Buffer,
const std::vector<const DagNotPrefixInfo *> &NotStrings,
- const FileCheckRequest &Req, std::vector<FileCheckDiag> *Diags) const {
+ const FileCheckRequest &Req, FileCheckDiagList *Diags) const {
bool DirectiveFail = false;
for (auto NotInfo : NotStrings) {
assert((NotInfo->DagNotPat.getCheckTy() == Check::CheckNot) &&
@@ -2386,7 +2386,7 @@ size_t
FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
std::vector<const DagNotPrefixInfo *> &NotStrings,
const FileCheckRequest &Req,
- std::vector<FileCheckDiag> *Diags) const {
+ FileCheckDiagList *Diags) const {
if (DagNotStrings.empty())
return 0;
@@ -2475,18 +2475,15 @@ FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer,
// Due to their verbosity, we don't print verbose diagnostics here if
// we're gathering them for a
diff erent rendering, but we always print
// other diagnostics.
- if (!Diags) {
+ if (Diags) {
+ Diags->adjustPrevDiags(FileCheckDiag::MatchFoundButDiscarded);
+ } else {
SMLoc OldStart = SMLoc::getFromPointer(Buffer.data() + MI->Pos);
SMLoc OldEnd = SMLoc::getFromPointer(Buffer.data() + MI->End);
SMRange OldRange(OldStart, OldEnd);
SM.PrintMessage(OldStart, SourceMgr::DK_Note,
"match discarded, overlaps earlier DAG match here",
{OldRange});
- } 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;
@@ -2725,7 +2722,7 @@ void FileCheckPatternContext::clearLocalVars() {
}
bool FileCheck::checkInput(SourceMgr &SM, StringRef Buffer,
- std::vector<FileCheckDiag> *Diags) {
+ FileCheckDiagList *Diags) {
bool ChecksFailed = false;
unsigned i = 0, j = 0, e = CheckStrings.size();
diff --git a/llvm/lib/FileCheck/FileCheckImpl.h b/llvm/lib/FileCheck/FileCheckImpl.h
index 5851cfc4b5d5c..547c93f2acca5 100644
--- a/llvm/lib/FileCheck/FileCheckImpl.h
+++ b/llvm/lib/FileCheck/FileCheckImpl.h
@@ -734,16 +734,16 @@ class Pattern {
/// Prints the value of successful substitutions.
void printSubstitutions(const SourceMgr &SM, StringRef Buffer,
SMRange MatchRange, FileCheckDiag::MatchType MatchTy,
- std::vector<FileCheckDiag> *Diags) const;
+ FileCheckDiagList *Diags) const;
void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer,
- std::vector<FileCheckDiag> *Diags) const;
+ FileCheckDiagList *Diags) const;
bool hasVariable() const {
return !(Substitutions.empty() && VariableDefs.empty());
}
- LLVM_ABI_FOR_TEST void
- printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy,
- std::vector<FileCheckDiag> *Diags) const;
+ LLVM_ABI_FOR_TEST void printVariableDefs(const SourceMgr &SM,
+ FileCheckDiag::MatchType MatchTy,
+ FileCheckDiagList *Diags) const;
Check::FileCheckType getCheckTy() const { return CheckTy; }
@@ -870,7 +870,7 @@ struct FileCheckString {
/// Matches check string and its "not strings" and/or "dag strings".
size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode,
size_t &MatchLen, FileCheckRequest &Req,
- std::vector<FileCheckDiag> *Diags) const;
+ FileCheckDiagList *Diags) const;
/// Verifies that there is a single line in the given \p Buffer. Errors are
/// reported against \p SM.
@@ -883,13 +883,11 @@ struct FileCheckString {
/// \p Diags according to the verbosity level set in \p Req.
bool CheckNot(const SourceMgr &SM, StringRef Buffer,
const std::vector<const DagNotPrefixInfo *> &NotStrings,
- const FileCheckRequest &Req,
- std::vector<FileCheckDiag> *Diags) const;
+ const FileCheckRequest &Req, FileCheckDiagList *Diags) const;
/// Matches "dag strings" and their mixed "not strings".
size_t CheckDag(const SourceMgr &SM, StringRef Buffer,
std::vector<const DagNotPrefixInfo *> &NotStrings,
- const FileCheckRequest &Req,
- std::vector<FileCheckDiag> *Diags) const;
+ const FileCheckRequest &Req, FileCheckDiagList *Diags) const;
};
} // namespace llvm
diff --git a/llvm/unittests/FileCheck/FileCheckTest.cpp b/llvm/unittests/FileCheck/FileCheckTest.cpp
index 2c4130330e970..cc6d4f9ce9325 100644
--- a/llvm/unittests/FileCheck/FileCheckTest.cpp
+++ b/llvm/unittests/FileCheck/FileCheckTest.cpp
@@ -915,7 +915,7 @@ class PatternTester {
}
void printVariableDefs(FileCheckDiag::MatchType MatchTy,
- std::vector<FileCheckDiag> &Diags) {
+ FileCheckDiagList &Diags) {
P.printVariableDefs(SM, MatchTy, &Diags);
}
};
@@ -1641,7 +1641,7 @@ TEST_F(FileCheckTest, CapturedVarDiags) {
PatternTester Tester;
ASSERT_FALSE(Tester.parsePattern("[[STRVAR:[a-z]+]] [[#NUMVAR:@LINE]]"));
EXPECT_THAT_EXPECTED(Tester.match("foobar 2"), Succeeded());
- std::vector<FileCheckDiag> Diags;
+ FileCheckDiagList Diags;
Tester.printVariableDefs(FileCheckDiag::MatchFoundAndExpected, Diags);
EXPECT_EQ(Diags.size(), 2ul);
for (const FileCheckDiag &Diag : Diags) {
diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp
index 12fdbfd45279d..45d823dca6808 100644
--- a/llvm/utils/FileCheck/FileCheck.cpp
+++ b/llvm/utils/FileCheck/FileCheck.cpp
@@ -377,9 +377,9 @@ static std::string GetCheckTypeAbbreviation(Check::FileCheckType Ty) {
}
static void
-BuildInputAnnotations(const SourceMgr &SM, unsigned CheckFileBufferID,
+buildInputAnnotations(const SourceMgr &SM, unsigned CheckFileBufferID,
const std::pair<unsigned, unsigned> &ImpPatBufferIDRange,
- const std::vector<FileCheckDiag> &Diags,
+ const FileCheckDiagList &Diags,
std::vector<InputAnnotation> &Annotations,
unsigned &LabelWidth) {
struct CompareSMLoc {
@@ -397,17 +397,15 @@ BuildInputAnnotations(const SourceMgr &SM, unsigned CheckFileBufferID,
unsigned DiagIndex = 0;
// What's the widest label?
LabelWidth = 0;
- for (auto DiagItr = Diags.begin(), DiagEnd = Diags.end(); DiagItr != DiagEnd;
- ++DiagItr) {
+ for (const FileCheckDiag &Diag : Diags) {
InputAnnotation A;
A.DiagIndex = DiagIndex++;
// Build label, which uniquely identifies this check result.
- unsigned CheckBufferID = SM.FindBufferContainingLoc(DiagItr->CheckLoc);
- auto CheckLineAndCol =
- SM.getLineAndColumn(DiagItr->CheckLoc, CheckBufferID);
+ unsigned CheckBufferID = SM.FindBufferContainingLoc(Diag.CheckLoc);
+ auto CheckLineAndCol = SM.getLineAndColumn(Diag.CheckLoc, CheckBufferID);
llvm::raw_string_ostream Label(A.Label);
- Label << GetCheckTypeAbbreviation(DiagItr->CheckTy) << ":";
+ Label << GetCheckTypeAbbreviation(Diag.CheckTy) << ":";
if (CheckBufferID == CheckFileBufferID)
Label << CheckLineAndCol.first;
else if (ImpPatBufferIDRange.first <= CheckBufferID &&
@@ -416,53 +414,52 @@ BuildInputAnnotations(const SourceMgr &SM, unsigned CheckFileBufferID,
else
llvm_unreachable("expected diagnostic's check location to be either in "
"the check file or for an implicit pattern");
- if (DiagCountPerPattern[DiagItr->CheckLoc] > 1)
- Label << "'" << DiagIndexPerPattern[DiagItr->CheckLoc]++;
+ if (DiagCountPerPattern[Diag.CheckLoc] > 1)
+ Label << "'" << DiagIndexPerPattern[Diag.CheckLoc]++;
LabelWidth = std::max((std::string::size_type)LabelWidth, A.Label.size());
- A.Marker = GetMarker(DiagItr->MatchTy);
- if (!DiagItr->Note.empty()) {
- A.Marker.Note = DiagItr->Note;
+ A.Marker = GetMarker(Diag.MatchTy);
+ if (!Diag.Note.empty()) {
+ A.Marker.Note = Diag.Note;
// It's less confusing if notes that don't actually have ranges don't have
// markers. For example, a marker for 'with "VAR" equal to "5"' would
// seem to indicate where "VAR" matches, but the location we actually have
// for the marker simply points to the start of the match/search range for
// the full pattern of which the substitution is potentially just one
// component.
- if (DiagItr->InputStartLine == DiagItr->InputEndLine &&
- DiagItr->InputStartCol == DiagItr->InputEndCol)
+ if (Diag.InputStartLine == Diag.InputEndLine &&
+ Diag.InputStartCol == Diag.InputEndCol)
A.Marker.Lead = ' ';
}
- if (DiagItr->MatchTy == FileCheckDiag::MatchFoundErrorNote) {
- assert(!DiagItr->Note.empty() &&
+ if (Diag.MatchTy == FileCheckDiag::MatchFoundErrorNote) {
+ assert(!Diag.Note.empty() &&
"expected custom note for MatchFoundErrorNote");
A.Marker.Note = "error: " + A.Marker.Note;
}
A.FoundAndExpectedMatch =
- DiagItr->MatchTy == FileCheckDiag::MatchFoundAndExpected;
+ Diag.MatchTy == FileCheckDiag::MatchFoundAndExpected;
// Compute the mark location, and break annotation into multiple
// annotations if it spans multiple lines.
A.IsFirstLine = true;
- A.InputLine = DiagItr->InputStartLine;
- A.InputStartCol = DiagItr->InputStartCol;
- if (DiagItr->InputStartLine == DiagItr->InputEndLine) {
+ A.InputLine = Diag.InputStartLine;
+ A.InputStartCol = Diag.InputStartCol;
+ if (Diag.InputStartLine == Diag.InputEndLine) {
// Sometimes ranges are empty in order to indicate a specific point, but
// that would mean nothing would be marked, so adjust the range to
// include the following character.
- A.InputEndCol =
- std::max(DiagItr->InputStartCol + 1, DiagItr->InputEndCol);
+ A.InputEndCol = std::max(Diag.InputStartCol + 1, Diag.InputEndCol);
Annotations.push_back(A);
} else {
- assert(DiagItr->InputStartLine < DiagItr->InputEndLine &&
+ assert(Diag.InputStartLine < Diag.InputEndLine &&
"expected input range not to be inverted");
A.InputEndCol = UINT_MAX;
Annotations.push_back(A);
- for (unsigned L = DiagItr->InputStartLine + 1, E = DiagItr->InputEndLine;
- L <= E; ++L) {
+ for (unsigned L = Diag.InputStartLine + 1, E = Diag.InputEndLine; L <= E;
+ ++L) {
// If a range ends before the first column on a line, then it has no
// characters on that line, so there's nothing to render.
- if (DiagItr->InputEndCol == 1 && L == E)
+ if (Diag.InputEndCol == 1 && L == E)
break;
InputAnnotation B;
B.DiagIndex = A.DiagIndex;
@@ -476,7 +473,7 @@ BuildInputAnnotations(const SourceMgr &SM, unsigned CheckFileBufferID,
if (L != E)
B.InputEndCol = UINT_MAX;
else
- B.InputEndCol = DiagItr->InputEndCol;
+ B.InputEndCol = Diag.InputEndCol;
B.FoundAndExpectedMatch = A.FoundAndExpectedMatch;
Annotations.push_back(B);
}
@@ -853,7 +850,7 @@ int main(int argc, char **argv) {
InputFileText, InputFile.getBufferIdentifier()),
SMLoc());
- std::vector<FileCheckDiag> Diags;
+ FileCheckDiagList Diags;
int ExitCode = FC.checkInput(SM, InputFileText,
DumpInput == DumpInputNever ? nullptr : &Diags)
? EXIT_SUCCESS
@@ -868,7 +865,7 @@ int main(int argc, char **argv) {
<< "\n";
std::vector<InputAnnotation> Annotations;
unsigned LabelWidth;
- BuildInputAnnotations(SM, CheckFileBufferID, ImpPatBufferIDRange, Diags,
+ buildInputAnnotations(SM, CheckFileBufferID, ImpPatBufferIDRange, Diags,
Annotations, LabelWidth);
DumpAnnotatedInput(errs(), Req, DumpInputFilter, DumpInputContext,
InputFileText, Annotations, LabelWidth);
More information about the llvm-commits
mailing list