Home | History | Annotate | Download | only in LD
      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