1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[Object] Change Archive::child_iterator for better interop with Error/Expected.

See http://reviews.llvm.org/D22079

Changes the Archive::child_begin and Archive::children to require a reference
to an Error. If iterator increment fails (because the archive header is
damaged) the iterator will be set to 'end()', and the error stored in the
given Error&. The Error value should be checked by the user immediately after
the loop. E.g.:

Error Err;
for (auto &C : A->children(Err)) {
  // Do something with archive child C.
}
// Check the error immediately after the loop.
if (Err)
  return Err;

Failure to check the Error will result in an abort() when the Error goes out of
scope (as guaranteed by the Error class).

llvm-svn: 275316
This commit is contained in:
Lang Hames 2016-07-13 21:13:05 +00:00
parent 46cdf3f128
commit c4fb566fb8
15 changed files with 235 additions and 196 deletions

View File

@ -106,21 +106,20 @@ public:
};
class child_iterator {
ErrorOr<Child> child;
Child C;
Error *E;
public:
child_iterator() : child(Child(nullptr, nullptr, nullptr)) {}
child_iterator(const Child &c) : child(c) {}
child_iterator(std::error_code EC) : child(EC) {}
const ErrorOr<Child> *operator->() const { return &child; }
const ErrorOr<Child> &operator*() const { return child; }
child_iterator() : C(Child(nullptr, nullptr, nullptr)), E(nullptr) {}
child_iterator(const Child &C, Error *E) : C(C), E(E) {}
const Child *operator->() const { return &C; }
const Child &operator*() const { return C; }
bool operator==(const child_iterator &other) const {
// We ignore error states so that comparisions with end() work, which
// allows range loops.
if (child.getError() || other.child.getError())
return false;
return *child == *other.child;
// Ignore errors here: If an error occurred during increment then getNext
// will have been set to child_end(), and the following comparison should
// do the right thing.
return C == other.C;
}
bool operator!=(const child_iterator &other) const {
@ -130,8 +129,15 @@ public:
// Code in loops with child_iterators must check for errors on each loop
// iteration. And if there is an error break out of the loop.
child_iterator &operator++() { // Preincrement
assert(child && "Can't increment iterator with error");
child = child->getNext();
assert(E && "Can't increment iterator with no Error attached");
if (auto ChildOrErr = C.getNext())
C = *ChildOrErr;
else {
ErrorAsOutParameter ErrAsOutParam(*E);
C = C.getParent()->child_end().C;
*E = errorCodeToError(ChildOrErr.getError());
E = nullptr;
}
return *this;
}
};
@ -190,10 +196,11 @@ public:
Kind kind() const { return (Kind)Format; }
bool isThin() const { return IsThin; }
child_iterator child_begin(bool SkipInternal = true) const;
child_iterator child_begin(Error &Err, bool SkipInternal = true) const;
child_iterator child_end() const;
iterator_range<child_iterator> children(bool SkipInternal = true) const {
return make_range(child_begin(SkipInternal), child_end());
iterator_range<child_iterator> children(Error &Err,
bool SkipInternal = true) const {
return make_range(child_begin(Err, SkipInternal), child_end());
}
symbol_iterator symbol_begin() const;
@ -208,7 +215,7 @@ public:
}
// check if a symbol is in the archive
child_iterator findSym(StringRef name) const;
child_iterator findSym(Error &Err, StringRef name) const;
bool hasSymbolTable() const;
StringRef getSymbolTable() const { return SymbolTable; }

View File

@ -940,6 +940,11 @@ private:
std::function<int(const Error &)> GetExitCode;
};
/// Report a serious error, calling any installed error handler. See
/// ErrorHandling.h.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err,
bool gen_crash_diag = true);
} // namespace llvm
#endif // LLVM_SUPPORT_ERROR_H

View File

