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 35 TextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream& pOStream, 36 const LinkerConfig& pConfig) 37 : m_OStream(pOStream), m_Config(pConfig), m_pInput(NULL) { 38 } 39 40 TextDiagnosticPrinter::~TextDiagnosticPrinter() { 41 } 42 43 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or 44 /// capturing it to a log as needed. 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 (at) 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 166 void TextDiagnosticPrinter::beginInput(const Input& pInput, 167 const LinkerConfig& pConfig) { 168 m_pInput = &pInput; 169 } 170 171 void TextDiagnosticPrinter::endInput() { 172 m_pInput = NULL; 173 } 174 175 } // namespace mcld 176