//===- TextDiagnosticPrinter.cpp ------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include <mcld/LD/TextDiagnosticPrinter.h> #include <mcld/LinkerConfig.h> #include <llvm/Support/Signals.h> #include <string> using namespace mcld; static const enum llvm::raw_ostream::Colors UnreachableColor = llvm::raw_ostream::RED; static const enum llvm::raw_ostream::Colors FatalColor = llvm::raw_ostream::YELLOW; static const enum llvm::raw_ostream::Colors ErrorColor = llvm::raw_ostream::RED; static const enum llvm::raw_ostream::Colors WarningColor = llvm::raw_ostream::MAGENTA; static const enum llvm::raw_ostream::Colors DebugColor = llvm::raw_ostream::CYAN; static const enum llvm::raw_ostream::Colors NoteColor = llvm::raw_ostream::GREEN; static const enum llvm::raw_ostream::Colors IgnoreColor = llvm::raw_ostream::BLUE; // Used for changing only the bold attribute. static const enum llvm::raw_ostream::Colors SavedColor = llvm::raw_ostream::SAVEDCOLOR; //===----------------------------------------------------------------------===// // TextDiagnosticPrinter TextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream& pOStream, const LinkerConfig& pConfig) : m_OStream(pOStream), m_Config(pConfig), m_pInput(NULL) { } TextDiagnosticPrinter::~TextDiagnosticPrinter() { } /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or /// capturing it to a log as needed. void TextDiagnosticPrinter::handleDiagnostic(DiagnosticEngine::Severity pSeverity, const Diagnostic& pInfo) { DiagnosticPrinter::handleDiagnostic(pSeverity, pInfo); std::string out_string; pInfo.format(out_string); switch (pSeverity) { case DiagnosticEngine::Unreachable: { m_OStream.changeColor(UnreachableColor, true); m_OStream << "Unreachable: "; m_OStream.resetColor(); m_OStream << out_string << "\n"; break; } case DiagnosticEngine::Fatal: { m_OStream.changeColor(FatalColor, true); m_OStream << "Fatal: "; m_OStream.resetColor(); m_OStream << out_string << "\n"; break; } case DiagnosticEngine::Error: { m_OStream.changeColor(ErrorColor, true); m_OStream << "Error: "; m_OStream.resetColor(); m_OStream << out_string << "\n"; break; } case DiagnosticEngine::Warning: { m_OStream.changeColor(WarningColor, true); m_OStream << "Warning: "; m_OStream.resetColor(); m_OStream << out_string << "\n"; break; } case DiagnosticEngine::Debug: { // show debug message only if verbose >= 0 if (0 <= m_Config.options().verbose()) { m_OStream.changeColor(DebugColor, true); m_OStream << "Debug: "; m_OStream.resetColor(); m_OStream << out_string << "\n"; } break; } case DiagnosticEngine::Note: { // show ignored message only if verbose >= 1 if (1 <= m_Config.options().verbose()) { m_OStream.changeColor(NoteColor, true); m_OStream << "Note: "; m_OStream.resetColor(); m_OStream << out_string << "\n"; } break; } case DiagnosticEngine::Ignore: { // show ignored message only if verbose >= 2 if (2 <= m_Config.options().verbose()) { m_OStream.changeColor(IgnoreColor, true); m_OStream << "Ignore: "; m_OStream.resetColor(); m_OStream << out_string << "\n"; } break; } default: break; } switch (pSeverity) { case DiagnosticEngine::Unreachable: { m_OStream << "\n\n"; m_OStream.changeColor(llvm::raw_ostream::YELLOW); m_OStream << "You encounter a bug of MCLinker, please report to:\n" << " mclinker@googlegroups.com\n"; m_OStream.resetColor(); } /** fall through **/ case DiagnosticEngine::Fatal: { // If we reached here, we are failing ungracefully. Run the interrupt handlers // to make sure any special cleanups get done, in particular that we remove // files registered with RemoveFileOnSignal. llvm::sys::RunInterruptHandlers(); exit(1); break; } case DiagnosticEngine::Error: { int16_t error_limit = m_Config.options().maxErrorNum(); if ((error_limit != -1) && (getNumErrors() > static_cast<unsigned>(error_limit))) { m_OStream << "\n\n"; m_OStream.changeColor(llvm::raw_ostream::YELLOW); m_OStream << "too many error messages (>" << error_limit << ")...\n"; m_OStream.resetColor(); llvm::sys::RunInterruptHandlers(); exit(1); } break; } case DiagnosticEngine::Warning: { int16_t warning_limit = m_Config.options().maxWarnNum(); if ((warning_limit != -1) && (getNumWarnings() > static_cast<unsigned>(warning_limit))) { m_OStream << "\n\n"; m_OStream.changeColor(llvm::raw_ostream::YELLOW); m_OStream << "too many warning messages (>" << warning_limit << ")...\n"; m_OStream.resetColor(); llvm::sys::RunInterruptHandlers(); exit(1); } } default: break; } } void TextDiagnosticPrinter::beginInput(const Input& pInput, const LinkerConfig& pConfig) { m_pInput = &pInput; } void TextDiagnosticPrinter::endInput() { m_pInput = NULL; }