ErrorHandler.h revision 341825
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. 156326947Sdim#define CHECK(E, S) check2(E, [&] { return toString(S); }) 157326947Sdim 158326947Sdim} // namespace lld 159326947Sdim 160326947Sdim#endif 161