[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
https://github.com/jdenny-ornl edited https://github.com/llvm/llvm-project/pull/195569 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
@@ -111,24 +112,29 @@ class FileCheckType {
};
} // namespace Check
-/// Summary of a FileCheck diagnostic.
-struct FileCheckDiag {
- /// What is the FileCheck directive for this diagnostic?
- Check::FileCheckType CheckTy;
- /// Where is the FileCheck directive for this diagnostic?
- SMLoc CheckLoc;
+class MatchResultDiag;
+
+/// Abstract base class for recording a FileCheck diagnostic for a pattern
+/// (e.g., \c CHECK-NEXT directive or \c --implicit-check-not).
+///
+/// \c FileCheckDiag has two direct derived classes:
+/// - \c MatchResultDiag records a match result for a pattern. There might be
+/// more than one for a single pattern. For example, for \c CHECK-DAG there
+/// might be several discarded matches before either a good match or a
failure
+/// to match.
+/// - \c MatchNoteDiag provides an additional note about the most recent
+/// \c MatchResultDiag emitted by a FileCheck invocation. For example, there
+/// might be a fuzzy match after a failure to match.
+class FileCheckDiag {
+public:
+ enum FileCheckDiagKind { FCDK_MatchResultDiag, FCDK_MatchNoteDiag };
jdenny-ornl wrote:
Without `FCDK_`, these enumerators collide with the derived class names in
derived class methods, in particular `classof`. Is it preferred to qualify
them like `FileCheckDiag::MatchResultDiag` there instead?
Using `FCDK_` is an attempt to followed the examples in [LLVM's RTTI
docs](https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html#basic-setup). Do
those docs need to be updated for LLVM's current preferred style?
https://github.com/llvm/llvm-project/pull/195569
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
@@ -390,76 +390,95 @@ buildInputAnnotations(const SourceMgr &SM, unsigned
CheckFileBufferID,
// How many diagnostics does each pattern have?
std::map DiagCountPerPattern;
for (const FileCheckDiag &Diag : Diags)
-++DiagCountPerPattern[Diag.CheckLoc];
+++DiagCountPerPattern[Diag.getMatchResultDiag().getCheckLoc()];
// How many diagnostics have we seen so far per pattern?
std::map DiagIndexPerPattern;
// How many total diagnostics have we seen so far?
unsigned DiagIndex = 0;
// What's the widest label?
LabelWidth = 0;
+ // The label prefix that uniquely identifies the current MatchResultDiag and
+ // its MatchNoteDiag series.
+ std::string CurLabelPrefix;
for (const FileCheckDiag &Diag : Diags) {
InputAnnotation A;
A.DiagIndex = DiagIndex++;
+if (const MatchResultDiag *MRD = dyn_cast(&Diag)) {
+ CurLabelPrefix.clear();
+ llvm::raw_string_ostream LabelStrm(CurLabelPrefix);
+ LabelStrm << GetCheckTypeAbbreviation(MRD->getCheckTy()) << ":";
+ unsigned CheckBufferID = SM.FindBufferContainingLoc(MRD->getCheckLoc());
+ if (CheckBufferID == CheckFileBufferID)
+LabelStrm
+<< SM.getLineAndColumn(MRD->getCheckLoc(), CheckBufferID).first;
+ else if (ImpPatBufferIDRange.first <= CheckBufferID &&
+ CheckBufferID < ImpPatBufferIDRange.second)
+LabelStrm << "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");
+}
-// Build label, which uniquely identifies this check result.
-unsigned CheckBufferID = SM.FindBufferContainingLoc(Diag.CheckLoc);
-auto CheckLineAndCol = SM.getLineAndColumn(Diag.CheckLoc, CheckBufferID);
-llvm::raw_string_ostream Label(A.Label);
-Label << GetCheckTypeAbbreviation(Diag.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");
-if (DiagCountPerPattern[Diag.CheckLoc] > 1)
- Label << "'" << DiagIndexPerPattern[Diag.CheckLoc]++;
+// Build label that uniquely identifies this FileCheckDiag.
+llvm::raw_string_ostream LabelStrm(A.Label);
+LabelStrm << CurLabelPrefix;
+if (DiagCountPerPattern[Diag.getMatchResultDiag().getCheckLoc()] > 1)
+ LabelStrm
+ << "'"
+ << DiagIndexPerPattern[Diag.getMatchResultDiag().getCheckLoc()]++;
LabelWidth = std::max((std::string::size_type)LabelWidth, A.Label.size());
-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 (Diag.InputStartLine == Diag.InputEndLine &&
- Diag.InputStartCol == Diag.InputEndCol)
-A.Marker.Lead = ' ';
+A.Marker = GetMarker(Diag.getMatchType());
+std::optional CustomNote = std::nullopt;
jdenny-ornl wrote:
> `optional` defaults to `nullopt`.
Dropped the init.
> Why not just use `StringRef CustomNote`?
Are you suggesting dropping the `std::optional`? It is there because we do not
always have a custom note.
https://github.com/llvm/llvm-project/pull/195569
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
@@ -159,41 +165,124 @@ struct FileCheckDiag {
/// Indicates a fuzzy match that serves as a suggestion for the next
/// intended match for an expected pattern with too few or no good matches.
MatchFuzzy,
- } MatchTy;
+ };
+
+private:
+ const FileCheckDiagKind Kind;
+ MatchType MatchTy;
+ SMRange InputRange;
+
+public:
+ FileCheckDiag(FileCheckDiagKind Kind, MatchType MatchTy, SMRange InputRange)
+ : Kind(Kind), MatchTy(MatchTy), InputRange(InputRange) {}
+ /// Destructor is purely virtual to ensure this remains an abstract class.
+ virtual ~FileCheckDiag() = 0;
+ /// Of what derived class is this an instance?
+ FileCheckDiagKind getKind() const { return Kind; }
+ /// If this is a \c MatchResultDiag, return itself. If this is a
+ /// \c MatchNoteDiag, return its associated \c MatchResultDiag.
+ virtual const MatchResultDiag &getMatchResultDiag() const = 0;
+ /// Adjust the match type.
+ void adjustMatchType(MatchType MatchTy) { this->MatchTy = MatchTy; }
+ /// Get the match type.
+ MatchType getMatchType() const { return MatchTy; }
/// The search range if MatchTy starts with MatchNone, or the match range
/// otherwise.
- unsigned InputStartLine;
- unsigned InputStartCol;
- unsigned InputEndLine;
- unsigned InputEndCol;
- /// A note to replace the one normally indicated by MatchTy, or the empty
- /// string if none.
- std::string Note;
- LLVM_ABI FileCheckDiag(const SourceMgr &SM,
- const Check::FileCheckType &CheckTy, SMLoc CheckLoc,
- MatchType MatchTy, SMRange InputRange,
- StringRef Note = "");
+ SMRange getInputRange() const { return InputRange; }
+};
+
+/// Class for recording a FileCheck diagnostic that reports a match result for
a
+/// pattern.
+class MatchResultDiag : public FileCheckDiag {
+private:
+ Check::FileCheckType CheckTy;
+ SMLoc CheckLoc;
+
+public:
+ MatchResultDiag(const Check::FileCheckType &CheckTy, SMLoc CheckLoc,
+ MatchType MatchTy, SMRange InputRange)
+ : FileCheckDiag(FCDK_MatchResultDiag, MatchTy, InputRange),
+CheckTy(CheckTy), CheckLoc(CheckLoc) {}
+ /// Is \p FCD an instance of \c MatchResultDiag?
+ static bool classof(const FileCheckDiag *FCD) {
+return FCD->getKind() == FCDK_MatchResultDiag;
+ }
+ /// Get itself.
+ virtual const MatchResultDiag &getMatchResultDiag() const override {
jdenny-ornl wrote:
Done.
https://github.com/llvm/llvm-project/pull/195569
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
https://github.com/jdenny-ornl updated
https://github.com/llvm/llvm-project/pull/195569
>From 1f468c7903b13911e75c8704a129e8b6e86aa18b Mon Sep 17 00:00:00 2001
From: "Joel E. Denny"
Date: Sun, 3 May 2026 17:58:37 -0400
Subject: [PATCH 1/3] [FileCheck][NFC] Introduce MatchResultDiag and
MatchNoteDiag
This patch depends on PR # and continues its effort to decouple
the `-dump-input` presentation layer (in
`llvm/utils/FileCheck/FileCheck.cpp`) and the FileCheck library's
diagnostic emission (in `llvm/lib/FileCheck/FileCheck.cpp`).
Similar to compiler errors/warnings/remarks vs. notes, the
`FileCheckDiag` series emitted by the FileCheck library contains match
results, each of which might be followed by a series of associated
notes before the next match result. Without this patch series, that
association is not formally modeled by `FileCheckDiag` or clearly
documented, and `-dump-input` is not able to easily reason about it.
This patch improves the situation by introducing two `FileCheckDiag`
derived classes: `MatchResultDiag` and `MatchNoteDiag`. It extends
`FileCheckDiagList` to directly associate each `MatchNoteDiag` with
its `MatchResultDiag`. Thus:
- `FileCheckDiagList::adjustPrevDiags` no longer has to determine that
association based on directive location info.
- Match result instances of `FileCheckDiag` no longer need to store a
redundant custom note field, which only makes sense for notes.
- Note instances of `FileCheckDiag` no longer need to store the
directive type and location, which are already stored by their match
result instances.
- In both the FileCheck library and the `-dump-input` presentation
layer, it is now clearer when a `FileCheckDiag` is a match result
vs. a note.
---
llvm/include/llvm/FileCheck/FileCheck.h| 153 -
llvm/lib/FileCheck/FileCheck.cpp | 48 +++
llvm/unittests/FileCheck/FileCheckTest.cpp | 32 +++--
llvm/utils/FileCheck/FileCheck.cpp | 101 --
4 files changed, 221 insertions(+), 113 deletions(-)
diff --git a/llvm/include/llvm/FileCheck/FileCheck.h
b/llvm/include/llvm/FileCheck/FileCheck.h
index 07684e6fc6cff..b171d1048cddb 100644
--- a/llvm/include/llvm/FileCheck/FileCheck.h
+++ b/llvm/include/llvm/FileCheck/FileCheck.h
@@ -14,6 +14,7 @@
#define LLVM_FILECHECK_FILECHECK_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/SMLoc.h"
@@ -110,24 +111,29 @@ class FileCheckType {
};
} // namespace Check
-/// Summary of a FileCheck diagnostic.
-struct FileCheckDiag {
- /// What is the FileCheck directive for this diagnostic?
- Check::FileCheckType CheckTy;
- /// Where is the FileCheck directive for this diagnostic?
- SMLoc CheckLoc;
+class MatchResultDiag;
+
+/// Abstract base class for recording a FileCheck diagnostic for a pattern
+/// (e.g., \c CHECK-NEXT directive or \c --implicit-check-not).
+///
+/// \c FileCheckDiag has two direct derived classes:
+/// - \c MatchResultDiag records a match result for a pattern. There might be
+/// more than one for a single pattern. For example, for \c CHECK-DAG there
+/// might be several discarded matches before either a good match or a
failure
+/// to match.
+/// - \c MatchNoteDiag provides an additional note about the most recent
+/// \c MatchResultDiag emitted by a FileCheck invocation. For example, there
+/// might be a fuzzy match after a failure to match.
+class FileCheckDiag {
+public:
+ enum FileCheckDiagKind { FCDK_MatchResultDiag, FCDK_MatchNoteDiag };
+
/// What type of match result does this diagnostic describe?
///
/// A directive's supplied pattern is said to be either expected or excluded
/// depending on whether the pattern must have or must not have a match in
/// order for the directive to succeed. For example, a CHECK directive's
/// pattern is expected, and a CHECK-NOT directive's pattern is excluded.
- ///
- /// There might be more than one match result for a single pattern. For
- /// example, there might be several discarded matches
- /// (MatchFoundButDiscarded) before either a good match
- /// (MatchFoundAndExpected) or a failure to match (MatchNoneButExpected),
- /// and there might be a fuzzy match (MatchFuzzy) after the latter.
enum MatchType {
/// Indicates a good match for an expected pattern.
MatchFoundAndExpected,
@@ -158,39 +164,122 @@ struct FileCheckDiag {
/// Indicates a fuzzy match that serves as a suggestion for the next
/// intended match for an expected pattern with too few or no good matches.
MatchFuzzy,
- } MatchTy;
+ };
+
+private:
+ const FileCheckDiagKind Kind;
+ MatchType MatchTy;
+ SMRange InputRange;
+
+public:
+ FileCheckDiag(FileCheckDiagKind Kind, MatchType MatchTy, SMRange InputRange)
+ : Kind(Kind), MatchTy(MatchTy), InputRange(InputRange) {}
+ /// Destructor is purely virtual to ensure this remains an
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
@@ -111,24 +112,29 @@ class FileCheckType {
};
} // namespace Check
-/// Summary of a FileCheck diagnostic.
-struct FileCheckDiag {
- /// What is the FileCheck directive for this diagnostic?
- Check::FileCheckType CheckTy;
- /// Where is the FileCheck directive for this diagnostic?
- SMLoc CheckLoc;
+class MatchResultDiag;
+
+/// Abstract base class for recording a FileCheck diagnostic for a pattern
+/// (e.g., \c CHECK-NEXT directive or \c --implicit-check-not).
+///
+/// \c FileCheckDiag has two direct derived classes:
+/// - \c MatchResultDiag records a match result for a pattern. There might be
+/// more than one for a single pattern. For example, for \c CHECK-DAG there
+/// might be several discarded matches before either a good match or a
failure
+/// to match.
+/// - \c MatchNoteDiag provides an additional note about the most recent
+/// \c MatchResultDiag emitted by a FileCheck invocation. For example, there
+/// might be a fuzzy match after a failure to match.
+class FileCheckDiag {
+public:
+ enum FileCheckDiagKind { FCDK_MatchResultDiag, FCDK_MatchNoteDiag };
MaskRay wrote:
`FCDK_` prefix is reundant since the enum is nested in the class
https://github.com/llvm/llvm-project/pull/195569
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
@@ -390,76 +390,95 @@ buildInputAnnotations(const SourceMgr &SM, unsigned
CheckFileBufferID,
// How many diagnostics does each pattern have?
std::map DiagCountPerPattern;
for (const FileCheckDiag &Diag : Diags)
-++DiagCountPerPattern[Diag.CheckLoc];
+++DiagCountPerPattern[Diag.getMatchResultDiag().getCheckLoc()];
// How many diagnostics have we seen so far per pattern?
std::map DiagIndexPerPattern;
// How many total diagnostics have we seen so far?
unsigned DiagIndex = 0;
// What's the widest label?
LabelWidth = 0;
+ // The label prefix that uniquely identifies the current MatchResultDiag and
+ // its MatchNoteDiag series.
+ std::string CurLabelPrefix;
for (const FileCheckDiag &Diag : Diags) {
InputAnnotation A;
A.DiagIndex = DiagIndex++;
+if (const MatchResultDiag *MRD = dyn_cast(&Diag)) {
+ CurLabelPrefix.clear();
+ llvm::raw_string_ostream LabelStrm(CurLabelPrefix);
+ LabelStrm << GetCheckTypeAbbreviation(MRD->getCheckTy()) << ":";
+ unsigned CheckBufferID = SM.FindBufferContainingLoc(MRD->getCheckLoc());
+ if (CheckBufferID == CheckFileBufferID)
+LabelStrm
+<< SM.getLineAndColumn(MRD->getCheckLoc(), CheckBufferID).first;
+ else if (ImpPatBufferIDRange.first <= CheckBufferID &&
+ CheckBufferID < ImpPatBufferIDRange.second)
+LabelStrm << "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");
+}
-// Build label, which uniquely identifies this check result.
-unsigned CheckBufferID = SM.FindBufferContainingLoc(Diag.CheckLoc);
-auto CheckLineAndCol = SM.getLineAndColumn(Diag.CheckLoc, CheckBufferID);
-llvm::raw_string_ostream Label(A.Label);
-Label << GetCheckTypeAbbreviation(Diag.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");
-if (DiagCountPerPattern[Diag.CheckLoc] > 1)
- Label << "'" << DiagIndexPerPattern[Diag.CheckLoc]++;
+// Build label that uniquely identifies this FileCheckDiag.
+llvm::raw_string_ostream LabelStrm(A.Label);
+LabelStrm << CurLabelPrefix;
+if (DiagCountPerPattern[Diag.getMatchResultDiag().getCheckLoc()] > 1)
+ LabelStrm
+ << "'"
+ << DiagIndexPerPattern[Diag.getMatchResultDiag().getCheckLoc()]++;
LabelWidth = std::max((std::string::size_type)LabelWidth, A.Label.size());
-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 (Diag.InputStartLine == Diag.InputEndLine &&
- Diag.InputStartCol == Diag.InputEndCol)
-A.Marker.Lead = ' ';
+A.Marker = GetMarker(Diag.getMatchType());
+std::optional CustomNote = std::nullopt;
MaskRay wrote:
`optional` defaults to `nullopt`. Why not just use `StringRef CustomNote`?
https://github.com/llvm/llvm-project/pull/195569
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
https://github.com/MaskRay approved this pull request. https://github.com/llvm/llvm-project/pull/195569 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
@@ -159,41 +165,124 @@ struct FileCheckDiag {
/// Indicates a fuzzy match that serves as a suggestion for the next
/// intended match for an expected pattern with too few or no good matches.
MatchFuzzy,
- } MatchTy;
+ };
+
+private:
+ const FileCheckDiagKind Kind;
+ MatchType MatchTy;
+ SMRange InputRange;
+
+public:
+ FileCheckDiag(FileCheckDiagKind Kind, MatchType MatchTy, SMRange InputRange)
+ : Kind(Kind), MatchTy(MatchTy), InputRange(InputRange) {}
+ /// Destructor is purely virtual to ensure this remains an abstract class.
+ virtual ~FileCheckDiag() = 0;
+ /// Of what derived class is this an instance?
+ FileCheckDiagKind getKind() const { return Kind; }
+ /// If this is a \c MatchResultDiag, return itself. If this is a
+ /// \c MatchNoteDiag, return its associated \c MatchResultDiag.
+ virtual const MatchResultDiag &getMatchResultDiag() const = 0;
+ /// Adjust the match type.
+ void adjustMatchType(MatchType MatchTy) { this->MatchTy = MatchTy; }
+ /// Get the match type.
+ MatchType getMatchType() const { return MatchTy; }
/// The search range if MatchTy starts with MatchNone, or the match range
/// otherwise.
- unsigned InputStartLine;
- unsigned InputStartCol;
- unsigned InputEndLine;
- unsigned InputEndCol;
- /// A note to replace the one normally indicated by MatchTy, or the empty
- /// string if none.
- std::string Note;
- LLVM_ABI FileCheckDiag(const SourceMgr &SM,
- const Check::FileCheckType &CheckTy, SMLoc CheckLoc,
- MatchType MatchTy, SMRange InputRange,
- StringRef Note = "");
+ SMRange getInputRange() const { return InputRange; }
+};
+
+/// Class for recording a FileCheck diagnostic that reports a match result for
a
+/// pattern.
+class MatchResultDiag : public FileCheckDiag {
+private:
+ Check::FileCheckType CheckTy;
+ SMLoc CheckLoc;
+
+public:
+ MatchResultDiag(const Check::FileCheckType &CheckTy, SMLoc CheckLoc,
+ MatchType MatchTy, SMRange InputRange)
+ : FileCheckDiag(FCDK_MatchResultDiag, MatchTy, InputRange),
+CheckTy(CheckTy), CheckLoc(CheckLoc) {}
+ /// Is \p FCD an instance of \c MatchResultDiag?
+ static bool classof(const FileCheckDiag *FCD) {
+return FCD->getKind() == FCDK_MatchResultDiag;
+ }
+ /// Get itself.
+ virtual const MatchResultDiag &getMatchResultDiag() const override {
MaskRay wrote:
drop `virtual` with `override`.
https://github.com/llvm/llvm-project/pull/195569
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-testing-tools
Author: Joel E. Denny (jdenny-ornl)
Changes
This patch depends on PR #195568 and continues its effort to decouple
the `-dump-input` presentation layer (in
`llvm/utils/FileCheck/FileCheck.cpp`) and the FileCheck library's diagnostic
emission (in `llvm/lib/FileCheck/FileCheck.cpp`).
Similar to compiler errors/warnings/remarks vs. notes, the `FileCheckDiag`
series emitted by the FileCheck library contains match results, each of which
might be followed by a series of associated notes before the next match result.
Without this patch series, that association is not formally modeled by
`FileCheckDiag` or clearly documented, and `-dump-input` is not able to easily
reason about it.
This patch improves the situation by introducing two `FileCheckDiag` derived
classes: `MatchResultDiag` and `MatchNoteDiag`. It extends `FileCheckDiagList`
to directly associate each `MatchNoteDiag` with its `MatchResultDiag`. Thus:
- `FileCheckDiagList::adjustPrevDiags` no longer has to determine that
association based on directive location info.
- Match result instances of `FileCheckDiag` no longer need to store a redundant
custom note field, which only makes sense for notes.
- Note instances of `FileCheckDiag` no longer need to store the directive type
and location, which are already stored by their match result instances.
- In both the FileCheck library and the `-dump-input` presentation layer, it is
now clearer when a `FileCheckDiag` is a match result vs. a note.
---
Patch is 24.24 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/195569.diff
4 Files Affected:
- (modified) llvm/include/llvm/FileCheck/FileCheck.h (+121-32)
- (modified) llvm/lib/FileCheck/FileCheck.cpp (+18-30)
- (modified) llvm/unittests/FileCheck/FileCheckTest.cpp (+22-10)
- (modified) llvm/utils/FileCheck/FileCheck.cpp (+60-41)
``diff
diff --git a/llvm/include/llvm/FileCheck/FileCheck.h
b/llvm/include/llvm/FileCheck/FileCheck.h
index 07684e6fc6cff..b171d1048cddb 100644
--- a/llvm/include/llvm/FileCheck/FileCheck.h
+++ b/llvm/include/llvm/FileCheck/FileCheck.h
@@ -14,6 +14,7 @@
#define LLVM_FILECHECK_FILECHECK_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/SMLoc.h"
@@ -110,24 +111,29 @@ class FileCheckType {
};
} // namespace Check
-/// Summary of a FileCheck diagnostic.
-struct FileCheckDiag {
- /// What is the FileCheck directive for this diagnostic?
- Check::FileCheckType CheckTy;
- /// Where is the FileCheck directive for this diagnostic?
- SMLoc CheckLoc;
+class MatchResultDiag;
+
+/// Abstract base class for recording a FileCheck diagnostic for a pattern
+/// (e.g., \c CHECK-NEXT directive or \c --implicit-check-not).
+///
+/// \c FileCheckDiag has two direct derived classes:
+/// - \c MatchResultDiag records a match result for a pattern. There might be
+/// more than one for a single pattern. For example, for \c CHECK-DAG there
+/// might be several discarded matches before either a good match or a
failure
+/// to match.
+/// - \c MatchNoteDiag provides an additional note about the most recent
+/// \c MatchResultDiag emitted by a FileCheck invocation. For example, there
+/// might be a fuzzy match after a failure to match.
+class FileCheckDiag {
+public:
+ enum FileCheckDiagKind { FCDK_MatchResultDiag, FCDK_MatchNoteDiag };
+
/// What type of match result does this diagnostic describe?
///
/// A directive's supplied pattern is said to be either expected or excluded
/// depending on whether the pattern must have or must not have a match in
/// order for the directive to succeed. For example, a CHECK directive's
/// pattern is expected, and a CHECK-NOT directive's pattern is excluded.
- ///
- /// There might be more than one match result for a single pattern. For
- /// example, there might be several discarded matches
- /// (MatchFoundButDiscarded) before either a good match
- /// (MatchFoundAndExpected) or a failure to match (MatchNoneButExpected),
- /// and there might be a fuzzy match (MatchFuzzy) after the latter.
enum MatchType {
/// Indicates a good match for an expected pattern.
MatchFoundAndExpected,
@@ -158,39 +164,122 @@ struct FileCheckDiag {
/// Indicates a fuzzy match that serves as a suggestion for the next
/// intended match for an expected pattern with too few or no good matches.
MatchFuzzy,
- } MatchTy;
+ };
+
+private:
+ const FileCheckDiagKind Kind;
+ MatchType MatchTy;
+ SMRange InputRange;
+
+public:
+ FileCheckDiag(FileCheckDiagKind Kind, MatchType MatchTy, SMRange InputRange)
+ : Kind(Kind), MatchTy(MatchTy), InputRange(InputRange) {}
+ /// Destructor is purely virtual to ensure this remains an abstract class.
+ virtual ~FileCheckDiag() = 0;
+ /// Of what derived class is
[llvm-branch-commits] [llvm] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag (PR #195569)
https://github.com/jdenny-ornl created
https://github.com/llvm/llvm-project/pull/195569
This patch depends on PR #195568 and continues its effort to decouple the
`-dump-input` presentation layer (in
`llvm/utils/FileCheck/FileCheck.cpp`) and the FileCheck library's diagnostic
emission (in `llvm/lib/FileCheck/FileCheck.cpp`).
Similar to compiler errors/warnings/remarks vs. notes, the `FileCheckDiag`
series emitted by the FileCheck library contains match results, each of which
might be followed by a series of associated notes before the next match result.
Without this patch series, that association is not formally modeled by
`FileCheckDiag` or clearly documented, and `-dump-input` is not able to easily
reason about it.
This patch improves the situation by introducing two `FileCheckDiag` derived
classes: `MatchResultDiag` and `MatchNoteDiag`. It extends `FileCheckDiagList`
to directly associate each `MatchNoteDiag` with its `MatchResultDiag`. Thus:
- `FileCheckDiagList::adjustPrevDiags` no longer has to determine that
association based on directive location info.
- Match result instances of `FileCheckDiag` no longer need to store a redundant
custom note field, which only makes sense for notes.
- Note instances of `FileCheckDiag` no longer need to store the directive type
and location, which are already stored by their match result instances.
- In both the FileCheck library and the `-dump-input` presentation layer, it is
now clearer when a `FileCheckDiag` is a match result vs. a note.
>From 1f468c7903b13911e75c8704a129e8b6e86aa18b Mon Sep 17 00:00:00 2001
From: "Joel E. Denny"
Date: Sun, 3 May 2026 17:58:37 -0400
Subject: [PATCH] [FileCheck][NFC] Introduce MatchResultDiag and MatchNoteDiag
This patch depends on PR # and continues its effort to decouple
the `-dump-input` presentation layer (in
`llvm/utils/FileCheck/FileCheck.cpp`) and the FileCheck library's
diagnostic emission (in `llvm/lib/FileCheck/FileCheck.cpp`).
Similar to compiler errors/warnings/remarks vs. notes, the
`FileCheckDiag` series emitted by the FileCheck library contains match
results, each of which might be followed by a series of associated
notes before the next match result. Without this patch series, that
association is not formally modeled by `FileCheckDiag` or clearly
documented, and `-dump-input` is not able to easily reason about it.
This patch improves the situation by introducing two `FileCheckDiag`
derived classes: `MatchResultDiag` and `MatchNoteDiag`. It extends
`FileCheckDiagList` to directly associate each `MatchNoteDiag` with
its `MatchResultDiag`. Thus:
- `FileCheckDiagList::adjustPrevDiags` no longer has to determine that
association based on directive location info.
- Match result instances of `FileCheckDiag` no longer need to store a
redundant custom note field, which only makes sense for notes.
- Note instances of `FileCheckDiag` no longer need to store the
directive type and location, which are already stored by their match
result instances.
- In both the FileCheck library and the `-dump-input` presentation
layer, it is now clearer when a `FileCheckDiag` is a match result
vs. a note.
---
llvm/include/llvm/FileCheck/FileCheck.h| 153 -
llvm/lib/FileCheck/FileCheck.cpp | 48 +++
llvm/unittests/FileCheck/FileCheckTest.cpp | 32 +++--
llvm/utils/FileCheck/FileCheck.cpp | 101 --
4 files changed, 221 insertions(+), 113 deletions(-)
diff --git a/llvm/include/llvm/FileCheck/FileCheck.h
b/llvm/include/llvm/FileCheck/FileCheck.h
index 07684e6fc6cff..b171d1048cddb 100644
--- a/llvm/include/llvm/FileCheck/FileCheck.h
+++ b/llvm/include/llvm/FileCheck/FileCheck.h
@@ -14,6 +14,7 @@
#define LLVM_FILECHECK_FILECHECK_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/SMLoc.h"
@@ -110,24 +111,29 @@ class FileCheckType {
};
} // namespace Check
-/// Summary of a FileCheck diagnostic.
-struct FileCheckDiag {
- /// What is the FileCheck directive for this diagnostic?
- Check::FileCheckType CheckTy;
- /// Where is the FileCheck directive for this diagnostic?
- SMLoc CheckLoc;
+class MatchResultDiag;
+
+/// Abstract base class for recording a FileCheck diagnostic for a pattern
+/// (e.g., \c CHECK-NEXT directive or \c --implicit-check-not).
+///
+/// \c FileCheckDiag has two direct derived classes:
+/// - \c MatchResultDiag records a match result for a pattern. There might be
+/// more than one for a single pattern. For example, for \c CHECK-DAG there
+/// might be several discarded matches before either a good match or a
failure
+/// to match.
+/// - \c MatchNoteDiag provides an additional note about the most recent
+/// \c MatchResultDiag emitted by a FileCheck invocation. For example, there
+/// might be a fuzzy match after a failure to match.
+class FileCheckDiag {
+public:
+ enum
