2015-08-14 22:12:54 +08:00
|
|
|
//===- Error.h --------------------------------------------------*- C++ -*-===//
|
2015-08-06 23:08:23 +08:00
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2016-09-29 09:26:48 +08:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//
|
2016-11-24 09:44:21 +08:00
|
|
|
// Error prints out an error message and increment a global variable
|
|
|
|
// ErrorCount to record the fact that we met an error condition. It does
|
2016-09-29 09:26:48 +08:00
|
|
|
// 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 errors in a single run.
|
|
|
|
//
|
|
|
|
// Warn doesn't do anything but printing out a given message.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2015-08-06 23:08:23 +08:00
|
|
|
|
2016-09-16 06:26:07 +08:00
|
|
|
#ifndef LLD_ELF_ERROR_H
|
|
|
|
#define LLD_ELF_ERROR_H
|
2015-08-06 23:08:23 +08:00
|
|
|
|
|
|
|
#include "lld/Core/LLVM.h"
|
|
|
|
|
2016-09-29 08:40:08 +08:00
|
|
|
#include "llvm/Support/Error.h"
|
|
|
|
|
2015-08-06 23:08:23 +08:00
|
|
|
namespace lld {
|
2016-02-28 08:25:54 +08:00
|
|
|
namespace elf {
|
2015-08-06 23:08:23 +08:00
|
|
|
|
2016-11-24 02:15:37 +08:00
|
|
|
extern uint64_t ErrorCount;
|
2016-02-03 06:49:32 +08:00
|
|
|
extern llvm::raw_ostream *ErrorOS;
|
2016-10-20 04:05:43 +08:00
|
|
|
extern llvm::StringRef Argv0;
|
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.
In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.
This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.
In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.
I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.
http://reviews.llvm.org/D16641
llvm-svn: 259069
2016-01-29 02:40:06 +08:00
|
|
|
|
2016-02-26 02:56:01 +08:00
|
|
|
void log(const Twine &Msg);
|
2016-09-30 05:00:23 +08:00
|
|
|
void warn(const Twine &Msg);
|
2015-09-25 02:55:33 +08:00
|
|
|
|
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.
In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.
This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.
In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.
I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.
http://reviews.llvm.org/D16641
llvm-svn: 259069
2016-01-29 02:40:06 +08:00
|
|
|
void error(const Twine &Msg);
|
2016-03-13 12:25:41 +08:00
|
|
|
void error(std::error_code EC, const Twine &Prefix);
|
2015-08-06 23:08:23 +08:00
|
|
|
|
2016-10-27 21:32:32 +08:00
|
|
|
LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
|
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.
In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.
This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.
In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.
I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.
http://reviews.llvm.org/D16641
llvm-svn: 259069
2016-01-29 02:40:06 +08:00
|
|
|
LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
|
2016-10-07 16:51:57 +08:00
|
|
|
LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
|
2016-03-13 12:25:43 +08:00
|
|
|
|
2016-11-17 02:54:37 +08:00
|
|
|
// check() functions are convenient functions to strip errors
|
|
|
|
// from error-or-value objects.
|
2016-07-15 10:01:03 +08:00
|
|
|
template <class T> T check(ErrorOr<T> E) {
|
|
|
|
if (auto EC = E.getError())
|
|
|
|
fatal(EC.message());
|
|
|
|
return std::move(*E);
|
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.
In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.
This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.
In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.
I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.
http://reviews.llvm.org/D16641
llvm-svn: 259069
2016-01-29 02:40:06 +08:00
|
|
|
}
|
2016-02-03 05:13:09 +08:00
|
|
|
|
2016-07-15 10:01:03 +08:00
|
|
|
template <class T> T check(Expected<T> E) {
|
2016-11-17 02:54:37 +08:00
|
|
|
if (!E)
|
|
|
|
handleAllErrors(std::move(E.takeError()),
|
|
|
|
[](llvm::ErrorInfoBase &EIB) -> Error {
|
|
|
|
fatal(EIB.message());
|
|
|
|
return Error::success();
|
|
|
|
});
|
|
|
|
return std::move(*E);
|
2016-04-21 05:24:51 +08:00
|
|
|
}
|
|
|
|
|
2016-07-15 10:01:03 +08:00
|
|
|
template <class T> T check(ErrorOr<T> E, const Twine &Prefix) {
|
|
|
|
if (auto EC = E.getError())
|
2016-10-07 04:04:54 +08:00
|
|
|
fatal(Prefix + ": " + EC.message());
|
2016-07-15 10:01:03 +08:00
|
|
|
return std::move(*E);
|
2016-03-04 00:21:44 +08:00
|
|
|
}
|
ELF: Rename error -> fatal and redefine error as a non-noreturn function.
In many situations, we don't want to exit at the first error even in the
process model. For example, it is better to report all undefined symbols
rather than reporting the first one that the linker picked up randomly.
In order to handle such errors, we don't need to wrap everything with
ErrorOr (thanks for David Blaikie for pointing this out!) Instead, we
can set a flag to record the fact that we found an error and keep it
going until it reaches a reasonable checkpoint.
This idea should be applicable to other places. For example, we can
ignore broken relocations and check for errors after visiting all relocs.
In this patch, I rename error to fatal, and introduce another version of
error which doesn't call exit. That function instead sets HasError to true.
Once HasError becomes true, it stays true, so that we know that there
was an error if it is true.
I think introducing a non-noreturn error reporting function is by itself
a good idea, and it looks to me that this also provides a gradual path
towards lld-as-a-library (or at least embed-lld-to-your-program) without
sacrificing code readability with lots of ErrorOr's.
http://reviews.llvm.org/D16641
llvm-svn: 259069
2016-01-29 02:40:06 +08:00
|
|
|
|
2016-07-15 10:01:03 +08:00
|
|
|
template <class T> T check(Expected<T> E, const Twine &Prefix) {
|
|
|
|
if (!E)
|
2016-10-07 04:04:54 +08:00
|
|
|
fatal(Prefix + ": " + errorToErrorCode(E.takeError()).message());
|
2016-07-15 10:01:03 +08:00
|
|
|
return std::move(*E);
|
2016-06-30 04:36:11 +08:00
|
|
|
}
|
|
|
|
|
2016-02-28 08:25:54 +08:00
|
|
|
} // namespace elf
|
2015-08-06 23:08:23 +08:00
|
|
|
} // namespace lld
|
|
|
|
|
|
|
|
#endif
|