xref: /llvm-project/flang/lib/Frontend/TextDiagnosticBuffer.cpp (revision f0346a5862cc2f177e102d96f9f88da55fe82fd3)
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.
HandleDiagnostic(clang::DiagnosticsEngine::Level level,const clang::Diagnostic & info)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 
flushDiagnostics(clang::DiagnosticsEngine & diags) const56 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