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