]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/Error.cpp
Merge lld trunk r300422 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / COFF / Error.cpp
1 //===- Error.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 "Error.h"
11 #include "Config.h"
12
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/Support/Error.h"
15 #include "llvm/Support/ManagedStatic.h"
16 #include "llvm/Support/Process.h"
17 #include "llvm/Support/raw_ostream.h"
18 #include <mutex>
19
20 #if !defined(_MSC_VER) && !defined(__MINGW32__)
21 #include <unistd.h>
22 #endif
23
24 using namespace llvm;
25
26 namespace lld {
27 // The functions defined in this file can be called from multiple threads,
28 // but outs() or errs() are not thread-safe. We protect them using a mutex.
29 static std::mutex Mu;
30
31 namespace coff {
32 StringRef Argv0;
33 uint64_t ErrorCount;
34 raw_ostream *ErrorOS;
35
36 static LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) {
37   // Dealloc/destroy ManagedStatic variables before calling
38   // _exit(). In a non-LTO build, this is a nop. In an LTO
39   // build allows us to get the output of -time-passes.
40   llvm_shutdown();
41
42   outs().flush();
43   errs().flush();
44   _exit(Val);
45 }
46
47 static void print(StringRef S, raw_ostream::Colors C) {
48   *ErrorOS << Argv0 + ": ";
49   if (Config->ColorDiagnostics) {
50     ErrorOS->changeColor(C, true);
51     *ErrorOS << S;
52     ErrorOS->resetColor();
53   } else {
54     *ErrorOS << S;
55   }
56 }
57
58 void log(const Twine &Msg) {
59   if (Config->Verbose) {
60     std::lock_guard<std::mutex> Lock(Mu);
61     outs() << Argv0 << ": " << Msg << "\n";
62   }
63 }
64
65 void message(const Twine &Msg) {
66   std::lock_guard<std::mutex> Lock(Mu);
67   outs() << Msg << "\n";
68   outs().flush();
69 }
70
71 void error(const Twine &Msg) {
72   std::lock_guard<std::mutex> Lock(Mu);
73
74   if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
75     print("error: ", raw_ostream::RED);
76     *ErrorOS << Msg << "\n";
77   } else if (ErrorCount == Config->ErrorLimit) {
78     print("error: ", raw_ostream::RED);
79     *ErrorOS << "too many errors emitted, stopping now"
80              << " (use /ERRORLIMIT:0 to see all errors)\n";
81     exitLld(1);
82   }
83
84   ++ErrorCount;
85 }
86
87 void fatal(const Twine &Msg) {
88   if (Config->ColorDiagnostics) {
89     errs().changeColor(raw_ostream::RED, /*bold=*/true);
90     errs() << "error: ";
91     errs().resetColor();
92   } else {
93     errs() << "error: ";
94   }
95   errs() << Msg << "\n";
96   exitLld(1);
97 }
98
99 void fatal(std::error_code EC, const Twine &Msg) {
100   fatal(Msg + ": " + EC.message());
101 }
102
103 void fatal(llvm::Error &Err, const Twine &Msg) {
104   fatal(errorToErrorCode(std::move(Err)), Msg);
105 }
106
107 void warn(const Twine &Msg) {
108   std::lock_guard<std::mutex> Lock(Mu);
109   print("warning: ", raw_ostream::MAGENTA);
110   *ErrorOS << Msg << "\n";
111 }
112
113 } // namespace coff
114 } // namespace lld