10b57cec5SDimitry Andric //===- TextDiagnosticBuffer.cpp - Buffer Text Diagnostics -----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This is a concrete diagnostic client, which buffers the diagnostic messages.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "clang/Frontend/TextDiagnosticBuffer.h"
140b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h"
150b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
160b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
170b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric using namespace clang;
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric /// HandleDiagnostic - Store the errors, warnings, and notes that are
220b57cec5SDimitry Andric /// reported.
HandleDiagnostic(DiagnosticsEngine::Level Level,const Diagnostic & Info)230b57cec5SDimitry Andric void TextDiagnosticBuffer::HandleDiagnostic(DiagnosticsEngine::Level Level,
240b57cec5SDimitry Andric const Diagnostic &Info) {
250b57cec5SDimitry Andric // Default implementation (Warnings/errors count).
260b57cec5SDimitry Andric DiagnosticConsumer::HandleDiagnostic(Level, Info);
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric SmallString<100> Buf;
290b57cec5SDimitry Andric Info.FormatDiagnostic(Buf);
300b57cec5SDimitry Andric switch (Level) {
310b57cec5SDimitry Andric default: llvm_unreachable(
320b57cec5SDimitry Andric "Diagnostic not handled during diagnostic buffering!");
330b57cec5SDimitry Andric case DiagnosticsEngine::Note:
340b57cec5SDimitry Andric All.emplace_back(Level, Notes.size());
357a6dacacSDimitry Andric Notes.emplace_back(Info.getLocation(), std::string(Buf));
360b57cec5SDimitry Andric break;
370b57cec5SDimitry Andric case DiagnosticsEngine::Warning:
380b57cec5SDimitry Andric All.emplace_back(Level, Warnings.size());
397a6dacacSDimitry Andric Warnings.emplace_back(Info.getLocation(), std::string(Buf));
400b57cec5SDimitry Andric break;
410b57cec5SDimitry Andric case DiagnosticsEngine::Remark:
420b57cec5SDimitry Andric All.emplace_back(Level, Remarks.size());
437a6dacacSDimitry Andric Remarks.emplace_back(Info.getLocation(), std::string(Buf));
440b57cec5SDimitry Andric break;
450b57cec5SDimitry Andric case DiagnosticsEngine::Error:
460b57cec5SDimitry Andric case DiagnosticsEngine::Fatal:
470b57cec5SDimitry Andric All.emplace_back(Level, Errors.size());
487a6dacacSDimitry Andric Errors.emplace_back(Info.getLocation(), std::string(Buf));
490b57cec5SDimitry Andric break;
500b57cec5SDimitry Andric }
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric
FlushDiagnostics(DiagnosticsEngine & Diags) const530b57cec5SDimitry Andric void TextDiagnosticBuffer::FlushDiagnostics(DiagnosticsEngine &Diags) const {
540b57cec5SDimitry Andric for (const auto &I : All) {
550b57cec5SDimitry Andric auto Diag = Diags.Report(Diags.getCustomDiagID(I.first, "%0"));
560b57cec5SDimitry Andric switch (I.first) {
570b57cec5SDimitry Andric default: llvm_unreachable(
580b57cec5SDimitry Andric "Diagnostic not handled during diagnostic flushing!");
590b57cec5SDimitry Andric case DiagnosticsEngine::Note:
600b57cec5SDimitry Andric Diag << Notes[I.second].second;
610b57cec5SDimitry Andric break;
620b57cec5SDimitry Andric case DiagnosticsEngine::Warning:
630b57cec5SDimitry Andric Diag << Warnings[I.second].second;
640b57cec5SDimitry Andric break;
650b57cec5SDimitry Andric case DiagnosticsEngine::Remark:
660b57cec5SDimitry Andric Diag << Remarks[I.second].second;
670b57cec5SDimitry Andric break;
680b57cec5SDimitry Andric case DiagnosticsEngine::Error:
690b57cec5SDimitry Andric case DiagnosticsEngine::Fatal:
700b57cec5SDimitry Andric Diag << Errors[I.second].second;
710b57cec5SDimitry Andric break;
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric }
75