• 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 // Used for changing only the bold attribute.
25 static const enum llvm::raw_ostream::Colors SavedColor = llvm::raw_ostream::SAVEDCOLOR;
26 
27 //===----------------------------------------------------------------------===//
28 // TextDiagnosticPrinter
TextDiagnosticPrinter(llvm::raw_ostream & pOStream,const LinkerConfig & pConfig)29 TextDiagnosticPrinter::TextDiagnosticPrinter(llvm::raw_ostream& pOStream,
30                                              const LinkerConfig& pConfig)
31   : m_OStream(pOStream), m_Config(pConfig), m_pInput(NULL) {
32 }
33 
~TextDiagnosticPrinter()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
handleDiagnostic(DiagnosticEngine::Severity pSeverity,const Diagnostic & pInfo)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@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 
beginInput(const Input & pInput,const LinkerConfig & pConfig)159 void TextDiagnosticPrinter::beginInput(const Input& pInput, const LinkerConfig& pConfig)
160 {
161   m_pInput = &pInput;
162 }
163 
endInput()164 void TextDiagnosticPrinter::endInput()
165 {
166   m_pInput = NULL;
167 }
168