1 //===- ErrorHandler.cpp ---------------------------------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lld/Common/ErrorHandler.h"
12 #include "lld/Common/Threads.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/IR/DiagnosticInfo.h"
16 #include "llvm/IR/DiagnosticPrinter.h"
17 #include "llvm/Support/ManagedStatic.h"
18 #include "llvm/Support/raw_ostream.h"
21 #if !defined(_MSC_VER) && !defined(__MINGW32__)
28 // The functions defined in this file can be called from multiple threads,
29 // but outs() or errs() are not thread-safe. We protect them using a mutex.
32 // Prints "\n" or does nothing, depending on Msg contents of
33 // the previous call of this function.
34 static void newline(raw_ostream *ErrorOS, const Twine &Msg) {
35 // True if the previous error message contained "\n".
36 // We want to separate multi-line error messages with a newline.
41 Flag = StringRef(Msg.str()).contains('\n');
44 ErrorHandler &lld::errorHandler() {
45 static ErrorHandler Handler;
49 void lld::exitLld(int Val) {
50 // Delete the output buffer so that any tempory file is deleted.
51 errorHandler().OutputBuffer.reset();
53 // Dealloc/destroy ManagedStatic variables before calling
54 // _exit(). In a non-LTO build, this is a nop. In an LTO
55 // build allows us to get the output of -time-passes.
63 void lld::diagnosticHandler(const DiagnosticInfo &DI) {
65 raw_svector_ostream OS(S);
66 DiagnosticPrinterRawOStream DP(OS);
68 switch (DI.getSeverity()) {
82 void lld::checkError(Error E) {
83 handleAllErrors(std::move(E),
84 [&](ErrorInfoBase &EIB) { error(EIB.message()); });
87 void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
88 *ErrorOS << LogName << ": ";
89 if (ColorDiagnostics) {
90 ErrorOS->changeColor(C, true);
92 ErrorOS->resetColor();
98 void ErrorHandler::log(const Twine &Msg) {
100 std::lock_guard<std::mutex> Lock(Mu);
101 *ErrorOS << LogName << ": " << Msg << "\n";
105 void ErrorHandler::message(const Twine &Msg) {
106 std::lock_guard<std::mutex> Lock(Mu);
107 outs() << Msg << "\n";
111 void ErrorHandler::warn(const Twine &Msg) {
117 std::lock_guard<std::mutex> Lock(Mu);
118 newline(ErrorOS, Msg);
119 print("warning: ", raw_ostream::MAGENTA);
120 *ErrorOS << Msg << "\n";
123 void ErrorHandler::error(const Twine &Msg) {
124 std::lock_guard<std::mutex> Lock(Mu);
125 newline(ErrorOS, Msg);
127 if (ErrorLimit == 0 || ErrorCount < ErrorLimit) {
128 print("error: ", raw_ostream::RED);
129 *ErrorOS << Msg << "\n";
130 } else if (ErrorCount == ErrorLimit) {
131 print("error: ", raw_ostream::RED);
132 *ErrorOS << ErrorLimitExceededMsg << "\n";
140 void ErrorHandler::fatal(const Twine &Msg) {