1 //===--- TextDiagnosticPrinter.cpp - Diagnostic Printer -------------------===//
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 diagnostic client prints out their diagnostic messages.
10 //
11 //===----------------------------------------------------------------------===//
12 //
13 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "flang/Frontend/TextDiagnosticPrinter.h"
18 #include "flang/Frontend/TextDiagnostic.h"
19 #include "clang/Basic/DiagnosticOptions.h"
20 #include "llvm/ADT/SmallString.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/raw_ostream.h"
23 
24 using namespace Fortran::frontend;
25 
TextDiagnosticPrinter(raw_ostream & diagOs,clang::DiagnosticOptions * diags)26 TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &diagOs,
27                                              clang::DiagnosticOptions *diags)
28     : os(diagOs), diagOpts(diags) {}
29 
~TextDiagnosticPrinter()30 TextDiagnosticPrinter::~TextDiagnosticPrinter() {}
31 
HandleDiagnostic(clang::DiagnosticsEngine::Level level,const clang::Diagnostic & info)32 void TextDiagnosticPrinter::HandleDiagnostic(
33     clang::DiagnosticsEngine::Level level, const clang::Diagnostic &info) {
34   // Default implementation (Warnings/errors count).
35   DiagnosticConsumer::HandleDiagnostic(level, info);
36 
37   // Render the diagnostic message into a temporary buffer eagerly. We'll use
38   // this later as we print out the diagnostic to the terminal.
39   llvm::SmallString<100> outStr;
40   info.FormatDiagnostic(outStr);
41 
42   llvm::raw_svector_ostream diagMessageStream(outStr);
43 
44   if (!prefix.empty())
45     os << prefix << ": ";
46 
47   // We only emit diagnostics in contexts that lack valid source locations.
48   assert(!info.getLocation().isValid() &&
49       "Diagnostics with valid source location are not supported");
50 
51   Fortran::frontend::TextDiagnostic::printDiagnosticLevel(os, level,
52                                                           diagOpts->ShowColors);
53   Fortran::frontend::TextDiagnostic::printDiagnosticMessage(
54       os,
55       /*IsSupplemental=*/level == clang::DiagnosticsEngine::Note,
56       diagMessageStream.str(), diagOpts->ShowColors);
57 
58   os.flush();
59 }
60