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 29 TextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream& pOStream, 30 const LinkerConfig& pConfig) 31 : m_OStream(pOStream), m_Config(pConfig), m_pInput(NULL) { 32 } 33 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 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 (at) 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 159 void TextDiagnosticPrinter::beginInput(const Input& pInput, const LinkerConfig& pConfig) 160 { 161 m_pInput = &pInput; 162 } 163 164 void TextDiagnosticPrinter::endInput() 165 { 166 m_pInput = NULL; 167 } 168