diff options
author | Bob Haarman <llvm@inglorion.net> | 2017-10-25 22:28:38 +0000 |
---|---|---|
committer | Bob Haarman <llvm@inglorion.net> | 2017-10-25 22:28:38 +0000 |
commit | b8a59c8aa5ff25aa21a64169c1870d988401cd53 (patch) | |
tree | e8c92ab03251381c760718413916ddee9bd4574a /lld/include/lld | |
parent | 5e6cb9022c5c87f3ecf593f3210d15fd25467342 (diff) | |
download | bcm5719-llvm-b8a59c8aa5ff25aa21a64169c1870d988401cd53.tar.gz bcm5719-llvm-b8a59c8aa5ff25aa21a64169c1870d988401cd53.zip |
[lld] unified COFF and ELF error handling on new Common/ErrorHandler
Summary:
The COFF linker and the ELF linker have long had similar but separate
Error.h and Error.cpp files to implement error handling. This change
introduces new error handling code in Common/ErrorHandler.h, changes the
COFF and ELF linkers to use it, and removes the old, separate
implementations.
Reviewers: ruiu
Reviewed By: ruiu
Subscribers: smeenai, jyknight, emaste, sdardis, nemanjai, nhaehnle, mgorny, javed.absar, kbarton, fedor.sergeev, llvm-commits
Differential Revision: https://reviews.llvm.org/D39259
llvm-svn: 316624
Diffstat (limited to 'lld/include/lld')
-rw-r--r-- | lld/include/lld/Common/ErrorHandler.h | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/lld/include/lld/Common/ErrorHandler.h b/lld/include/lld/Common/ErrorHandler.h new file mode 100644 index 00000000000..05a1d6cd5fc --- /dev/null +++ b/lld/include/lld/Common/ErrorHandler.h @@ -0,0 +1,101 @@ +//===- ErrorHandler.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// In LLD, we have three levels of errors: fatal, error or warn. +// +// Fatal makes the program exit immediately with an error message. +// You shouldn't use it except for reporting a corrupted input file. +// +// Error prints out an error message and increment a global variable +// ErrorCount to record the fact that we met an error condition. It does +// not exit, so it is safe for a lld-as-a-library use case. It is generally +// useful because it can report more than one error in a single run. +// +// Warn doesn't do anything but printing out a given message. +// +// It is not recommended to use llvm::outs() or llvm::errs() directly +// in LLD because they are not thread-safe. The functions declared in +// this file are mutually excluded, so you want to use them instead. +// +//===----------------------------------------------------------------------===// + +#ifndef LLD_COMMON_ERRORHANDLER_H +#define LLD_COMMON_ERRORHANDLER_H + +#include "lld/Common/LLVM.h" + +#include "llvm/Support/Error.h" + +namespace lld { + +class ErrorHandler { +public: + uint64_t ErrorCount = 0; + uint64_t ErrorLimit = 20; + StringRef ErrorLimitExceededMsg = "too many errors emitted, stopping now"; + StringRef LogName = "lld"; + llvm::raw_ostream *ErrorOS = &llvm::errs(); + bool ColorDiagnostics = llvm::errs().has_colors(); + bool ExitEarly = true; + bool FatalWarnings = false; + bool Verbose = false; + + void error(const Twine &Msg); + LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg); + void log(const Twine &Msg); + void message(const Twine &Msg); + void warn(const Twine &Msg); + +private: + void print(StringRef S, raw_ostream::Colors C); +}; + +/// Returns the default error handler. +ErrorHandler &errorHandler(); + +inline void error(const Twine &Msg) { errorHandler().error(Msg); } +inline LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg) { + errorHandler().fatal(Msg); +} +inline void log(const Twine &Msg) { errorHandler().log(Msg); } +inline void message(const Twine &Msg) { errorHandler().message(Msg); } +inline void warn(const Twine &Msg) { errorHandler().warn(Msg); } +inline uint64_t errorCount() { return errorHandler().ErrorCount; } + +LLVM_ATTRIBUTE_NORETURN void exitLld(int Val); + +// check() functions are convenient functions to strip errors +// from error-or-value objects. +template <class T> T check(ErrorOr<T> E) { + if (auto EC = E.getError()) + fatal(EC.message()); + return std::move(*E); +} + +template <class T> T check(Expected<T> E) { + if (!E) + fatal(llvm::toString(E.takeError())); + return std::move(*E); +} + +template <class T> T check(ErrorOr<T> E, const Twine &Prefix) { + if (auto EC = E.getError()) + fatal(Prefix + ": " + EC.message()); + return std::move(*E); +} + +template <class T> T check(Expected<T> E, const Twine &Prefix) { + if (!E) + fatal(Prefix + ": " + toString(E.takeError())); + return std::move(*E); +} + +} // namespace lld + +#endif |