Author: Jackson Stogel Date: 2026-04-03T15:02:14-07:00 New Revision: 3f37512c8fcfd4c26b7eed46a04edec8d763e2b1
URL: https://github.com/llvm/llvm-project/commit/3f37512c8fcfd4c26b7eed46a04edec8d763e2b1 DIFF: https://github.com/llvm/llvm-project/commit/3f37512c8fcfd4c26b7eed46a04edec8d763e2b1.diff LOG: [DiagnosticInfo] Allow std::string_view in DiagnosticBuilder operator<<. (#190374) After a68ae7b0cc0922b79114aabe8cf1ec8dc68524d7, calling `<<` with a `std::string_view` gives: ``` clang/include/clang/Basic/Diagnostic.h:1319:8: error: use of overloaded operator '<<' is ambiguous (with operand types 'const StreamingDiagnostic' and 'const std::string_view') 1319 | DB << V; | ~~ ^ ~ ``` Added: Modified: clang/include/clang/Basic/Diagnostic.h clang/unittests/Basic/DiagnosticTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 5a6f5fd61a5db..aa05f9d60dadf 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -36,6 +36,7 @@ #include <memory> #include <optional> #include <string> +#include <string_view> #include <type_traits> #include <utility> #include <vector> @@ -1374,6 +1375,12 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, return DB; } +inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, + std::string_view S) { + DB.AddString(S); + return DB; +} + inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, const std::string &S) { DB.AddString(S); diff --git a/clang/unittests/Basic/DiagnosticTest.cpp b/clang/unittests/Basic/DiagnosticTest.cpp index 5492146f40fa9..4d310d3ece23f 100644 --- a/clang/unittests/Basic/DiagnosticTest.cpp +++ b/clang/unittests/Basic/DiagnosticTest.cpp @@ -23,6 +23,7 @@ #include "gtest/gtest.h" #include <memory> #include <optional> +#include <string_view> #include <vector> using namespace llvm; @@ -42,8 +43,19 @@ void clang::DiagnosticsTestHelper(DiagnosticsEngine &diag) { namespace { using testing::AllOf; using testing::ElementsAre; +using testing::HasSubstr; using testing::IsEmpty; +MATCHER_P(WithMessage, M, + "has diagnostic message that " + + ::testing::DescribeMatcher<std::string>(M)) { + return testing::ExplainMatchResult(M, arg.getMessage().str(), + result_listener); +} +MATCHER(IsError, "has error severity") { + return arg.getLevel() == DiagnosticsEngine::Level::Error; +} + // Check that DiagnosticErrorTrap works with SuppressAllDiagnostics. TEST(DiagnosticTest, suppressAndTrap) { DiagnosticOptions DiagOpts; @@ -164,20 +176,20 @@ TEST(DiagnosticTest, diagnosticError) { EXPECT_EQ(Value->first, 20); } +class CaptureDiagnosticConsumer : public DiagnosticConsumer { +public: + SmallVector<StoredDiagnostic> StoredDiags; + + void HandleDiagnostic(DiagnosticsEngine::Level level, + const Diagnostic &Info) override { + StoredDiags.push_back(StoredDiagnostic(level, Info)); + } +}; + TEST(DiagnosticTest, storedDiagEmptyWarning) { DiagnosticOptions DiagOpts; DiagnosticsEngine Diags(DiagnosticIDs::create(), DiagOpts); - class CaptureDiagnosticConsumer : public DiagnosticConsumer { - public: - SmallVector<StoredDiagnostic> StoredDiags; - - void HandleDiagnostic(DiagnosticsEngine::Level level, - const Diagnostic &Info) override { - StoredDiags.push_back(StoredDiagnostic(level, Info)); - } - }; - CaptureDiagnosticConsumer CaptureConsumer; Diags.setClient(&CaptureConsumer, /*ShouldOwnClient=*/false); Diags.Report(diag::pp_hash_warning) << ""; @@ -187,6 +199,21 @@ TEST(DiagnosticTest, storedDiagEmptyWarning) { Diags.Report(CaptureConsumer.StoredDiags.front()); } +// std::string_view is used by downstream consumers. +TEST(DiagnosticTest, reportAcceptsStringViewMessage) { + DiagnosticOptions DiagOpts; + DiagnosticsEngine Diags(DiagnosticIDs::create(), DiagOpts); + + CaptureDiagnosticConsumer CaptureConsumer; + Diags.setClient(&CaptureConsumer, /*ShouldOwnClient=*/false); + + std::string_view SV = "diagnostic"; + Diags.Report(diag::err_target_unknown_triple) << SV; + + EXPECT_THAT(CaptureConsumer.StoredDiags, + ElementsAre(WithMessage(HasSubstr("diagnostic")))); +} + class SuppressionMappingTest : public testing::Test { public: SuppressionMappingTest() { @@ -226,13 +253,6 @@ class SuppressionMappingTest : public testing::Test { CaptureDiagnosticConsumer CaptureConsumer; }; -MATCHER_P(WithMessage, Msg, "has diagnostic message") { - return arg.getMessage() == Msg; -} -MATCHER(IsError, "has error severity") { - return arg.getLevel() == DiagnosticsEngine::Level::Error; -} - TEST_F(SuppressionMappingTest, MissingMappingFile) { Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt"; clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
