1affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===- TextDiagnosticPrinter.cpp ------------------------------------------===//
2affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
3affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//                     The MCLinker Project
4affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
5affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This file is distributed under the University of Illinois Open Source
6affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// License. See LICENSE.TXT for details.
7affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
8affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/TextDiagnosticPrinter.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines
13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/Signals.h>
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines
15affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <string>
16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const enum llvm::raw_ostream::Colors UnreachableColor =
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    llvm::raw_ostream::RED;
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const enum llvm::raw_ostream::Colors FatalColor =
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    llvm::raw_ostream::YELLOW;
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const enum llvm::raw_ostream::Colors ErrorColor = llvm::raw_ostream::RED;
2437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const enum llvm::raw_ostream::Colors WarningColor =
2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    llvm::raw_ostream::MAGENTA;
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const enum llvm::raw_ostream::Colors DebugColor =
2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    llvm::raw_ostream::CYAN;
2837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const enum llvm::raw_ostream::Colors NoteColor =
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    llvm::raw_ostream::GREEN;
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic const enum llvm::raw_ostream::Colors IgnoreColor =
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    llvm::raw_ostream::BLUE;
32affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
33affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
34affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// TextDiagnosticPrinter
35affc150dc44fab1911775a49636d0ce85333b634Zonr ChangTextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream& pOStream,
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                             const LinkerConfig& pConfig)
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_OStream(pOStream), m_Config(pConfig), m_pInput(NULL) {
38affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4037b74a387bb3993387029859c2d9d051c41c724eStephen HinesTextDiagnosticPrinter::~TextDiagnosticPrinter() {
41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
42affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
43affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
44affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// capturing it to a log as needed.
4537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid TextDiagnosticPrinter::handleDiagnostic(
4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    DiagnosticEngine::Severity pSeverity,
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const Diagnostic& pInfo) {
48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  DiagnosticPrinter::handleDiagnostic(pSeverity, pInfo);
49affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  std::string out_string;
51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  pInfo.format(out_string);
52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  switch (pSeverity) {
54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Unreachable: {
55affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.changeColor(UnreachableColor, true);
56affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << "Unreachable: ";
57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.resetColor();
58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << out_string << "\n";
59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
60affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Fatal: {
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.changeColor(FatalColor, true);
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << "Fatal: ";
64affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.resetColor();
65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << out_string << "\n";
66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Error: {
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.changeColor(ErrorColor, true);
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << "Error: ";
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.resetColor();
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << out_string << "\n";
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Warning: {
76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.changeColor(WarningColor, true);
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << "Warning: ";
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.resetColor();
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << out_string << "\n";
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Debug: {
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // show debug message only if verbose >= 0
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (m_Config.options().verbose() >= 0) {
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.changeColor(DebugColor, true);
86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream << "Debug: ";
87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.resetColor();
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream << out_string << "\n";
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Note: {
93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // show ignored message only if verbose >= 1
9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (m_Config.options().verbose() >= 1) {
95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.changeColor(NoteColor, true);
96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream << "Note: ";
97affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.resetColor();
98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream << out_string << "\n";
99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Ignore: {
103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // show ignored message only if verbose >= 2
10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (m_Config.options().verbose() >= 2) {
105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.changeColor(IgnoreColor, true);
106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream << "Ignore: ";
107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.resetColor();
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream << out_string << "\n";
109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  switch (pSeverity) {
117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Unreachable: {
118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << "\n\n";
119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.changeColor(llvm::raw_ostream::YELLOW);
120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream << "You encounter a bug of MCLinker, please report to:\n"
121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                << "  mclinker@googlegroups.com\n";
122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      m_OStream.resetColor();
123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    /** fall through **/
125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Fatal: {
12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      // If we reached here, we are failing ungracefully. Run the interrupt
12737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      // handlers
12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      // to make sure any special cleanups get done, in particular that we
12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      // remove
130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // files registered with RemoveFileOnSignal.
131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      llvm::sys::RunInterruptHandlers();
132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      exit(1);
133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
135affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Error: {
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      int16_t error_limit = m_Config.options().maxErrorNum();
137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if ((error_limit != -1) &&
138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          (getNumErrors() > static_cast<unsigned>(error_limit))) {
139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream << "\n\n";
140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.changeColor(llvm::raw_ostream::YELLOW);
141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream << "too many error messages (>" << error_limit << ")...\n";
142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.resetColor();
143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        llvm::sys::RunInterruptHandlers();
144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        exit(1);
145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    case DiagnosticEngine::Warning: {
14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      int16_t warning_limit = m_Config.options().maxWarnNum();
150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if ((warning_limit != -1) &&
151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          (getNumWarnings() > static_cast<unsigned>(warning_limit))) {
152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream << "\n\n";
153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.changeColor(llvm::raw_ostream::YELLOW);
15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        m_OStream << "too many warning messages (>" << warning_limit
15537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                  << ")...\n";
156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        m_OStream.resetColor();
157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        llvm::sys::RunInterruptHandlers();
158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        exit(1);
159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    default:
162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      break;
163affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
16637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid TextDiagnosticPrinter::beginInput(const Input& pInput,
16737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                       const LinkerConfig& pConfig) {
168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_pInput = &pInput;
169affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
170affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
17137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid TextDiagnosticPrinter::endInput() {
172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_pInput = NULL;
173affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines
17537b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
176