1 //===- TextDiagnosticPrinter.cpp ------------------------------------------===//
2 //
3 // The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include "mcld/LD/TextDiagnosticPrinter.h"
10
11 #include "mcld/LinkerConfig.h"
12
13 #include <llvm/Support/Signals.h>
14
15 #include <string>
16
17 namespace mcld {
18
19 static const enum llvm::raw_ostream::Colors UnreachableColor =
20 llvm::raw_ostream::RED;
21 static const enum llvm::raw_ostream::Colors FatalColor =
22 llvm::raw_ostream::YELLOW;
23 static const enum llvm::raw_ostream::Colors ErrorColor = llvm::raw_ostream::RED;
24 static const enum llvm::raw_ostream::Colors WarningColor =
25 llvm::raw_ostream::MAGENTA;
26 static const enum llvm::raw_ostream::Colors DebugColor =
27 llvm::raw_ostream::CYAN;
28 static const enum llvm::raw_ostream::Colors NoteColor =
29 llvm::raw_ostream::GREEN;
30 static const enum llvm::raw_ostream::Colors IgnoreColor =
31 llvm::raw_ostream::BLUE;
32
33 //===----------------------------------------------------------------------===//
34 // TextDiagnosticPrinter
TextDiagnosticPrinter(llvm::raw_ostream & pOStream,const LinkerConfig & pConfig)35 TextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream& pOStream,
36 const LinkerConfig& pConfig)
37 : m_OStream(pOStream), m_Config(pConfig), m_pInput(NULL) {
38 }
39
~TextDiagnosticPrinter()40 TextDiagnosticPrinter::~TextDiagnosticPrinter() {
41 }
42
43 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
44 /// capturing it to a log as needed.
handleDiagnostic(DiagnosticEngine::Severity pSeverity,const Diagnostic & pInfo)45 void TextDiagnosticPrinter::handleDiagnostic(
46 DiagnosticEngine::Severity pSeverity,
47 const Diagnostic& pInfo) {
48 DiagnosticPrinter::handleDiagnostic(pSeverity, pInfo);
49
50 std::string out_string;
51 pInfo.format(out_string);
52
53 switch (pSeverity) {
54 case DiagnosticEngine::Unreachable: {
55 m_OStream.changeColor(UnreachableColor, true);
56 m_OStream << "Unreachable: ";
57 m_OStream.resetColor();
58 m_OStream << out_string << "\n";
59 break;
60 }
61 case DiagnosticEngine::Fatal: {
62 m_OStream.changeColor(FatalColor, true);
63 m_OStream << "Fatal: ";
64 m_OStream.resetColor();
65 m_OStream << out_string << "\n";
66 break;
67 }
68 case DiagnosticEngine::Error: {
69 m_OStream.changeColor(ErrorColor, true);
70 m_OStream << "Error: ";
71 m_OStream.resetColor();
72 m_OStream << out_string << "\n";
73 break;
74 }
75 case DiagnosticEngine::Warning: {
76 m_OStream.changeColor(WarningColor, true);
77 m_OStream << "Warning: ";
78 m_OStream.resetColor();
79 m_OStream << out_string << "\n";
80 break;
81 }
82 case DiagnosticEngine::Debug: {
83 // show debug message only if verbose >= 0
84 if (m_Config.options().verbose() >= 0) {
85 m_OStream.changeColor(DebugColor, true);
86 m_OStream << "Debug: ";
87 m_OStream.resetColor();
88 m_OStream << out_string << "\n";
89 }
90 break;
91 }
92 case DiagnosticEngine::Note: {
93 // show ignored message only if verbose >= 1
94 if (m_Config.options().verbose() >= 1) {
95 m_OStream.changeColor(NoteColor, true);
96 m_OStream << "Note: ";
97 m_OStream.resetColor();
98 m_OStream << out_string << "\n";
99 }
100 break;
101 }
102 case DiagnosticEngine::Ignore: {
103 // show ignored message only if verbose >= 2
104 if (m_Config.options().verbose() >= 2) {
105 m_OStream.changeColor(IgnoreColor, true);
106 m_OStream << "Ignore: ";
107 m_OStream.resetColor();
108 m_OStream << out_string << "\n";
109 }
110 break;
111 }
112 default:
113 break;
114 }
115
116 switch (pSeverity) {
117 case DiagnosticEngine::Unreachable: {
118 m_OStream << "\n\n";
119 m_OStream.changeColor(llvm::raw_ostream::YELLOW);
120 m_OStream << "You encounter a bug of MCLinker, please report to:\n"
121 << " mclinker@googlegroups.com\n";
122 m_OStream.resetColor();
123 }
124 /** fall through **/
125 case DiagnosticEngine::Fatal: {
126 // If we reached here, we are failing ungracefully. Run the interrupt
127 // handlers
128 // to make sure any special cleanups get done, in particular that we
129 // remove
130 // files registered with RemoveFileOnSignal.
131 llvm::sys::RunInterruptHandlers();
132 exit(1);
133 break;
134 }
135 case DiagnosticEngine::Error: {
136 int16_t error_limit = m_Config.options().maxErrorNum();
137 if ((error_limit != -1) &&
138 (getNumErrors() > static_cast<unsigned>(error_limit))) {
139 m_OStream << "\n\n";
140 m_OStream.changeColor(llvm::raw_ostream::YELLOW);
141 m_OStream << "too many error messages (>" << error_limit << ")...\n";
142 m_OStream.resetColor();
143 llvm::sys::RunInterruptHandlers();
144 exit(1);
145 }
146 break;
147 }
148 case DiagnosticEngine::Warning: {
149 int16_t warning_limit = m_Config.options().maxWarnNum();
150 if ((warning_limit != -1) &&
151 (getNumWarnings() > static_cast<unsigned>(warning_limit))) {
152 m_OStream << "\n\n";
153 m_OStream.changeColor(llvm::raw_ostream::YELLOW);
154 m_OStream << "too many warning messages (>" << warning_limit
155 << ")...\n";
156 m_OStream.resetColor();
157 llvm::sys::RunInterruptHandlers();
158 exit(1);
159 }
160 }
161 default:
162 break;
163 }
164 }
165
beginInput(const Input & pInput,const LinkerConfig & pConfig)166 void TextDiagnosticPrinter::beginInput(const Input& pInput,
167 const LinkerConfig& pConfig) {
168 m_pInput = &pInput;
169 }
170
endInput()171 void TextDiagnosticPrinter::endInput() {
172 m_pInput = NULL;
173 }
174
175 } // namespace mcld
176