@ -327,13 +327,14 @@ RuntimeDyld::SymbolInfo MCJIT::findSymbol(const std::string &Name,
for (object::OwningBinary<object::Archive> &OB : Archives) {
object::Archive *A = OB.getBinary();
// Look for our symbols in each Archive
object::Archive::child_iterator ChildIt = A->findSym(Name);
if (std::error_code EC = ChildIt->getError())
report_fatal_error(EC.message());
Error Err;
object::Archive::child_iterator ChildIt = A->findSym(Err, Name);
if (Err)
report_fatal_error(std::move(Err));
if (ChildIt != A->child_end()) {
// FIXME: Support nested archives?
Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
(*ChildIt)->getAsBinary();
ChildIt->getAsBinary();
if (!ChildBinOrErr) {
// TODO: Actually report errors helpfully.
consumeError(ChildBinOrErr.takeError());

View File

@ -258,13 +258,14 @@ private:
for (object::OwningBinary<object::Archive> &OB : Archives) {
object::Archive *A = OB.getBinary();
// Look for our symbols in each Archive
object::Archive::child_iterator ChildIt = A->findSym(Name);
if (std::error_code EC = ChildIt->getError())
report_fatal_error(EC.message());
Error Err;
object::Archive::child_iterator ChildIt = A->findSym(Err, Name);
if (Err)
report_fatal_error(std::move(Err));
if (ChildIt != A->child_end()) {
// FIXME: Support nested archives?
Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
(*ChildIt)->getAsBinary();
ChildIt->getAsBinary();
if (!ChildBinOrErr) {
// TODO: Actually report errors helpfully.
consumeError(ChildBinOrErr.takeError());

View File

@ -298,12 +298,9 @@ Archive::Archive(MemoryBufferRef Source, Error &Err)
}
// Get the special members.
child_iterator I = child_begin(false);
std::error_code ec;
if ((ec = I->getError())) {
Err = errorCodeToError(ec);
child_iterator I = child_begin(Err, false);
if (Err)
return;
}
child_iterator E = child_end();
// This is at least a valid empty archive. Since an empty archive is the
@ -315,13 +312,13 @@ Archive::Archive(MemoryBufferRef Source, Error &Err)
Err = Error::success();
return;
}
const Child *C = &**I;
const Child *C = &*I;
auto Increment = [&]() {
++I;
if ((Err = errorCodeToError(I->getError())))
if (Err)
return true;
C = &**I;
C = &*I;
return false;
};
@ -366,8 +363,7 @@ Archive::Archive(MemoryBufferRef Source, Error &Err)
Format = K_BSD;
// We know this is BSD, so getName will work since there is no string table.
ErrorOr<StringRef> NameOrErr = C->getName();
ec = NameOrErr.getError();
if (ec) {
if (auto ec = NameOrErr.getError()) {
Err = errorCodeToError(ec);
return;
}
@ -465,23 +461,29 @@ Archive::Archive(MemoryBufferRef Source, Error &Err)
Err = Error::success();
}
Archive::child_iterator Archive::child_begin(bool SkipInternal) const {
Archive::child_iterator Archive::child_begin(Error &Err,
bool SkipInternal) const {
if (Data.getBufferSize() == 8) // empty archive.
return child_end();
if (SkipInternal)
return Child(this, FirstRegularData, FirstRegularStartOfFile);
return child_iterator(Child(this, FirstRegularData,
FirstRegularStartOfFile),
&Err);
const char *Loc = Data.getBufferStart() + strlen(Magic);
std::error_code EC;
Child c(this, Loc, &EC);
if (EC)
return child_iterator(EC);
return child_iterator(c);
Child C(this, Loc, &EC);
if (EC) {
ErrorAsOutParameter ErrAsOutParam(Err);
Err = errorCodeToError(EC);
return child_end();
}
return child_iterator(C, &Err);
}
Archive::child_iterator Archive::child_end() const {
return Child(this, nullptr, nullptr);
return child_iterator(Child(this, nullptr, nullptr), nullptr);
}
StringRef Archive::Symbol::getName() const {
@ -665,18 +667,20 @@ uint32_t Archive::getNumberOfSymbols() const {
return read32le(buf);
}
Archive::child_iterator Archive::findSym(StringRef name) const {
Archive::child_iterator Archive::findSym(Error &Err, StringRef name) const {
Archive::symbol_iterator bs = symbol_begin();
Archive::symbol_iterator es = symbol_end();
for (; bs != es; ++bs) {
StringRef SymName = bs->getName();
if (SymName == name) {
ErrorOr<Archive::child_iterator> ResultOrErr = bs->getMember();
// FIXME: Should we really eat the error?
if (ResultOrErr.getError())
if (auto MemberOrErr = bs->getMember()) {
return child_iterator(*MemberOrErr, &Err);
} else {
ErrorAsOutParameter ErrAsOutParam(Err);
Err = errorCodeToError(MemberOrErr.getError());
return child_end();
return ResultOrErr.get();
}
}
}
return child_end();

View File

@ -64,6 +64,7 @@ void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner) {
});
}
std::error_code ErrorList::convertToErrorCode() const {
return std::error_code(static_cast<int>(ErrorErrorCode::MultipleErrors),
*ErrorErrorCat);
@ -99,4 +100,14 @@ std::error_code StringError::convertToErrorCode() const {
return EC;
}
void report_fatal_error(Error Err, bool GenCrashDiag) {
assert(Err && "report_fatal_error called with success value");
std::string ErrMsg;
{
raw_string_ostream ErrStream(ErrMsg);
logAllUnhandledErrors(std::move(Err), ErrStream, "");
}
report_fatal_error(ErrMsg);
}
}

View File

@ -102,10 +102,8 @@ BinaryHolder::GetArchiveMemberBuffers(StringRef Filename,
Buffers.reserve(CurrentArchives.size());
for (const auto &CurrentArchive : CurrentArchives) {
for (auto ChildOrErr : CurrentArchive->children()) {
if (std::error_code Err = ChildOrErr.getError())
return Err;
const auto &Child = *ChildOrErr;
Error Err;
for (auto Child : CurrentArchive->children(Err)) {
if (auto NameOrErr = Child.getName()) {
if (*NameOrErr == Filename) {
if (Timestamp != sys::TimeValue::PosixZeroTime() &&
@ -123,6 +121,8 @@ BinaryHolder::GetArchiveMemberBuffers(StringRef Filename,
}
}
}
if (Err)
return errorToErrorCode(std::move(Err));
}
if (Buffers.empty())

View File

@ -405,35 +405,37 @@ static void performReadOperation(ArchiveOperation Operation,
fail("extracting from a thin archive is not supported");
bool Filter = !Members.empty();
for (auto &ChildOrErr : OldArchive->children()) {
failIfError(ChildOrErr.getError());
const object::Archive::Child &C = *ChildOrErr;
{
Error Err;
for (auto &C : OldArchive->children(Err)) {
ErrorOr<StringRef> NameOrErr = C.getName();
failIfError(NameOrErr.getError());
StringRef Name = NameOrErr.get();
ErrorOr<StringRef> NameOrErr = C.getName();
failIfError(NameOrErr.getError());
StringRef Name = NameOrErr.get();
if (Filter) {
auto I = std::find(Members.begin(), Members.end(), Name);
if (I == Members.end())
continue;
Members.erase(I);
}
if (Filter) {
auto I = std::find(Members.begin(), Members.end(), Name);
if (I == Members.end())
continue;
Members.erase(I);
}
switch (Operation) {
default:
llvm_unreachable("Not a read operation");
case Print:
doPrint(Name, C);
break;
case DisplayTable:
doDisplayTable(Name, C);
break;
case Extract:
doExtract(Name, C);
break;
switch (Operation) {
default:
llvm_unreachable("Not a read operation");
case Print:
doPrint(Name, C);
break;
case DisplayTable:
doDisplayTable(Name, C);
break;
case Extract:
doExtract(Name, C);
break;
}
}
failIfError(std::move(Err));
}
if (Members.empty())
return;
for (StringRef Name : Members)
@ -531,9 +533,8 @@ computeNewArchiveMembers(ArchiveOperation Operation,
int InsertPos = -1;
StringRef PosName = sys::path::filename(RelPos);
if (OldArchive) {
for (auto &ChildOrErr : OldArchive->children()) {
failIfError(ChildOrErr.getError());
auto &Child = ChildOrErr.get();
Error Err;
for (auto &Child : OldArchive->children(Err)) {
int Pos = Ret.size();
ErrorOr<StringRef> NameOrErr = Child.getName();
failIfError(NameOrErr.getError());
@ -568,6 +569,7 @@ computeNewArchiveMembers(ArchiveOperation Operation,
if (MemberI != Members.end())
Members.erase(MemberI);
}
failIfError(std::move(Err));
}
if (Operation == Delete)
@ -764,9 +766,11 @@ static void runMRIScript() {
"Could not parse library");
Archives.push_back(std::move(*LibOrErr));
object::Archive &Lib = *Archives.back();
for (auto &MemberOrErr : Lib.children()) {
failIfError(MemberOrErr.getError());
addMember(NewMembers, *MemberOrErr);
{
Error Err;
for (auto &Member : Lib.children(Err))
addMember(NewMembers, Member);
failIfError(std::move(Err));
}
break;
}

View File

@ -50,6 +50,14 @@ static void error(std::error_code EC) {
exit(1);
}
static void error(Error Err) {
if (Err) {
logAllUnhandledErrors(std::move(Err), outs(), "Error reading file: ");
outs().flush();
exit(1);
}
}
} // namespace llvm
static void reportError(StringRef Input, StringRef Message) {
@ -482,9 +490,8 @@ static void dumpCXXData(const ObjectFile *Obj) {
}
static void dumpArchive(const Archive *Arc) {
for (auto &ErrorOrChild : Arc->children()) {
error(ErrorOrChild.getError());
const Archive::Child &ArcC = *ErrorOrChild;
Error Err;
for (auto &ArcC : Arc->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = ArcC.getAsBinary();
if (!ChildOrErr) {
// Ignore non-object files.
@ -504,6 +511,7 @@ static void dumpArchive(const Archive *Arc) {
else
reportError(Arc->getFileName(), cxxdump_error::unrecognized_file_format);
}
error(std::move(Err));
}
static void dumpInput(StringRef File) {

View File

@ -1109,30 +1109,31 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
}
}
for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
I != E; ++I) {
if (error(I->getError()))
return;
auto &C = I->get();
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
error(std::move(E), Filename, C);
continue;
}
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
if (!checkMachOAndArchFlags(O, Filename))
return;
if (!PrintFileName) {
outs() << "\n";
if (isa<MachOObjectFile>(O)) {
outs() << Filename << "(" << O->getFileName() << ")";
} else
outs() << O->getFileName();
outs() << ":\n";
{
Error Err;
for (auto &C : A->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
error(std::move(E), Filename, C);
continue;
}
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
if (!checkMachOAndArchFlags(O, Filename))
return;
if (!PrintFileName) {
outs() << "\n";
if (isa<MachOObjectFile>(O)) {
outs() << Filename << "(" << O->getFileName() << ")";
} else
outs() << O->getFileName();
outs() << ":\n";
}
dumpSymbolNamesFromObject(*O, false, Filename);
}
dumpSymbolNamesFromObject(*O, false, Filename);
}
if (Err)
error(std::move(Err), A->getFileName());
}
return;
}
@ -1174,12 +1175,8 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
if (error(AI->getError()))
return;
auto &C = AI->get();
Error Err;
for (auto &C : A->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr =
C.getAsBinary(&Context);
if (!ChildOrErr) {
@ -1209,6 +1206,8 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
ArchitectureName);
}
}
if (Err)
error(std::move(Err), A->getFileName());
} else {
consumeError(AOrErr.takeError());
error(Filename + " for architecture " +
@ -1247,12 +1246,8 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
if (error(AI->getError()))
return;
auto &C = AI->get();
Error Err;
for (auto &C : A->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr =
C.getAsBinary(&Context);
if (!ChildOrErr) {
@ -1272,6 +1267,8 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
dumpSymbolNamesFromObject(*O, false, ArchiveName);
}
}
if (Err)
error(std::move(Err), A->getFileName());
} else {
consumeError(AOrErr.takeError());
error(Filename + " for architecture " +
@ -1316,11 +1313,8 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
} else if (Expected<std::unique_ptr<Archive>> AOrErr =
I->getAsArchive()) {
std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
AI != AE; ++AI) {
if (error(AI->getError()))
return;
auto &C = AI->get();
Error Err;
for (auto &C : A->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr =
C.getAsBinary(&Context);
if (!ChildOrErr) {
@ -1349,6 +1343,8 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName);
}
}
if (Err)
error(std::move(Err), A->getFileName());
} else {
consumeError(AOrErr.takeError());
error(Filename + " for architecture " +

View File

@ -1535,13 +1535,11 @@ static void printArchiveChild(const Archive::Child &C, bool verbose,
}
static void printArchiveHeaders(Archive *A, bool verbose, bool print_offset) {
for (Archive::child_iterator I = A->child_begin(false), E = A->child_end();
I != E; ++I) {
if (std::error_code EC = I->getError())
report_fatal_error(EC.message());
const Archive::Child &C = **I;
Error Err;
for (const auto &C : A->children(Err, false))
printArchiveChild(C, verbose, print_offset);
}
if (Err)
report_fatal_error(std::move(Err));
}
// ParseInputMachO() parses the named Mach-O file in Filename and handles the
@ -1572,11 +1570,8 @@ void llvm::ParseInputMachO(StringRef Filename) {
outs() << "Archive : " << Filename << "\n";
if (ArchiveHeaders)
printArchiveHeaders(A, !NonVerbose, ArchiveMemberOffsets);
for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
I != E; ++I) {
if (std::error_code EC = I->getError())
report_error(Filename, EC);
auto &C = I->get();
Error Err;
for (auto &C : A->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
@ -1589,6 +1584,8 @@ void llvm::ParseInputMachO(StringRef Filename) {
ProcessMachO(Filename, O, O->getFileName());
}
}
if (Err)
report_error(Filename, std::move(Err));
return;
}
if (UniversalHeaders) {
@ -1630,12 +1627,8 @@ void llvm::ParseInputMachO(StringRef Filename) {
outs() << "\n";
if (ArchiveHeaders)
printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
if (std::error_code EC = AI->getError())
report_error(Filename, EC);
auto &C = AI->get();
Error Err;
for (auto &C : A->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
@ -1646,6 +1639,8 @@ void llvm::ParseInputMachO(StringRef Filename) {
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
ProcessMachO(Filename, O, O->getFileName(), ArchitectureName);
}
if (Err)
report_error(Filename, std::move(Err));
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + Filename + " for " +
@ -1687,12 +1682,8 @@ void llvm::ParseInputMachO(StringRef Filename) {
outs() << "Archive : " << Filename << "\n";
if (ArchiveHeaders)
printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
if (std::error_code EC = AI->getError())
report_error(Filename, EC);
auto &C = AI->get();
Error Err;
for (auto &C : A->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
@ -1703,6 +1694,8 @@ void llvm::ParseInputMachO(StringRef Filename) {
dyn_cast<MachOObjectFile>(&*ChildOrErr.get()))
ProcessMachO(Filename, O, O->getFileName());
}
if (Err)
report_error(Filename, std::move(Err));
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + Filename + " for architecture " +
@ -1740,11 +1733,8 @@ void llvm::ParseInputMachO(StringRef Filename) {
outs() << "\n";
if (ArchiveHeaders)
printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
AI != AE; ++AI) {
if (std::error_code EC = AI->getError())
report_error(Filename, EC);
auto &C = AI->get();
Error Err;
for (auto &C : A->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
@ -1758,6 +1748,8 @@ void llvm::ParseInputMachO(StringRef Filename) {
ArchitectureName);
}
}
if (Err)
report_error(Filename, std::move(Err));
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + Filename + " for architecture " +

View File

@ -1702,10 +1702,8 @@ static void DumpObject(const ObjectFile *o, const Archive *a = nullptr) {
/// @brief Dump each object file in \a a;
static void DumpArchive(const Archive *a) {
for (auto &ErrorOrChild : a->children()) {
if (std::error_code EC = ErrorOrChild.getError())
report_error(a->getFileName(), EC);
const Archive::Child &C = *ErrorOrChild;
Error Err;
for (auto &C : a->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
@ -1717,6 +1715,8 @@ static void DumpArchive(const Archive *a) {
else
report_error(a->getFileName(), object_error::invalid_file_type);
}
if (Err)
report_error(a->getFileName(), std::move(Err));
}
/// @brief Open file and figure out how to dump it.

View File

@ -295,6 +295,17 @@ static void reportError(StringRef Input, StringRef Message) {
reportError(Twine(Input) + ": " + Message);
}
static void reportError(StringRef Input, Error Err) {
if (Input == "-")
Input = "<stdin>";
std::string ErrMsg;
{
raw_string_ostream ErrStream(ErrMsg);
logAllUnhandledErrors(std::move(Err), ErrStream, Input + ": ");
}
reportError(ErrMsg);
}
static bool isMipsArch(unsigned Arch) {
switch (Arch) {
case llvm::Triple::mips:
@ -424,10 +435,8 @@ static void dumpObject(const ObjectFile *Obj) {
/// @brief Dumps each object file in \a Arc;
static void dumpArchive(const Archive *Arc) {
for (auto &ErrorOrChild : Arc->children()) {
if (std::error_code EC = ErrorOrChild.getError())
reportError(Arc->getFileName(), EC.message());
const auto &Child = *ErrorOrChild;
Error Err;
for (auto &Child : Arc->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) {
@ -444,6 +453,8 @@ static void dumpArchive(const Archive *Arc) {
else
reportError(Arc->getFileName(), readobj_error::unrecognized_file_format);
}
if (Err)
reportError(Arc->getFileName(), std::move(Err));
}
/// @brief Dumps each object file in \a MachO Universal Binary;

View File

@ -527,15 +527,12 @@ static void printFileSectionSizes(StringRef file) {
if (Archive *a = dyn_cast<Archive>(&Bin)) {
// This is an archive. Iterate over each member and display its sizes.
for (object::Archive::child_iterator i = a->child_begin(),
e = a->child_end();
i != e; ++i) {
if (error(i->getError()))
exit(1);
Expected<std::unique_ptr<Binary>> ChildOrErr = i->get().getAsBinary();
Error Err;
for (auto &C : a->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
error(std::move(E), a->getFileName(), i->get());
error(std::move(E), a->getFileName(), C);
continue;
}
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
@ -555,6 +552,8 @@ static void printFileSectionSizes(StringRef file) {
}
}
}
if (Err)
error(std::move(Err), a->getFileName());
} else if (MachOUniversalBinary *UB =
dyn_cast<MachOUniversalBinary>(&Bin)) {
// If we have a list of architecture flags specified dump only those.
@ -597,17 +596,13 @@ static void printFileSectionSizes(StringRef file) {
std::unique_ptr<Archive> &UA = *AOrErr;
// This is an archive. Iterate over each member and display its
// sizes.
for (object::Archive::child_iterator i = UA->child_begin(),
e = UA->child_end();
i != e; ++i) {
if (error(i->getError()))
exit(1);
Expected<std::unique_ptr<Binary>> ChildOrErr =
i->get().getAsBinary();
Error Err;
for (auto &C : UA->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(
ChildOrErr.takeError()))
error(std::move(E), UA->getFileName(), i->get(),
error(std::move(E), UA->getFileName(), C,
ArchFlags.size() > 1 ?
StringRef(I->getArchTypeName()) : StringRef());
continue;
@ -637,6 +632,8 @@ static void printFileSectionSizes(StringRef file) {
}
}
}
if (Err)
error(std::move(Err), UA->getFileName());
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + file + " for architecture " +
@ -688,17 +685,13 @@ static void printFileSectionSizes(StringRef file) {
std::unique_ptr<Archive> &UA = *AOrErr;
// This is an archive. Iterate over each member and display its
// sizes.
for (object::Archive::child_iterator i = UA->child_begin(),
e = UA->child_end();
i != e; ++i) {
if (error(i->getError()))
exit(1);
Expected<std::unique_ptr<Binary>> ChildOrErr =
i->get().getAsBinary();
Error Err;
for (auto &C : UA->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(
ChildOrErr.takeError()))
error(std::move(E), UA->getFileName(), i->get());
error(std::move(E), UA->getFileName(), C);
continue;
}
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
@ -721,6 +714,8 @@ static void printFileSectionSizes(StringRef file) {
}
}
}
if (Err)
error(std::move(Err), UA->getFileName());
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + file + " for architecture " +
@ -765,16 +760,13 @@ static void printFileSectionSizes(StringRef file) {
I->getAsArchive()) {
std::unique_ptr<Archive> &UA = *AOrErr;
// This is an archive. Iterate over each member and display its sizes.
for (object::Archive::child_iterator i = UA->child_begin(),
e = UA->child_end();
i != e; ++i) {
if (error(i->getError()))
exit(1);
Expected<std::unique_ptr<Binary>> ChildOrErr = i->get().getAsBinary();
Error Err;
for (auto &C : UA->children(Err)) {
Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (!ChildOrErr) {
if (auto E = isNotObjectErrorInvalidFileType(
ChildOrErr.takeError()))
error(std::move(E), UA->getFileName(), i->get(), MoreThanOneArch ?
error(std::move(E), UA->getFileName(), C, MoreThanOneArch ?
StringRef(I->getArchTypeName()) : StringRef());
continue;
}
@ -798,6 +790,8 @@ static void printFileSectionSizes(StringRef file) {
}
}
}
if (Err)
error(std::move(Err), UA->getFileName());
} else {
consumeError(AOrErr.takeError());
error("Mach-O universal file: " + file + " for architecture " +

View File

@ -135,10 +135,15 @@ template <typename T> static void FailIfError(const ErrorOr<T> &E) {
FailIfError(E.getError());
}
static void FailIfError(Error Err) {
if (Err) {
logAllUnhandledErrors(std::move(Err), errs(), "Error: ");
exit(1);
}
}
template <typename T> static void FailIfError(Expected<T> &E) {
if (E)
return;
logAllUnhandledErrors(E.takeError(), errs(), "Error: ");
FailIfError(E.takeError());
}
static void FailIfNotEmpty(const llvm::Twine &E) {
@ -417,9 +422,8 @@ static void getObjectCoveragePoints(const object::ObjectFile &O,
static void
visitObjectFiles(const object::Archive &A,
function_ref<void(const object::ObjectFile &)> Fn) {
for (auto &ErrorOrChild : A.children()) {
FailIfError(ErrorOrChild);
const object::Archive::Child &C = *ErrorOrChild;
Error Err;
for (auto &C : A.children(Err)) {
Expected<std::unique_ptr<object::Binary>> ChildOrErr = C.getAsBinary();
FailIfError(errorToErrorCode(ChildOrErr.takeError()));
if (auto *O = dyn_cast<object::ObjectFile>(&*ChildOrErr.get()))
@ -427,6 +431,7 @@ visitObjectFiles(const object::Archive &A,
else
FailIfError(object::object_error::invalid_file_type);
}
FailIfError(std::move(Err));
}
static void