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 | // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ |
14 | // |
15 | //===----------------------------------------------------------------------===// |
16 | |
17 | #include "flang/Frontend/TextDiagnosticBuffer.h" |
18 | #include "clang/Basic/Diagnostic.h" |
19 | #include "llvm/ADT/SmallString.h" |
20 | #include "llvm/Support/ErrorHandling.h" |
21 | |
22 | using namespace Fortran::frontend; |
23 | |
24 | /// HandleDiagnostic - Store the errors, warnings, and notes that are |
25 | /// reported. |
26 | void TextDiagnosticBuffer::HandleDiagnostic( |
27 | clang::DiagnosticsEngine::Level level, const clang::Diagnostic &info) { |
28 | // Default implementation (warnings_/errors count). |
29 | DiagnosticConsumer::HandleDiagnostic(level, info); |
30 | |
31 | llvm::SmallString<100> buf; |
32 | info.FormatDiagnostic(buf); |
33 | switch (level) { |
34 | default: |
35 | llvm_unreachable("Diagnostic not handled during diagnostic buffering!" ); |
36 | case clang::DiagnosticsEngine::Note: |
37 | all.emplace_back(level, notes.size()); |
38 | notes.emplace_back(info.getLocation(), std::string(buf)); |
39 | break; |
40 | case clang::DiagnosticsEngine::Warning: |
41 | all.emplace_back(level, warnings.size()); |
42 | warnings.emplace_back(info.getLocation(), std::string(buf)); |
43 | break; |
44 | case clang::DiagnosticsEngine::Remark: |
45 | all.emplace_back(level, remarks.size()); |
46 | remarks.emplace_back(info.getLocation(), std::string(buf)); |
47 | break; |
48 | case clang::DiagnosticsEngine::Error: |
49 | case clang::DiagnosticsEngine::Fatal: |
50 | all.emplace_back(level, errors.size()); |
51 | errors.emplace_back(info.getLocation(), std::string(buf)); |
52 | break; |
53 | } |
54 | } |
55 | |
56 | void TextDiagnosticBuffer::flushDiagnostics( |
57 | clang::DiagnosticsEngine &diags) const { |
58 | for (const auto &i : all) { |
59 | auto diag = diags.Report(diags.getCustomDiagID(i.first, "%0" )); |
60 | switch (i.first) { |
61 | default: |
62 | llvm_unreachable("Diagnostic not handled during diagnostic flushing!" ); |
63 | case clang::DiagnosticsEngine::Note: |
64 | diag << notes[i.second].second; |
65 | break; |
66 | case clang::DiagnosticsEngine::Warning: |
67 | diag << warnings[i.second].second; |
68 | break; |
69 | case clang::DiagnosticsEngine::Remark: |
70 | diag << remarks[i.second].second; |
71 | break; |
72 | case clang::DiagnosticsEngine::Error: |
73 | case clang::DiagnosticsEngine::Fatal: |
74 | diag << errors[i.second].second; |
75 | break; |
76 | } |
77 | } |
78 | } |
79 | |