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 // 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