ErrorHandler.h revision 326947
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//
10326947Sdim// In LLD, we have three levels of errors: fatal, error or warn.
11326947Sdim//
12326947Sdim// Fatal makes the program exit immediately with an error message.
13326947Sdim// You shouldn't use it except for reporting a corrupted input file.
14326947Sdim//
15326947Sdim// Error prints out an error message and increment a global variable
16326947Sdim// ErrorCount to record the fact that we met an error condition. It does
17326947Sdim// not exit, so it is safe for a lld-as-a-library use case. It is generally
18326947Sdim// useful because it can report more than one error in a single run.
19326947Sdim//
20326947Sdim// Warn doesn't do anything but printing out a given message.
21326947Sdim//
22326947Sdim// It is not recommended to use llvm::outs() or llvm::errs() directly
23326947Sdim// in LLD because they are not thread-safe. The functions declared in
24326947Sdim// this file are mutually excluded, so you want to use them instead.
25326947Sdim//
26326947Sdim//===----------------------------------------------------------------------===//
27326947Sdim
28326947Sdim#ifndef LLD_COMMON_ERRORHANDLER_H
29326947Sdim#define LLD_COMMON_ERRORHANDLER_H
30326947Sdim
31326947Sdim#include "lld/Common/LLVM.h"
32326947Sdim
33326947Sdim#include "llvm/ADT/STLExtras.h"
34326947Sdim#include "llvm/Support/Error.h"
35326947Sdim#include "llvm/Support/FileOutputBuffer.h"
36326947Sdim
37326947Sdimnamespace lld {
38326947Sdim
39326947Sdimclass ErrorHandler {
40326947Sdimpublic:
41326947Sdim  uint64_t ErrorCount = 0;
42326947Sdim  uint64_t ErrorLimit = 20;
43326947Sdim  StringRef ErrorLimitExceededMsg = "too many errors emitted, stopping now";
44326947Sdim  StringRef LogName = "lld";
45326947Sdim  llvm::raw_ostream *ErrorOS = &llvm::errs();
46326947Sdim  bool ColorDiagnostics = llvm::errs().has_colors();
47326947Sdim  bool ExitEarly = true;
48326947Sdim  bool FatalWarnings = false;
49326947Sdim  bool Verbose = false;
50326947Sdim
51326947Sdim  void error(const Twine &Msg);
52326947Sdim  LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
53326947Sdim  void log(const Twine &Msg);
54326947Sdim  void message(const Twine &Msg);
55326947Sdim  void warn(const Twine &Msg);
56326947Sdim
57326947Sdim  std::unique_ptr<llvm::FileOutputBuffer> OutputBuffer;
58326947Sdim
59326947Sdimprivate:
60326947Sdim  void print(StringRef S, raw_ostream::Colors C);
61326947Sdim};
62326947Sdim
63326947Sdim/// Returns the default error handler.
64326947SdimErrorHandler &errorHandler();
65326947Sdim
66326947Sdiminline void error(const Twine &Msg) { errorHandler().error(Msg); }
67326947Sdiminline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg) {
68326947Sdim  errorHandler().fatal(Msg);
69326947Sdim}
70326947Sdiminline void log(const Twine &Msg) { errorHandler().log(Msg); }
71326947Sdiminline void message(const Twine &Msg) { errorHandler().message(Msg); }
72326947Sdiminline void warn(const Twine &Msg) { errorHandler().warn(Msg); }
73326947Sdiminline uint64_t errorCount() { return errorHandler().ErrorCount; }
74326947Sdim
75326947SdimLLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
76326947Sdim
77326947Sdim// check functions are convenient functions to strip errors
78326947Sdim// from error-or-value objects.
79326947Sdimtemplate <class T> T check(ErrorOr<T> E) {
80326947Sdim  if (auto EC = E.getError())
81326947Sdim    fatal(EC.message());
82326947Sdim  return std::move(*E);
83326947Sdim}
84326947Sdim
85326947Sdimtemplate <class T> T check(Expected<T> E) {
86326947Sdim  if (!E)
87326947Sdim    fatal(llvm::toString(E.takeError()));
88326947Sdim  return std::move(*E);
89326947Sdim}
90326947Sdim
91326947Sdimtemplate <class T>
92326947SdimT check2(ErrorOr<T> E, llvm::function_ref<std::string()> Prefix) {
93326947Sdim  if (auto EC = E.getError())
94326947Sdim    fatal(Prefix() + ": " + EC.message());
95326947Sdim  return std::move(*E);
96326947Sdim}
97326947Sdim
98326947Sdimtemplate <class T>
99326947SdimT check2(Expected<T> E, llvm::function_ref<std::string()> Prefix) {
100326947Sdim  if (!E)
101326947Sdim    fatal(Prefix() + ": " + toString(E.takeError()));
102326947Sdim  return std::move(*E);
103326947Sdim}
104326947Sdim
105326947Sdiminline std::string toString(const Twine &S) { return S.str(); }
106326947Sdim
107326947Sdim// To evaluate the second argument lazily, we use C macro.
108326947Sdim#define CHECK(E, S) check2(E, [&] { return toString(S); })
109326947Sdim
110326947Sdim} // namespace lld
111326947Sdim
112326947Sdim#endif
113