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