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