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