1 //===- ErrorHandler.h -------------------------------------------*- C++ -*-===//
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 // We designed lld's error handlers with the following goals in mind:
11 //
12 // - Errors can occur at any place where we handle user input, but we don't
13 // want them to affect the normal execution path too much. Ideally,
14 // handling errors should be as simple as reporting them and exit (but
15 // without actually doing exit).
16 //
17 // In particular, the design to wrap all functions that could fail with
18 // ErrorOr<T> is rejected because otherwise we would have to wrap a large
19 // number of functions in lld with ErrorOr. With that approach, if some
20 // function F can fail, not only F but all functions that transitively call
21 // F have to be wrapped with ErrorOr. That seemed too much.
22 //
23 // - Finding only one error at a time is not sufficient. We want to find as
24 // many errors as possible with one execution of the linker. That means the
25 // linker needs to keep running after a first error and give up at some
26 // checkpoint (beyond which it would find cascading, false errors caused by
27 // the previous errors).
28 //
29 // - We want a simple interface to report errors. Unlike Clang, the data we
30 // handle is compiled binary, so we don't need an error reporting mechanism
31 // that's as sophisticated as the one that Clang has.
32 //
33 // The current lld's error handling mechanism is simple:
34 //
35 // - When you find an error, report it using error() and continue as far as
36 // you can. An internal error counter is incremented by one every time you
37 // call error().
38 //
39 // A common idiom to handle an error is calling error() and then returning
40 // a reasonable default value. For example, if your function handles a
41 // user-supplied alignment value, and if you find an invalid alignment
42 // (e.g. 17 which is not 2^n), you may report it using error() and continue
43 // as if it were alignment 1 (which is the simplest reasonable value).
44 //
45 // Note that you should not continue with an invalid value; that breaks the
46 // internal consistency. You need to maintain all variables have some sane
47 // value even after an error occurred. So, when you have to continue with
48 // some value, always use a dummy value.
49 //
50 // - Find a reasonable checkpoint at where you want to stop the linker, and
51 // add code to return from the function if errorCount() > 0. In most cases,
52 // a checkpoint already exists, so you don't need to do anything for this.
53 //
54 // This interface satisfies all the goals that we mentioned above.
55 //
56 // You should never call fatal() except for reporting a corrupted input file.
57 // fatal() immediately terminates the linker, so the function is not desirable
58 // if you are using lld as a subroutine in other program, and with that you
59 // can find only one error at a time.
60 //
61 // warn() doesn't do anything but printing out a given message.
62 //
63 // It is not recommended to use llvm::outs() or llvm::errs() directly in lld
64 // because they are not thread-safe. The functions declared in this file are
65 // thread-safe.
66 //
67 //===----------------------------------------------------------------------===//
68
69 #ifndef LLD_COMMON_ERRORHANDLER_H
70 #define LLD_COMMON_ERRORHANDLER_H
71
72 #include "lld/Common/LLVM.h"
73
74 #include "llvm/ADT/STLExtras.h"
75 #include "llvm/Support/Error.h"
76 #include "llvm/Support/FileOutputBuffer.h"
77
78 namespace llvm {
79 class DiagnosticInfo;
80 }
81
82 namespace lld {
83
84 class ErrorHandler {
85 public:
86 uint64_t ErrorCount = 0;
87 uint64_t ErrorLimit = 20;
88 StringRef ErrorLimitExceededMsg = "too many errors emitted, stopping now";
89 StringRef LogName = "lld";
90 llvm::raw_ostream *ErrorOS = &llvm::errs();
91 bool ColorDiagnostics = llvm::errs().has_colors();
92 bool ExitEarly = true;
93 bool FatalWarnings = false;
94 bool Verbose = false;
95
96 void error(const Twine &Msg);
97 LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
98 void log(const Twine &Msg);
99 void message(const Twine &Msg);
100 void warn(const Twine &Msg);
101
102 std::unique_ptr<llvm::FileOutputBuffer> OutputBuffer;
103
104 private:
105 void print(StringRef S, raw_ostream::Colors C);
106 };
107
108 /// Returns the default error handler.
109 ErrorHandler &errorHandler();
110
error(const Twine & Msg)111 inline void error(const Twine &Msg) { errorHandler().error(Msg); }
fatal(const Twine & Msg)112 inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg) {
113 errorHandler().fatal(Msg);
114 }
log(const Twine & Msg)115 inline void log(const Twine &Msg) { errorHandler().log(Msg); }
message(const Twine & Msg)116 inline void message(const Twine &Msg) { errorHandler().message(Msg); }
warn(const Twine & Msg)117 inline void warn(const Twine &Msg) { errorHandler().warn(Msg); }
errorCount()118 inline uint64_t errorCount() { return errorHandler().ErrorCount; }
119
120 LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
121
122 void diagnosticHandler(const llvm::DiagnosticInfo &DI);
123 void checkError(Error E);
124
125 // check functions are convenient functions to strip errors
126 // from error-or-value objects.
check(ErrorOr<T> E)127 template <class T> T check(ErrorOr<T> E) {
128 if (auto EC = E.getError())
129 fatal(EC.message());
130 return std::move(*E);
131 }
132
check(Expected<T> E)133 template <class T> T check(Expected<T> E) {
134 if (!E)
135 fatal(llvm::toString(E.takeError()));
136 return std::move(*E);
137 }
138
139 template <class T>
check2(ErrorOr<T> E,llvm::function_ref<std::string ()> Prefix)140 T check2(ErrorOr<T> E, llvm::function_ref<std::string()> Prefix) {
141 if (auto EC = E.getError())
142 fatal(Prefix() + ": " + EC.message());
143 return std::move(*E);
144 }
145
146 template <class T>
check2(Expected<T> E,llvm::function_ref<std::string ()> Prefix)147 T check2(Expected<T> E, llvm::function_ref<std::string()> Prefix) {
148 if (!E)
149 fatal(Prefix() + ": " + toString(E.takeError()));
150 return std::move(*E);
151 }
152
toString(const Twine & S)153 inline std::string toString(const Twine &S) { return S.str(); }
154
155 // To evaluate the second argument lazily, we use C macro.
156 #define CHECK(E, S) check2((E), [&] { return toString(S); })
157
158 } // namespace lld
159
160 #endif
161