blob: c169f7b50de891254f891d6a98dc113387869460 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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//
Andrew Scullcdfcccc2018-10-05 20:58:37 +010010// We designed lld's error handlers with the following goals in mind:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010011//
Andrew Scullcdfcccc2018-10-05 20:58:37 +010012// - 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).
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010016//
Andrew Scullcdfcccc2018-10-05 20:58:37 +010017// 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.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022//
Andrew Scullcdfcccc2018-10-05 20:58:37 +010023// - 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).
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010028//
Andrew Scullcdfcccc2018-10-05 20:58:37 +010029// - 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.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010066//
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
Andrew Scullcdfcccc2018-10-05 20:58:37 +010078namespace llvm {
79class DiagnosticInfo;
80}
81
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010082namespace lld {
83
84class ErrorHandler {
85public:
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
104private:
105 void print(StringRef S, raw_ostream::Colors C);
106};
107
108/// Returns the default error handler.
109ErrorHandler &errorHandler();
110
111inline void error(const Twine &Msg) { errorHandler().error(Msg); }
112inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg) {
113 errorHandler().fatal(Msg);
114}
115inline void log(const Twine &Msg) { errorHandler().log(Msg); }
116inline void message(const Twine &Msg) { errorHandler().message(Msg); }
117inline void warn(const Twine &Msg) { errorHandler().warn(Msg); }
118inline uint64_t errorCount() { return errorHandler().ErrorCount; }
119
120LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
121
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100122void diagnosticHandler(const llvm::DiagnosticInfo &DI);
123void checkError(Error E);
124
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100125// check functions are convenient functions to strip errors
126// from error-or-value objects.
127template <class T> T check(ErrorOr<T> E) {
128 if (auto EC = E.getError())
129 fatal(EC.message());
130 return std::move(*E);
131}
132
133template <class T> T check(Expected<T> E) {
134 if (!E)
135 fatal(llvm::toString(E.takeError()));
136 return std::move(*E);
137}
138
139template <class T>
140T 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
146template <class T>
147T 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
153inline std::string toString(const Twine &S) { return S.str(); }
154
155// To evaluate the second argument lazily, we use C macro.
Andrew Scull0372a572018-11-16 15:47:06 +0000156#define CHECK(E, S) check2((E), [&] { return toString(S); })
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100157
158} // namespace lld
159
160#endif