ErrorHandler.h revision 344779
1326947Sdim//===- ErrorHandler.h -------------------------------------------*- C++ -*-===//
2326947Sdim//
3326947Sdim//                             The LLVM Linker
4326947Sdim//
5326947Sdim// This file is distributed under the University of Illinois Open Source
6326947Sdim// License. See LICENSE.TXT for details.
7326947Sdim//
8326947Sdim//===----------------------------------------------------------------------===//
9326947Sdim//
10341825Sdim// We designed lld's error handlers with the following goals in mind:
11326947Sdim//
12341825Sdim//  - Errors can occur at any place where we handle user input, but we don't
13341825Sdim//    want them to affect the normal execution path too much. Ideally,
14341825Sdim//    handling errors should be as simple as reporting them and exit (but
15341825Sdim//    without actually doing exit).
16326947Sdim//
17341825Sdim//    In particular, the design to wrap all functions that could fail with
18341825Sdim//    ErrorOr<T> is rejected because otherwise we would have to wrap a large
19341825Sdim//    number of functions in lld with ErrorOr. With that approach, if some
20341825Sdim//    function F can fail, not only F but all functions that transitively call
21341825Sdim//    F have to be wrapped with ErrorOr. That seemed too much.
22326947Sdim//
23341825Sdim//  - Finding only one error at a time is not sufficient. We want to find as
24341825Sdim//    many errors as possible with one execution of the linker. That means the
25341825Sdim//    linker needs to keep running after a first error and give up at some
26341825Sdim//    checkpoint (beyond which it would find cascading, false errors caused by
27341825Sdim//    the previous errors).
28326947Sdim//
29341825Sdim//  - We want a simple interface to report errors. Unlike Clang, the data we
30341825Sdim//    handle is compiled binary, so we don't need an error reporting mechanism
31341825Sdim//    that's as sophisticated as the one that Clang has.
32326947Sdim//
33341825Sdim// The current lld's error handling mechanism is simple:
34341825Sdim//
35341825Sdim//  - When you find an error, report it using error() and continue as far as
36341825Sdim//    you can. An internal error counter is incremented by one every time you
37341825Sdim//    call error().
38341825Sdim//
39341825Sdim//    A common idiom to handle an error is calling error() and then returning
40341825Sdim//    a reasonable default value. For example, if your function handles a
41341825Sdim//    user-supplied alignment value, and if you find an invalid alignment
42341825Sdim//    (e.g. 17 which is not 2^n), you may report it using error() and continue
43341825Sdim//    as if it were alignment 1 (which is the simplest reasonable value).
44341825Sdim//
45341825Sdim//    Note that you should not continue with an invalid value; that breaks the
46341825Sdim//    internal consistency. You need to maintain all variables have some sane
47341825Sdim//    value even after an error occurred. So, when you have to continue with
48341825Sdim//    some value, always use a dummy value.
49341825Sdim//
50341825Sdim//  - Find a reasonable checkpoint at where you want to stop the linker, and
51341825Sdim//    add code to return from the function if errorCount() > 0. In most cases,
52341825Sdim//    a checkpoint already exists, so you don't need to do anything for this.
53341825Sdim//
54341825Sdim// This interface satisfies all the goals that we mentioned above.
55341825Sdim//
56341825Sdim// You should never call fatal() except for reporting a corrupted input file.
57341825Sdim// fatal() immediately terminates the linker, so the function is not desirable
58341825Sdim// if you are using lld as a subroutine in other program, and with that you
59341825Sdim// can find only one error at a time.
60341825Sdim//
61341825Sdim// warn() doesn't do anything but printing out a given message.
62341825Sdim//
63341825Sdim// It is not recommended to use llvm::outs() or llvm::errs() directly in lld
64341825Sdim// because they are not thread-safe. The functions declared in this file are
65341825Sdim// thread-safe.
66341825Sdim//
67326947Sdim//===----------------------------------------------------------------------===//
68326947Sdim
69326947Sdim#ifndef LLD_COMMON_ERRORHANDLER_H
70326947Sdim#define LLD_COMMON_ERRORHANDLER_H
71326947Sdim
72326947Sdim#include "lld/Common/LLVM.h"
73326947Sdim
74326947Sdim#include "llvm/ADT/STLExtras.h"
75326947Sdim#include "llvm/Support/Error.h"
76326947Sdim#include "llvm/Support/FileOutputBuffer.h"
77326947Sdim
78341825Sdimnamespace llvm {
79341825Sdimclass DiagnosticInfo;
80341825Sdim}
81341825Sdim
82326947Sdimnamespace lld {
83326947Sdim
84326947Sdimclass ErrorHandler {
85326947Sdimpublic:
86326947Sdim  uint64_t ErrorCount = 0;
87326947Sdim  uint64_t ErrorLimit = 20;
88326947Sdim  StringRef ErrorLimitExceededMsg = "too many errors emitted, stopping now";
89326947Sdim  StringRef LogName = "lld";
90326947Sdim  llvm::raw_ostream *ErrorOS = &llvm::errs();
91326947Sdim  bool ColorDiagnostics = llvm::errs().has_colors();
92326947Sdim  bool ExitEarly = true;
93326947Sdim  bool FatalWarnings = false;
94326947Sdim  bool Verbose = false;
95326947Sdim
96326947Sdim  void error(const Twine &Msg);
97326947Sdim  LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
98326947Sdim  void log(const Twine &Msg);
99326947Sdim  void message(const Twine &Msg);
100326947Sdim  void warn(const Twine &Msg);
101326947Sdim
102326947Sdim  std::unique_ptr<llvm::FileOutputBuffer> OutputBuffer;
103326947Sdim
104326947Sdimprivate:
105326947Sdim  void print(StringRef S, raw_ostream::Colors C);
106326947Sdim};
107326947Sdim
108326947Sdim/// Returns the default error handler.
109326947SdimErrorHandler &errorHandler();
110326947Sdim
111326947Sdiminline void error(const Twine &Msg) { errorHandler().error(Msg); }
112326947Sdiminline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg) {
113326947Sdim  errorHandler().fatal(Msg);
114326947Sdim}
115326947Sdiminline void log(const Twine &Msg) { errorHandler().log(Msg); }
116326947Sdiminline void message(const Twine &Msg) { errorHandler().message(Msg); }
117326947Sdiminline void warn(const Twine &Msg) { errorHandler().warn(Msg); }
118326947Sdiminline uint64_t errorCount() { return errorHandler().ErrorCount; }
119326947Sdim
120326947SdimLLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
121326947Sdim
122341825Sdimvoid diagnosticHandler(const llvm::DiagnosticInfo &DI);
123341825Sdimvoid checkError(Error E);
124341825Sdim
125326947Sdim// check functions are convenient functions to strip errors
126326947Sdim// from error-or-value objects.
127326947Sdimtemplate <class T> T check(ErrorOr<T> E) {
128326947Sdim  if (auto EC = E.getError())
129326947Sdim    fatal(EC.message());
130326947Sdim  return std::move(*E);
131326947Sdim}
132326947Sdim
133326947Sdimtemplate <class T> T check(Expected<T> E) {
134326947Sdim  if (!E)
135326947Sdim    fatal(llvm::toString(E.takeError()));
136326947Sdim  return std::move(*E);
137326947Sdim}
138326947Sdim
139326947Sdimtemplate <class T>
140326947SdimT check2(ErrorOr<T> E, llvm::function_ref<std::string()> Prefix) {
141326947Sdim  if (auto EC = E.getError())
142326947Sdim    fatal(Prefix() + ": " + EC.message());
143326947Sdim  return std::move(*E);
144326947Sdim}
145326947Sdim
146326947Sdimtemplate <class T>
147326947SdimT check2(Expected<T> E, llvm::function_ref<std::string()> Prefix) {
148326947Sdim  if (!E)
149326947Sdim    fatal(Prefix() + ": " + toString(E.takeError()));
150326947Sdim  return std::move(*E);
151326947Sdim}
152326947Sdim
153326947Sdiminline std::string toString(const Twine &S) { return S.str(); }
154326947Sdim
155326947Sdim// To evaluate the second argument lazily, we use C macro.
156344779Sdim#define CHECK(E, S) check2((E), [&] { return toString(S); })
157326947Sdim
158326947Sdim} // namespace lld
159326947Sdim
160326947Sdim#endif
161