1 //===- TextDiagnosticBuffer.cpp - Buffer Text Diagnostics -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This is a concrete diagnostic client, which buffers the diagnostic messages.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "flang/Frontend/TextDiagnosticBuffer.h"
14 #include "clang/Basic/Diagnostic.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/Support/ErrorHandling.h"
17
18 using namespace Fortran::frontend;
19
20 /// HandleDiagnostic - Store the errors, warnings, and notes that are
21 /// reported.
HandleDiagnostic(clang::DiagnosticsEngine::Level level,const clang::Diagnostic & info)22 void TextDiagnosticBuffer::HandleDiagnostic(
23 clang::DiagnosticsEngine::Level level, const clang::Diagnostic &info) {
24 // Default implementation (warnings_/errors count).
25 DiagnosticConsumer::HandleDiagnostic(level, info);
26
27 llvm::SmallString<100> buf;
28 info.FormatDiagnostic(buf);
29 switch (level) {
30 default:
31 llvm_unreachable("Diagnostic not handled during diagnostic buffering!");
32 case clang::DiagnosticsEngine::Note:
33 all_.emplace_back(level, notes_.size());
34 notes_.emplace_back(info.getLocation(), std::string(buf.str()));
35 break;
36 case clang::DiagnosticsEngine::Warning:
37 all_.emplace_back(level, warnings_.size());
38 warnings_.emplace_back(info.getLocation(), std::string(buf.str()));
39 break;
40 case clang::DiagnosticsEngine::Remark:
41 all_.emplace_back(level, remarks_.size());
42 remarks_.emplace_back(info.getLocation(), std::string(buf.str()));
43 break;
44 case clang::DiagnosticsEngine::Error:
45 case clang::DiagnosticsEngine::Fatal:
46 all_.emplace_back(level, errors_.size());
47 errors_.emplace_back(info.getLocation(), std::string(buf.str()));
48 break;
49 }
50 }
51
FlushDiagnostics(clang::DiagnosticsEngine & Diags) const52 void TextDiagnosticBuffer::FlushDiagnostics(
53 clang::DiagnosticsEngine &Diags) const {
54 for (const auto &i : all_) {
55 auto Diag = Diags.Report(Diags.getCustomDiagID(i.first, "%0"));
56 switch (i.first) {
57 default:
58 llvm_unreachable("Diagnostic not handled during diagnostic flushing!");
59 case clang::DiagnosticsEngine::Note:
60 Diag << notes_[i.second].second;
61 break;
62 case clang::DiagnosticsEngine::Warning:
63 Diag << warnings_[i.second].second;
64 break;
65 case clang::DiagnosticsEngine::Remark:
66 Diag << remarks_[i.second].second;
67 break;
68 case clang::DiagnosticsEngine::Error:
69 case clang::DiagnosticsEngine::Fatal:
70 Diag << errors_[i.second].second;
71 break;
72 }
73 }
74 }
75