[Mlir-commits] [llvm] [mlir] [Support] Simplify the SourceMgrDiagnosticVerifier interface. NFC (PR #227567)
Alexander Richardson
llvmlistbot at llvm.org
Tue Oct 20 14:57:46 PDT 2026
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/227567
>From 2b95f0ed7c7ed0a58e24d273d0cdf55d7012fff6 Mon Sep 17 00:00:00 2001
From: Alex Richardson <alexrichardson at google.com>
Date: Tue, 20 Oct 2026 14:56:03 -0700
Subject: [PATCH] [nspr] initial commit
---
.../Support/SourceMgrDiagnosticVerifier.h | 101 +++++++-------
.../Support/SourceMgrDiagnosticVerifier.cpp | 126 ++++++++++--------
llvm/unittests/Support/CMakeLists.txt | 1 +
.../SourceMgrDiagnosticVerifierTest.cpp | 123 +++++++++++++++++
.../secondary/llvm/unittests/Support/BUILD.gn | 1 +
mlir/lib/IR/Diagnostics.cpp | 29 ++--
6 files changed, 260 insertions(+), 121 deletions(-)
create mode 100644 llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
diff --git a/llvm/include/llvm/Support/SourceMgrDiagnosticVerifier.h b/llvm/include/llvm/Support/SourceMgrDiagnosticVerifier.h
index 0a81f461d618c1..b4a6867ba7f57c 100644
--- a/llvm/include/llvm/Support/SourceMgrDiagnosticVerifier.h
+++ b/llvm/include/llvm/Support/SourceMgrDiagnosticVerifier.h
@@ -43,14 +43,47 @@ class LLVM_ABI SourceMgrDiagnosticVerifier {
/// The diagnostic's text matched an expected diagnostic, but its kind
/// didn't; a message about this has already been printed.
NearMiss,
- /// The diagnostic did not match any expected diagnostic. The caller is
- /// responsible for reporting it, if desired.
+ /// The diagnostic did not match any expected diagnostic.
Unexpected,
/// The diagnostic did not match, but \p reportUnexpected was false, so
/// nothing was printed and nothing needs to be done.
Ignored,
};
+ /// The location of an actual diagnostic.
+ struct Location {
+ /// The buffer containing the diagnostic, or null if it is in a file that
+ /// is not known to the SourceMgr (such a diagnostic never matches).
+ const MemoryBuffer *buf;
+ /// The 1-based line number of the diagnostic.
+ unsigned lineNo;
+ };
+
+ /// Scans all buffers currently registered with \p mgr for expected
+ /// diagnostics. Buffers added later are scanned the first time a
+ /// diagnostic is reported in them. Verifier errors (near misses, unmatched
+ /// expected diagnostics, malformed directives) are printed to \p os,
+ /// bypassing \p mgr's diagnostic handler.
+ SourceMgrDiagnosticVerifier(const SourceMgr &mgr, raw_ostream &os);
+
+ /// Matches a diagnostic against the expected diagnostics for \p loc, or
+ /// against the '@unknown' expected diagnostics if \p loc is std::nullopt.
+ /// Prints a message on a near miss. Reporting an unexpected diagnostic is
+ /// left to the caller. If \p reportUnexpected is false, a diagnostic that
+ /// does not match is ignored instead of failing verification.
+ MatchResult process(SourceMgr::DiagKind kind, std::optional<Location> loc,
+ StringRef message, bool reportUnexpected = true);
+
+ /// Like the overload above, but takes the location from \p diag and also
+ /// prints \p diag if it is unexpected.
+ MatchResult process(const SMDiagnostic &diag, bool reportUnexpected = true);
+
+ /// Reports any expected diagnostic that was never matched by a call to
+ /// \c process. Returns whether verification succeeded overall, i.e. no
+ /// diagnostic mismatches were recorded either here or by \c process.
+ bool verify();
+
+private:
/// A single diagnostic expected via an 'expected-<kind>' comment.
struct ExpectedDiag {
ExpectedDiag(SourceMgr::DiagKind kind, unsigned lineNo, SMLoc fileLoc,
@@ -60,16 +93,6 @@ class LLVM_ABI SourceMgrDiagnosticVerifier {
/// Returns true if this diagnostic matches the given message.
LLVM_ABI bool match(StringRef str) const;
- /// Computes the regex matcher for a '-re' diagnostic's substring.
- /// Returns false and prints a message through \p mgr on error.
- LLVM_ABI bool computeRegex(raw_ostream &os, SourceMgr &mgr);
-
- /// Prints \p msg at this diagnostic's location and returns false, for
- /// use as `return emitError(...);` in functions that report failure via
- /// a bool return.
- LLVM_ABI bool emitError(raw_ostream &os, SourceMgr &mgr,
- const Twine &msg) const;
-
/// The severity of the diagnostic expected.
SourceMgr::DiagKind kind;
/// The line number the expected diagnostic should be on.
@@ -85,45 +108,25 @@ class LLVM_ABI SourceMgrDiagnosticVerifier {
std::optional<Regex> substringRegex;
};
- SourceMgrDiagnosticVerifier() = default;
-
- /// Computes and caches the list of expected diagnostics for \p buf, if not
- /// already cached. Returns the (mutable) cached list.
- MutableArrayRef<ExpectedDiag> computeExpectedDiags(raw_ostream &os,
- SourceMgr &mgr,
- const MemoryBuffer *buf);
-
- /// Returns the cached expected diagnostics for the buffer named \p bufName,
- /// or std::nullopt if \p computeExpectedDiags hasn't been called for it.
- std::optional<MutableArrayRef<ExpectedDiag>>
- getExpectedDiags(StringRef bufName);
-
- /// Returns the expected diagnostics with an '@unknown' location.
- MutableArrayRef<ExpectedDiag> getExpectedUnknownLocDiags() {
- return expectedUnknownLocDiags;
- }
-
- /// Matches a single actual diagnostic against the expected diagnostics
- /// recorded for \p buf / \p lineNo, computing them first via \p
- /// computeExpectedDiags if they haven't been already. If \p hasLoc is
- /// false, the diagnostic has no location and is matched against the
- /// '@unknown' list instead (\p buf / \p lineNo are ignored). If \p hasLoc
- /// is true but \p buf is null (e.g. the diagnostic's file isn't a known
- /// buffer), the diagnostic is matched against an empty list, i.e. it can
- /// never match and is always unexpected. On a near miss, prints a message
- /// through \p mgr. \p reportUnexpected controls whether near misses /
- /// unexpected diagnostics are reported at all.
- MatchResult process(raw_ostream &os, SourceMgr &mgr, SourceMgr::DiagKind kind,
- bool hasLoc, const MemoryBuffer *buf, unsigned lineNo,
- StringRef message, bool reportUnexpected = true);
+ /// Prints \p diag to \c os, bypassing the SourceMgr's diagnostic handler so
+ /// that a verifier installed as that handler does not re-enter itself.
+ void printDiag(const SMDiagnostic &diag) const;
- /// Reports (through \p mgr) any expected diagnostic that was never matched
- /// by a call to \p process. Returns whether verification succeeded overall,
- /// i.e. no diagnostic mismatches were recorded either here or by \p
- /// process.
- bool verify(raw_ostream &os, SourceMgr &mgr);
+ /// Records a verification failure, prints \p msg at \p diag's location and
+ /// returns false.
+ bool emitError(const ExpectedDiag &diag, const Twine &msg);
+
+ /// Computes the regex matcher for a '-re' diagnostic's substring. Returns
+ /// false and prints a message on error.
+ bool computeRegex(ExpectedDiag &diag);
+
+ /// Scans \p buf for expected diagnostics and returns the list for its
+ /// buffer identifier.
+ MutableArrayRef<ExpectedDiag> computeExpectedDiags(const MemoryBuffer *buf);
+
+ const SourceMgr &mgr;
+ raw_ostream &os;
-private:
/// Regex used to recognize 'expected-<kind>' comments.
Regex expected{"expected-(error|note|remark|warning)(-re)? "
"*(@([+-][0-9]+|above|below|unknown))? *{{(.*)}}$"};
diff --git a/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp b/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
index 1e33637f05bc4a..cae1b3be6b0e1e 100644
--- a/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
+++ b/llvm/lib/Support/SourceMgrDiagnosticVerifier.cpp
@@ -12,6 +12,13 @@
using namespace llvm;
+SourceMgrDiagnosticVerifier::SourceMgrDiagnosticVerifier(const SourceMgr &mgr,
+ raw_ostream &os)
+ : mgr(mgr), os(os) {
+ for (unsigned i = 0, e = mgr.getNumBuffers(); i != e; ++i)
+ (void)computeExpectedDiags(mgr.getMemoryBuffer(i + 1));
+}
+
/// Given a diagnostic kind, return a human readable string for it.
static StringRef getDiagKindStr(SourceMgr::DiagKind kind) {
switch (kind) {
@@ -27,15 +34,23 @@ static StringRef getDiagKindStr(SourceMgr::DiagKind kind) {
llvm_unreachable("Unknown SourceMgr::DiagKind");
}
-bool SourceMgrDiagnosticVerifier::ExpectedDiag::emitError(
- raw_ostream &os, SourceMgr &mgr, const Twine &msg) const {
- if (fileLoc.isValid()) {
- SMRange range(fileLoc, SMLoc::getFromPointer(fileLoc.getPointer() +
- substring.size()));
- mgr.PrintMessage(os, fileLoc, SourceMgr::DK_Error, msg, range);
- } else {
- mgr.PrintMessage(os, fileLoc, SourceMgr::DK_Error, msg);
+void SourceMgrDiagnosticVerifier::printDiag(const SMDiagnostic &diag) const {
+ mgr.printIncludeStackForDiagnostic(diag.getLoc(), os);
+ diag.print(nullptr, os);
+}
+
+bool SourceMgrDiagnosticVerifier::emitError(const ExpectedDiag &diag,
+ const Twine &msg) {
+ ok = false;
+ SMRange range;
+ ArrayRef<SMRange> ranges;
+ if (diag.fileLoc.isValid()) {
+ range =
+ SMRange(diag.fileLoc, SMLoc::getFromPointer(diag.fileLoc.getPointer() +
+ diag.substring.size()));
+ ranges = range;
}
+ printDiag(mgr.GetMessage(diag.fileLoc, SourceMgr::DK_Error, msg, ranges));
return false;
}
@@ -47,43 +62,40 @@ bool SourceMgrDiagnosticVerifier::ExpectedDiag::match(StringRef str) const {
return str.contains(substring);
}
-bool SourceMgrDiagnosticVerifier::ExpectedDiag::computeRegex(raw_ostream &os,
- SourceMgr &mgr) {
+bool SourceMgrDiagnosticVerifier::computeRegex(ExpectedDiag &diag) {
std::string regexStr;
- raw_string_ostream regexOS(regexStr);
- StringRef strToProcess = substring;
+ raw_string_ostream regexOs(regexStr);
+ StringRef strToProcess = diag.substring;
while (!strToProcess.empty()) {
// Find the next regex block.
size_t regexIt = strToProcess.find("{{");
if (regexIt == StringRef::npos) {
- regexOS << Regex::escape(strToProcess);
+ regexOs << Regex::escape(strToProcess);
break;
}
- regexOS << Regex::escape(strToProcess.take_front(regexIt));
+ regexOs << Regex::escape(strToProcess.take_front(regexIt));
strToProcess = strToProcess.drop_front(regexIt + 2);
// Find the end of the regex block.
size_t regexEndIt = strToProcess.find("}}");
if (regexEndIt == StringRef::npos)
- return emitError(os, mgr, "found start of regex with no end '}}'");
+ return emitError(diag, "found start of regex with no end '}}'");
StringRef regexBlock = strToProcess.take_front(regexEndIt);
// Validate that the regex is actually valid.
std::string regexError;
if (!Regex(regexBlock).isValid(regexError))
- return emitError(os, mgr, "invalid regex: " + regexError);
+ return emitError(diag, "invalid regex: " + regexError);
- regexOS << '(' << regexBlock << ')';
+ regexOs << '(' << regexBlock << ')';
strToProcess = strToProcess.drop_front(regexEndIt + 2);
}
- substringRegex = Regex(regexStr);
+ diag.substringRegex = Regex(regexStr);
return true;
}
MutableArrayRef<SourceMgrDiagnosticVerifier::ExpectedDiag>
-SourceMgrDiagnosticVerifier::computeExpectedDiags(raw_ostream &os,
- SourceMgr &mgr,
- const MemoryBuffer *buf) {
+SourceMgrDiagnosticVerifier::computeExpectedDiags(const MemoryBuffer *buf) {
// If the buffer is invalid, return an empty list.
if (!buf)
return {};
@@ -128,10 +140,8 @@ SourceMgrDiagnosticVerifier::computeExpectedDiags(raw_ostream &os,
ExpectedDiag record(kind, lineNo + 1, expectedStart, matches[5]);
// Check to see if this is a regex match, i.e. it includes the `-re`.
- if (!matches[2].empty() && !record.computeRegex(os, mgr)) {
- ok = false;
+ if (!matches[2].empty() && !computeRegex(record))
continue;
- }
StringRef offsetMatch = matches[3];
if (!offsetMatch.empty()) {
@@ -171,28 +181,20 @@ SourceMgrDiagnosticVerifier::computeExpectedDiags(raw_ostream &os,
return expectedDiags;
}
-std::optional<MutableArrayRef<SourceMgrDiagnosticVerifier::ExpectedDiag>>
-SourceMgrDiagnosticVerifier::getExpectedDiags(StringRef bufName) {
- auto expectedDiags = expectedDiagsPerFile.find(bufName);
- if (expectedDiags != expectedDiagsPerFile.end())
- return MutableArrayRef<ExpectedDiag>(expectedDiags->second);
- return std::nullopt;
-}
-
SourceMgrDiagnosticVerifier::MatchResult
-SourceMgrDiagnosticVerifier::process(raw_ostream &os, SourceMgr &mgr,
- SourceMgr::DiagKind kind, bool hasLoc,
- const MemoryBuffer *buf, unsigned lineNo,
+SourceMgrDiagnosticVerifier::process(SourceMgr::DiagKind kind,
+ std::optional<Location> loc,
StringRef message, bool reportUnexpected) {
MutableArrayRef<ExpectedDiag> diags;
- if (hasLoc) {
+ if (loc) {
// If the buffer couldn't be resolved, `diags` stays empty: a diagnostic
// with a location in an unknown file can never match anything.
- if (buf) {
- if (auto maybeDiags = getExpectedDiags(buf->getBufferIdentifier()))
- diags = *maybeDiags;
+ if (loc->buf) {
+ auto it = expectedDiagsPerFile.find(loc->buf->getBufferIdentifier());
+ if (it != expectedDiagsPerFile.end())
+ diags = it->second;
else
- diags = computeExpectedDiags(os, mgr, buf);
+ diags = computeExpectedDiags(loc->buf);
}
} else {
diags = expectedUnknownLocDiags;
@@ -205,7 +207,7 @@ SourceMgrDiagnosticVerifier::process(raw_ostream &os, SourceMgr &mgr,
// If this was an expected error, remember that we saw it and return.
for (auto &e : diags) {
// File line must match (unless it's an unknown location).
- if (hasLoc && e.lineNo != lineNo)
+ if (loc && e.lineNo != loc->lineNo)
continue;
if (e.match(message)) {
if (e.kind == kind) {
@@ -226,29 +228,43 @@ SourceMgrDiagnosticVerifier::process(raw_ostream &os, SourceMgr &mgr,
// Otherwise, emit an error for the near miss.
if (nearMiss) {
- mgr.PrintMessage(os, nearMiss->fileLoc, SourceMgr::DK_Error,
- "'" + getDiagKindStr(kind) +
- "' diagnostic emitted when expecting a '" +
- getDiagKindStr(nearMiss->kind) + "'");
+ printDiag(mgr.GetMessage(nearMiss->fileLoc, SourceMgr::DK_Error,
+ "'" + getDiagKindStr(kind) +
+ "' diagnostic emitted when expecting a '" +
+ getDiagKindStr(nearMiss->kind) + "'"));
return MatchResult::NearMiss;
}
return MatchResult::Unexpected;
}
-bool SourceMgrDiagnosticVerifier::verify(raw_ostream &os, SourceMgr &mgr) {
+SourceMgrDiagnosticVerifier::MatchResult
+SourceMgrDiagnosticVerifier::process(const SMDiagnostic &diag,
+ bool reportUnexpected) {
+ std::optional<Location> loc;
+ if (diag.getLoc().isValid()) {
+ const MemoryBuffer *buf = nullptr;
+ if (unsigned id = mgr.FindBufferContainingLoc(diag.getLoc()))
+ buf = mgr.getMemoryBuffer(id);
+ loc = Location{buf, static_cast<unsigned>(diag.getLineNo())};
+ }
+ MatchResult result =
+ process(diag.getKind(), loc, diag.getMessage(), reportUnexpected);
+ if (result == MatchResult::Unexpected)
+ printDiag(diag);
+ return result;
+}
+
+bool SourceMgrDiagnosticVerifier::verify() {
// Verify that all expected errors were seen.
- auto checkExpectedDiags = [&](ExpectedDiag &diag) {
- if (!diag.matched) {
- diag.emitError(os, mgr,
- "expected " + getDiagKindStr(diag.kind) + " \"" +
- diag.substring + "\" was not produced");
- ok = false;
- }
+ auto checkExpectedDiags = [&](const ExpectedDiag &diag) {
+ if (!diag.matched)
+ emitError(diag, "expected " + getDiagKindStr(diag.kind) + " \"" +
+ diag.substring + "\" was not produced");
};
for (auto &expectedDiagsPair : expectedDiagsPerFile)
- for (auto &diag : expectedDiagsPair.second)
+ for (const ExpectedDiag &diag : expectedDiagsPair.second)
checkExpectedDiags(diag);
- for (auto &diag : expectedUnknownLocDiags)
+ for (const ExpectedDiag &diag : expectedUnknownLocDiags)
checkExpectedDiags(diag);
expectedDiagsPerFile.clear();
return ok;
diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt
index f9732ff4e0e4bb..c5db78950d21b4 100644
--- a/llvm/unittests/Support/CMakeLists.txt
+++ b/llvm/unittests/Support/CMakeLists.txt
@@ -90,6 +90,7 @@ add_llvm_unittest(SupportTests
SignalsTest.cpp
SipHashTest.cpp
SourceMgrTest.cpp
+ SourceMgrDiagnosticVerifierTest.cpp
SpecialCaseListTest.cpp
SuffixTreeTest.cpp
SwapByteOrderTest.cpp
diff --git a/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp b/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
new file mode 100644
index 00000000000000..5f731293a5c503
--- /dev/null
+++ b/llvm/unittests/Support/SourceMgrDiagnosticVerifierTest.cpp
@@ -0,0 +1,123 @@
+//===- unittests/Support/SourceMgrDiagnosticVerifierTest.cpp --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/SourceMgrDiagnosticVerifier.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using MatchResult = SourceMgrDiagnosticVerifier::MatchResult;
+
+namespace {
+
+class SourceMgrDiagnosticVerifierTest : public testing::Test {
+protected:
+ SourceMgr SM;
+ std::string Output;
+ raw_string_ostream OS{Output};
+
+ const MemoryBuffer *addBuffer(StringRef Text,
+ StringRef BufferName = "test.s") {
+ unsigned ID = SM.AddNewSourceBuffer(
+ MemoryBuffer::getMemBuffer(Text, BufferName), SMLoc());
+ return SM.getMemoryBuffer(ID);
+ }
+
+ SMDiagnostic getMessage(const MemoryBuffer *Buf, SourceMgr::DiagKind Kind,
+ StringRef Msg) {
+ return SM.GetMessage(SMLoc::getFromPointer(Buf->getBufferStart()), Kind,
+ Msg);
+ }
+};
+
+} // namespace
+
+TEST_F(SourceMgrDiagnosticVerifierTest, Match) {
+ const MemoryBuffer *Buf =
+ addBuffer("bad_op\n# expected-error at -1 {{invalid operand}}\n");
+ SourceMgrDiagnosticVerifier Verifier(SM, OS);
+
+ EXPECT_EQ(
+ Verifier.process(getMessage(Buf, SourceMgr::DK_Error, "invalid operand")),
+ MatchResult::Matched);
+ EXPECT_TRUE(Verifier.verify());
+ EXPECT_EQ(Output, "");
+}
+
+TEST_F(SourceMgrDiagnosticVerifierTest, UnknownLocation) {
+ addBuffer("# expected-warning at unknown {{no location warning}}\n");
+ SourceMgrDiagnosticVerifier Verifier(SM, OS);
+
+ SMDiagnostic Diag =
+ SM.GetMessage(SMLoc(), SourceMgr::DK_Warning, "no location warning");
+ EXPECT_EQ(Verifier.process(Diag), MatchResult::Matched);
+ EXPECT_TRUE(Verifier.verify());
+ EXPECT_EQ(Output, "");
+}
+
+TEST_F(SourceMgrDiagnosticVerifierTest, UnmatchedUnknownLocation) {
+ addBuffer("# expected-error at unknown {{missing unknown error}}\n");
+ SourceMgrDiagnosticVerifier Verifier(SM, OS);
+
+ EXPECT_FALSE(Verifier.verify());
+ EXPECT_NE(
+ StringRef(Output).find(
+ "error: expected error \"missing unknown error\" was not produced"),
+ StringRef::npos);
+}
+
+TEST_F(SourceMgrDiagnosticVerifierTest, ReportUnexpectedFalse) {
+ const MemoryBuffer *Buf =
+ addBuffer("op\n# expected-error at -1 {{expected msg}}\n");
+ SourceMgrDiagnosticVerifier Verifier(SM, OS);
+
+ // An unexpected diagnostic with ReportUnexpected = false is ignored and does
+ // not fail verification.
+ EXPECT_EQ(
+ Verifier.process(getMessage(Buf, SourceMgr::DK_Warning, "unrelated"),
+ /*reportUnexpected=*/false),
+ MatchResult::Ignored);
+ EXPECT_EQ(
+ Verifier.process(getMessage(Buf, SourceMgr::DK_Error, "expected msg"),
+ /*reportUnexpected=*/false),
+ MatchResult::Matched);
+ EXPECT_TRUE(Verifier.verify());
+ EXPECT_EQ(Output, "");
+}
+
+TEST_F(SourceMgrDiagnosticVerifierTest, UnknownFileNeverMatches) {
+ addBuffer("# expected-error {{anything}}\n");
+ SourceMgrDiagnosticVerifier Verifier(SM, OS);
+
+ SourceMgrDiagnosticVerifier::Location Loc{/*buf=*/nullptr, /*lineNo=*/1};
+ EXPECT_EQ(Verifier.process(SourceMgr::DK_Error, Loc, "anything"),
+ MatchResult::Unexpected);
+ EXPECT_FALSE(Verifier.verify());
+}
+
+TEST_F(SourceMgrDiagnosticVerifierTest, InstalledAsDiagHandler) {
+ addBuffer("op\n# expected-warning at -1 {{bad op}}\n");
+ SourceMgrDiagnosticVerifier Verifier(SM, OS);
+ SM.setDiagHandler(
+ [](const SMDiagnostic &Diag, void *Ctx) {
+ static_cast<SourceMgrDiagnosticVerifier *>(Ctx)->process(Diag);
+ },
+ &Verifier);
+
+ // The near-miss message must be printed to OS rather than re-entering the
+ // verifier through the SourceMgr's diagnostic handler.
+ SM.PrintMessage(
+ SMLoc::getFromPointer(SM.getMemoryBuffer(1)->getBufferStart()),
+ SourceMgr::DK_Error, "bad op");
+ EXPECT_NE(StringRef(Output).find(
+ "error: 'error' diagnostic emitted when expecting a 'warning'"),
+ StringRef::npos);
+ EXPECT_FALSE(Verifier.verify());
+}
diff --git a/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn
index 168b609279cab6..7569f7e6fcbb91 100644
--- a/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn
@@ -93,6 +93,7 @@ unittest("SupportTests") {
"SignalsTest.cpp",
"SipHashTest.cpp",
"SourceMgrTest.cpp",
+ "SourceMgrDiagnosticVerifierTest.cpp",
"SpecialCaseListTest.cpp",
"SuffixTreeTest.cpp",
"SwapByteOrderTest.cpp",
diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp
index 1e0a6aca7f19d5..6b048322cbbc52 100644
--- a/mlir/lib/IR/Diagnostics.cpp
+++ b/mlir/lib/IR/Diagnostics.cpp
@@ -641,8 +641,9 @@ namespace mlir {
namespace detail {
struct SourceMgrDiagnosticVerifierHandlerImpl {
SourceMgrDiagnosticVerifierHandlerImpl(
+ llvm::SourceMgr &srcMgr, raw_ostream &out,
SourceMgrDiagnosticVerifierHandler::Level level)
- : level(level) {}
+ : verifier(srcMgr, out), level(level) {}
/// The generic SourceMgr-based verifier core that this handler delegates
/// scanning and matching of 'expected-*' diagnostics to.
@@ -672,13 +673,7 @@ static StringRef getDiagKindStr(DiagnosticSeverity kind) {
SourceMgrDiagnosticVerifierHandler::SourceMgrDiagnosticVerifierHandler(
llvm::SourceMgr &srcMgr, MLIRContext *ctx, raw_ostream &out, Level level)
: SourceMgrDiagnosticHandler(srcMgr, ctx, out),
- impl(new SourceMgrDiagnosticVerifierHandlerImpl(level)) {
- // Compute the expected diagnostics for each of the current files in the
- // source manager.
- for (unsigned i = 0, e = mgr.getNumBuffers(); i != e; ++i)
- (void)impl->verifier.computeExpectedDiags(out, mgr,
- mgr.getMemoryBuffer(i + 1));
-
+ impl(new SourceMgrDiagnosticVerifierHandlerImpl(srcMgr, out, level)) {
// The base class registered a handler that prints every diagnostic. The
// verifier takes its place: it consumes diagnostics and reports unexpected
// ones itself.
@@ -698,7 +693,7 @@ SourceMgrDiagnosticVerifierHandler::~SourceMgrDiagnosticVerifierHandler() {
/// diagnostics were emitted. This return success if all diagnostics were
/// verified correctly, failure otherwise.
LogicalResult SourceMgrDiagnosticVerifierHandler::verify() {
- return success(impl->verifier.verify(os, mgr));
+ return success(impl->verifier.verify());
}
std::unique_ptr<ScopedDiagnosticHandler>
@@ -719,16 +714,16 @@ void SourceMgrDiagnosticVerifierHandler::process(Diagnostic &diag) {
void SourceMgrDiagnosticVerifierHandler::process(LocationAttr loc,
StringRef msg,
DiagnosticSeverity kind) {
- FileLineColLoc fileLoc = loc.findInstanceOf<FileLineColLoc>();
- const llvm::MemoryBuffer *buf =
- fileLoc ? getBufferForFile(fileLoc.getFilename()) : nullptr;
+ using Verifier = llvm::SourceMgrDiagnosticVerifier;
+ std::optional<Verifier::Location> verifierLoc;
+ if (FileLineColLoc fileLoc = loc.findInstanceOf<FileLineColLoc>())
+ verifierLoc = Verifier::Location{getBufferForFile(fileLoc.getFilename()),
+ fileLoc.getLine()};
bool reportUnexpected = impl->level != Level::OnlyExpected;
- using MatchResult = llvm::SourceMgrDiagnosticVerifier::MatchResult;
- MatchResult result = impl->verifier.process(
- os, mgr, getDiagKind(kind), /*hasLoc=*/static_cast<bool>(fileLoc), buf,
- fileLoc ? fileLoc.getLine() : 0, msg, reportUnexpected);
- if (result == MatchResult::Unexpected)
+ Verifier::MatchResult result = impl->verifier.process(
+ getDiagKind(kind), verifierLoc, msg, reportUnexpected);
+ if (result == Verifier::MatchResult::Unexpected)
emitDiagnostic(loc, "unexpected " + getDiagKindStr(kind) + ": " + msg,
DiagnosticSeverity::Error);
}
More information about the Mlir-commits
mailing list