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 
     11 #include "mcld/LinkerConfig.h"
     12 
     13 #include <llvm/Support/Signals.h>
     14 
     15 #include <string>
     16 
     17 namespace mcld {
     18 
     19 static const enum llvm::raw_ostream::Colors UnreachableColor =
     20     llvm::raw_ostream::RED;
     21 static const enum llvm::raw_ostream::Colors FatalColor =
     22     llvm::raw_ostream::YELLOW;
     23 static const enum llvm::raw_ostream::Colors ErrorColor = llvm::raw_ostream::RED;
     24 static const enum llvm::raw_ostream::Colors WarningColor =
     25     llvm::raw_ostream::MAGENTA;
     26 static const enum llvm::raw_ostream::Colors DebugColor =
     27     llvm::raw_ostream::CYAN;
     28 static const enum llvm::raw_ostream::Colors NoteColor =
     29     llvm::raw_ostream::GREEN;
     30 static const enum llvm::raw_ostream::Colors IgnoreColor =
     31     llvm::raw_ostream::BLUE;
     32 
     33 //===----------------------------------------------------------------------===//
     34 // TextDiagnosticPrinter
     35 TextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream& pOStream,
     36                                              const LinkerConfig& pConfig)
     37     : m_OStream(pOStream), m_Config(pConfig), m_pInput(NULL) {
     38 }
     39 
     40 TextDiagnosticPrinter::~TextDiagnosticPrinter() {
     41 }
     42 
     43 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
     44 /// capturing it to a log as needed.
     45 void TextDiagnosticPrinter::handleDiagnostic(
     46     DiagnosticEngine::Severity pSeverity,
     47     const Diagnostic& pInfo) {
     48   DiagnosticPrinter::handleDiagnostic(pSeverity, pInfo);
     49 
     50   std::string out_string;
     51   pInfo.format(out_string);
     52 
     53   switch (pSeverity) {
     54     case DiagnosticEngine::Unreachable: {
     55       m_OStream.changeColor(UnreachableColor, true);
     56       m_OStream << "Unreachable: ";
     57       m_OStream.resetColor();
     58       m_OStream << out_string << "\n";
     59       break;
     60     }
     61     case DiagnosticEngine::Fatal: {
     62       m_OStream.changeColor(FatalColor, true);
     63       m_OStream << "Fatal: ";
     64       m_OStream.resetColor();
     65       m_OStream << out_string << "\n";
     66       break;
     67     }
     68     case DiagnosticEngine::Error: {
     69       m_OStream.changeColor(ErrorColor, true);
     70       m_OStream << "Error: ";
     71       m_OStream.resetColor();
     72       m_OStream << out_string << "\n";
     73       break;
     74     }
     75     case DiagnosticEngine::Warning: {
     76       m_OStream.changeColor(WarningColor, true);
     77       m_OStream << "Warning: ";
     78       m_OStream.resetColor();
     79       m_OStream << out_string << "\n";
     80       break;
     81     }
     82     case DiagnosticEngine::Debug: {
     83       // show debug message only if verbose >= 0
     84       if (m_Config.options().verbose() >= 0) {
     85         m_OStream.changeColor(DebugColor, true);
     86         m_OStream << "Debug: ";
     87         m_OStream.resetColor();
     88         m_OStream << out_string << "\n";
     89       }
     90       break;
     91     }
     92     case DiagnosticEngine::Note: {
     93       // show ignored message only if verbose >= 1
     94       if (m_Config.options().verbose() >= 1) {
     95         m_OStream.changeColor(NoteColor, true);
     96         m_OStream << "Note: ";
     97         m_OStream.resetColor();
     98         m_OStream << out_string << "\n";
     99       }
    100       break;
    101     }
    102     case DiagnosticEngine::Ignore: {
    103       // show ignored message only if verbose >= 2
    104       if (m_Config.options().verbose() >= 2) {
    105         m_OStream.changeColor(IgnoreColor, true);
    106         m_OStream << "Ignore: ";
    107         m_OStream.resetColor();
    108         m_OStream << out_string << "\n";
    109       }
    110       break;
    111     }
    112     default:
    113       break;
    114   }
    115 
    116   switch (pSeverity) {
    117     case DiagnosticEngine::Unreachable: {
    118       m_OStream << "\n\n";
    119       m_OStream.changeColor(llvm::raw_ostream::YELLOW);
    120       m_OStream << "You encounter a bug of MCLinker, please report to:\n"
    121                 << "  mclinker (at) googlegroups.com\n";
    122       m_OStream.resetColor();
    123     }
    124     /** fall through **/
    125     case DiagnosticEngine::Fatal: {
    126       // If we reached here, we are failing ungracefully. Run the interrupt
    127       // handlers
    128       // to make sure any special cleanups get done, in particular that we
    129       // remove
    130       // files registered with RemoveFileOnSignal.
    131       llvm::sys::RunInterruptHandlers();
    132       exit(1);
    133       break;
    134     }
    135     case DiagnosticEngine::Error: {
    136       int16_t error_limit = m_Config.options().maxErrorNum();
    137       if ((error_limit != -1) &&
    138           (getNumErrors() > static_cast<unsigned>(error_limit))) {
    139         m_OStream << "\n\n";
    140         m_OStream.changeColor(llvm::raw_ostream::YELLOW);
    141         m_OStream << "too many error messages (>" << error_limit << ")...\n";
    142         m_OStream.resetColor();
    143         llvm::sys::RunInterruptHandlers();
    144         exit(1);
    145       }
    146       break;
    147     }
    148     case DiagnosticEngine::Warning: {
    149       int16_t warning_limit = m_Config.options().maxWarnNum();
    150       if ((warning_limit != -1) &&
    151           (getNumWarnings() > static_cast<unsigned>(warning_limit))) {
    152         m_OStream << "\n\n";
    153         m_OStream.changeColor(llvm::raw_ostream::YELLOW);
    154         m_OStream << "too many warning messages (>" << warning_limit
    155                   << ")...\n";
    156         m_OStream.resetColor();
    157         llvm::sys::RunInterruptHandlers();
    158         exit(1);
    159       }
    160     }
    161     default:
    162       break;
    163   }
    164 }
    165 
    166 void TextDiagnosticPrinter::beginInput(const Input& pInput,
    167                                        const LinkerConfig& pConfig) {
    168   m_pInput = &pInput;
    169 }
    170 
    171 void TextDiagnosticPrinter::endInput() {
    172   m_pInput = NULL;
    173 }
    174 
    175 }  // namespace mcld
    176