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