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 26 TextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream& pOStream, 27 const LinkerConfig& pConfig) 28 : m_OStream(pOStream), m_Config(pConfig), m_pInput(NULL) { 29 } 30 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 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 (at) 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 156 void TextDiagnosticPrinter::beginInput(const Input& pInput, const LinkerConfig& pConfig) 157 { 158 m_pInput = &pInput; 159 } 160 161 void TextDiagnosticPrinter::endInput() 162 { 163 m_pInput = NULL; 164 } 165