[clang] [clang] Apply internal buffering to clang diagnostics printing (PR #113440)
Mariya Podchishchaeva via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 4 03:19:39 PST 2024
https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/113440
>From 10439ffa9e61240402190538f7a1e1665ca215c8 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Wed, 23 Oct 2024 02:50:50 -0700
Subject: [PATCH] [clang] Apply internal buffering to clang diagnostics
printing
To stabilize output of clang when clang is run in multiple build threads
the whole diagnostic message is written first to internal buffer and then
the whole message is put to the output stream which usually points to
stderr to avoid printing to stderr with small chunks and interleaving of
multiple diagnostic messages.
---
clang/include/clang/Frontend/TextDiagnostic.h | 12 +++++++++++-
clang/lib/Frontend/TextDiagnostic.cpp | 16 +++++++++++++---
clang/lib/Frontend/TextDiagnosticPrinter.cpp | 10 +++++++---
3 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h b/clang/include/clang/Frontend/TextDiagnostic.h
index a2fe8ae995423b..e47a111c1dcdc2 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
#include "clang/Frontend/DiagnosticRenderer.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
namespace clang {
@@ -33,8 +34,15 @@ namespace clang {
/// DiagnosticClient is implemented through this class as is diagnostic
/// printing coming out of libclang.
class TextDiagnostic : public DiagnosticRenderer {
- raw_ostream &OS;
+ raw_ostream &Out;
const Preprocessor *PP;
+ // To stabilize output of clang when clang is run in multiple build threads
+ // the whole diagnostic message is written first to internal buffer and then
+ // the whole message is put to the output stream Out which usually points to
+ // stderr to avoid printing to stderr with small chunks and interleaving of
+ // multiple diagnostic messages.
+ SmallString<1024> InternalBuffer;
+ llvm::raw_svector_ostream OS;
public:
TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
@@ -104,6 +112,8 @@ class TextDiagnostic : public DiagnosticRenderer {
void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
StringRef ModuleName) override;
+ void endDiagnostic(DiagOrStoredDiag D,
+ DiagnosticsEngine::Level Level) override;
private:
void emitFilename(StringRef Filename, const SourceManager &SM);
diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp
index 4119ce6048d45d..fddb846745aa83 100644
--- a/clang/lib/Frontend/TextDiagnostic.cpp
+++ b/clang/lib/Frontend/TextDiagnostic.cpp
@@ -656,7 +656,11 @@ static bool printWordWrapped(raw_ostream &OS, StringRef Str, unsigned Columns,
TextDiagnostic::TextDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
DiagnosticOptions *DiagOpts,
const Preprocessor *PP)
- : DiagnosticRenderer(LangOpts, DiagOpts), OS(OS), PP(PP) {}
+ : DiagnosticRenderer(LangOpts, DiagOpts), Out(OS), PP(PP),
+ OS(InternalBuffer) {
+ this->OS.buffer().clear();
+ this->OS.enable_colors(true);
+}
TextDiagnostic::~TextDiagnostic() {}
@@ -664,7 +668,7 @@ void TextDiagnostic::emitDiagnosticMessage(
FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<clang::CharSourceRange> Ranges,
DiagOrStoredDiag D) {
- uint64_t StartOfLocationInfo = OS.tell();
+ uint64_t StartOfLocationInfo = Out.tell();
// Emit the location of this particular diagnostic.
if (Loc.isValid())
@@ -677,7 +681,7 @@ void TextDiagnostic::emitDiagnosticMessage(
printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
printDiagnosticMessage(OS,
/*IsSupplemental*/ Level == DiagnosticsEngine::Note,
- Message, OS.tell() - StartOfLocationInfo,
+ Message, Out.tell() - StartOfLocationInfo,
DiagOpts->MessageLength, DiagOpts->ShowColors);
}
@@ -1545,3 +1549,9 @@ void TextDiagnostic::emitParseableFixits(ArrayRef<FixItHint> Hints,
OS << "\"\n";
}
}
+
+void TextDiagnostic::endDiagnostic(DiagOrStoredDiag D,
+ DiagnosticsEngine::Level Level) {
+ Out << OS.str();
+ OS.buffer().clear();
+}
diff --git a/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/clang/lib/Frontend/TextDiagnosticPrinter.cpp
index dac5c44fe92566..6e24a19a1ad501 100644
--- a/clang/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/clang/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -133,12 +133,16 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
// diagnostics in a context that lacks language options, a source manager, or
// other infrastructure necessary when emitting more rich diagnostics.
if (!Info.getLocation().isValid()) {
- TextDiagnostic::printDiagnosticLevel(OS, Level, DiagOpts->ShowColors);
+ SmallString<1000> OutText;
+ llvm::raw_svector_ostream OutputBuffer(OutText);
+ OutputBuffer.enable_colors(true);
+ TextDiagnostic::printDiagnosticLevel(OutputBuffer, Level,
+ DiagOpts->ShowColors);
TextDiagnostic::printDiagnosticMessage(
- OS, /*IsSupplemental=*/Level == DiagnosticsEngine::Note,
+ OutputBuffer, /*IsSupplemental=*/Level == DiagnosticsEngine::Note,
DiagMessageStream.str(), OS.tell() - StartOfLocationInfo,
DiagOpts->MessageLength, DiagOpts->ShowColors);
- OS.flush();
+ OS << OutputBuffer.str();
return;
}
More information about the cfe-commits
mailing list