]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - Common/ErrorHandler.cpp
Vendor import of lld trunk r338150:
[FreeBSD/FreeBSD.git] / Common / ErrorHandler.cpp
1 //===- ErrorHandler.cpp ---------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lld/Common/ErrorHandler.h"
11
12 #include "lld/Common/Threads.h"
13
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"
19 #include <mutex>
20
21 #if !defined(_MSC_VER) && !defined(__MINGW32__)
22 #include <unistd.h>
23 #endif
24
25 using namespace llvm;
26 using namespace lld;
27
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.
30 static std::mutex Mu;
31
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.
37   static bool Flag;
38
39   if (Flag)
40     *ErrorOS << "\n";
41   Flag = StringRef(Msg.str()).contains('\n');
42 }
43
44 ErrorHandler &lld::errorHandler() {
45   static ErrorHandler Handler;
46   return Handler;
47 }
48
49 void lld::exitLld(int Val) {
50   // Delete the output buffer so that any tempory file is deleted.
51   errorHandler().OutputBuffer.reset();
52
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.
56   llvm_shutdown();
57
58   outs().flush();
59   errs().flush();
60   _exit(Val);
61 }
62
63 void lld::diagnosticHandler(const DiagnosticInfo &DI) {
64   SmallString<128> S;
65   raw_svector_ostream OS(S);
66   DiagnosticPrinterRawOStream DP(OS);
67   DI.print(DP);
68   switch (DI.getSeverity()) {
69   case DS_Error:
70     error(S);
71     break;
72   case DS_Warning:
73     warn(S);
74     break;
75   case DS_Remark:
76   case DS_Note:
77     message(S);
78     break;
79   }
80 }
81
82 void lld::checkError(Error E) {
83   handleAllErrors(std::move(E),
84                   [&](ErrorInfoBase &EIB) { error(EIB.message()); });
85 }
86
87 void ErrorHandler::print(StringRef S, raw_ostream::Colors C) {
88   *ErrorOS << LogName << ": ";
89   if (ColorDiagnostics) {
90     ErrorOS->changeColor(C, true);
91     *ErrorOS << S;
92     ErrorOS->resetColor();
93   } else {
94     *ErrorOS << S;
95   }
96 }
97
98 void ErrorHandler::log(const Twine &Msg) {
99   if (Verbose) {
100     std::lock_guard<std::mutex> Lock(Mu);
101     *ErrorOS << LogName << ": " << Msg << "\n";
102   }
103 }
104
105 void ErrorHandler::message(const Twine &Msg) {
106   std::lock_guard<std::mutex> Lock(Mu);
107   outs() << Msg << "\n";
108   outs().flush();
109 }
110
111 void ErrorHandler::warn(const Twine &Msg) {
112   if (FatalWarnings) {
113     error(Msg);
114     return;
115   }
116
117   std::lock_guard<std::mutex> Lock(Mu);
118   newline(ErrorOS, Msg);
119   print("warning: ", raw_ostream::MAGENTA);
120   *ErrorOS << Msg << "\n";
121 }
122
123 void ErrorHandler::error(const Twine &Msg) {
124   std::lock_guard<std::mutex> Lock(Mu);
125   newline(ErrorOS, Msg);
126
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";
133     if (ExitEarly)
134       exitLld(1);
135   }
136
137   ++ErrorCount;
138 }
139
140 void ErrorHandler::fatal(const Twine &Msg) {
141   error(Msg);
142   exitLld(1);
143 }