mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[Support] Make ErrorAsOutParameter take an Error* rather than an Error&.
This allows ErrorAsOutParameter to work better with "optional" errors. For example, consider a function where for certain input values it is known that the function can't fail. This can now be written as: Result foo(Arg X, Error *Err) { ErrorAsOutParameter EAO(Err); if (<Error Condition>) { if (Err) *Err = <report error>; else llvm_unreachable("Unexpected failure!"); } } Rather than having to construct an ErrorAsOutParameter under every conditional where Err is known to be non-null. llvm-svn: 276430
This commit is contained in:
parent
c5dafe9b5a
commit
3bf43acb9a
@ -688,7 +688,7 @@ public:
|
||||
|
||||
private:
|
||||
OrcRemoteTargetClient(ChannelT &Channel, Error &Err) : Channel(Channel) {
|
||||
ErrorAsOutParameter EAO(Err);
|
||||
ErrorAsOutParameter EAO(&Err);
|
||||
if (auto RIOrErr = callST<GetRemoteInfo>(Channel)) {
|
||||
std::tie(RemoteTargetTriple, RemotePointerSize, RemotePageSize,
|
||||
RemoteTrampolineSize, RemoteIndirectStubSize) = *RIOrErr;
|
||||
|
@ -131,10 +131,10 @@ public:
|
||||
// iteration. And if there is an error break out of the loop.
|
||||
child_iterator &operator++() { // Preincrement
|
||||
assert(E && "Can't increment iterator with no Error attached");
|
||||
ErrorAsOutParameter ErrAsOutParam(E);
|
||||
if (auto ChildOrErr = C.getNext())
|
||||
C = *ChildOrErr;
|
||||
else {
|
||||
ErrorAsOutParameter ErrAsOutParam(*E);
|
||||
C = C.getParent()->child_end().C;
|
||||
*E = ChildOrErr.takeError();
|
||||
E = nullptr;
|
||||
|
@ -571,24 +571,32 @@ inline void consumeError(Error Err) {
|
||||
/// RAII:
|
||||
///
|
||||
/// Result foo(Error &Err) {
|
||||
/// ErrorAsOutParameter ErrAsOutParam(Err); // 'Checked' flag set
|
||||
/// ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set
|
||||
/// // <body of foo>
|
||||
/// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
|
||||
/// }
|
||||
///
|
||||
/// ErrorAsOutParameter takes an Error* rather than Error& so that it can be
|
||||
/// used with optional Errors (Error pointers that are allowed to be null). If
|
||||
/// ErrorAsOutParameter took an Error reference, an instance would have to be
|
||||
/// created inside every condition that verified that Error was non-null. By
|
||||
/// taking an Error pointer we can just create one instance at the top of the
|
||||
/// function.
|
||||
class ErrorAsOutParameter {
|
||||
public:
|
||||
ErrorAsOutParameter(Error &Err) : Err(Err) {
|
||||
ErrorAsOutParameter(Error *Err) : Err(Err) {
|
||||
// Raise the checked bit if Err is success.
|
||||
(void)!!Err;
|
||||
if (Err)
|
||||
(void)!!*Err;
|
||||
}
|
||||
~ErrorAsOutParameter() {
|
||||
// Clear the checked bit.
|
||||
if (!Err)
|
||||
Err = Error::success();
|
||||
if (Err && !*Err)
|
||||
*Err = Error::success();
|
||||
}
|
||||
|
||||
private:
|
||||
Error &Err;
|
||||
Error *Err;
|
||||
};
|
||||
|
||||
/// Tagged union holding either a T or a Error.
|
||||
|
@ -108,16 +108,15 @@ Archive::Child::Child(const Archive *Parent, const char *Start, Error *Err)
|
||||
: Parent(Parent) {
|
||||
if (!Start)
|
||||
return;
|
||||
ErrorAsOutParameter ErrAsOutParam(Err);
|
||||
|
||||
uint64_t Size = sizeof(ArchiveMemberHeader);
|
||||
Data = StringRef(Start, Size);
|
||||
if (!isThinMember()) {
|
||||
Expected<uint64_t> MemberSize = getRawSize();
|
||||
if (!MemberSize) {
|
||||
if (Err) {
|
||||
ErrorAsOutParameter ErrAsOutParam(*Err);
|
||||
if (Err)
|
||||
*Err = MemberSize.takeError();
|
||||
}
|
||||
return;
|
||||
}
|
||||
Size += MemberSize.get();
|
||||
@ -299,7 +298,7 @@ void Archive::setFirstRegular(const Child &C) {
|
||||
|
||||
Archive::Archive(MemoryBufferRef Source, Error &Err)
|
||||
: Binary(Binary::ID_Archive, Source) {
|
||||
ErrorAsOutParameter ErrAsOutParam(Err);
|
||||
ErrorAsOutParameter ErrAsOutParam(&Err);
|
||||
StringRef Buffer = Data.getBuffer();
|
||||
// Check for sufficient magic.
|
||||
if (Buffer.startswith(ThinMagic)) {
|
||||
|
@ -267,7 +267,7 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
|
||||
DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
|
||||
DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
|
||||
HasPageZeroSegment(false) {
|
||||
ErrorAsOutParameter ErrAsOutParam(Err);
|
||||
ErrorAsOutParameter ErrAsOutParam(&Err);
|
||||
uint64_t BigSize;
|
||||
if (is64Bit()) {
|
||||
parseHeader(this, Header64, Err);
|
||||
|
@ -114,7 +114,7 @@ MachOUniversalBinary::create(MemoryBufferRef Source) {
|
||||
MachOUniversalBinary::MachOUniversalBinary(MemoryBufferRef Source, Error &Err)
|
||||
: Binary(Binary::ID_MachOUniversalBinary, Source), Magic(0),
|
||||
NumberOfObjects(0) {
|
||||
ErrorAsOutParameter ErrAsOutParam(Err);
|
||||
ErrorAsOutParameter ErrAsOutParam(&Err);
|
||||
if (Data.getBufferSize() < sizeof(MachO::fat_header)) {
|
||||
Err = make_error<GenericBinaryError>("File too small to be a Mach-O "
|
||||
"universal file",
|
||||
|
@ -109,7 +109,7 @@ TEST(Error, UncheckedSuccess) {
|
||||
|
||||
// ErrorAsOutParameter tester.
|
||||
void errAsOutParamHelper(Error &Err) {
|
||||
ErrorAsOutParameter ErrAsOutParam(Err);
|
||||
ErrorAsOutParameter ErrAsOutParam(&Err);
|
||||
// Verify that checked flag is raised - assignment should not crash.
|
||||
Err = Error::success();
|
||||
// Raise the checked bit manually - caller should still have to test the
|
||||
|
Loading…
x
Reference in New Issue
Block a user