• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
TextDiagnosticPrinter(llvm::raw_ostream & pOStream,const LinkerConfig & pConfig)26 TextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream& pOStream,
27                                              const LinkerConfig& pConfig)
28   : m_OStream(pOStream), m_Config(pConfig), m_pInput(NULL) {
29 }
30 
~TextDiagnosticPrinter()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
handleDiagnostic(DiagnosticEngine::Severity pSeverity,const Diagnostic & pInfo)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@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 
beginInput(const Input & pInput,const LinkerConfig & pConfig)156 void TextDiagnosticPrinter::beginInput(const Input& pInput, const LinkerConfig& pConfig)
157 {
158   m_pInput = &pInput;
159 }
160 
endInput()161 void TextDiagnosticPrinter::endInput()
162 {
163   m_pInput = NULL;
164 }
165