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

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 13 17:47:07 PDT 2016


Hi Vataly,

Reverted in r275353 while I write the corresponding LLD patch.

Thanks again for the heads up.

- Lang.


On Wed, Jul 13, 2016 at 5:29 PM, Vitaly Buka <vitalybuka at google.com> wrote:

> Thanks.
>
> On Wed, Jul 13, 2016 at 5:27 PM Lang Hames <lhames at gmail.com> wrote:
>
>> Hi Vitaly,
>>
>> Sorry about that - I'll take a look now and fix or revert as necessary.
>>
>> Cheers,
>> Lang.
>>
>> On Wed, Jul 13, 2016 at 5:06 PM, Vitaly Buka <vitalybuka at google.com>
>> wrote:
>>
>>> This patch is causing
>>> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/14630/steps/build%20clang%2Fmsan/logs/stdio
>>> Please let me know if you have a fix, or I'll have to revert it.
>>>
>>> On Wed, Jul 13, 2016 at 2:20 PM Lang Hames via llvm-commits <
>>> llvm-commits at lists.llvm.org> wrote:
>>>
>>>> Author: lhames
>>>> Date: Wed Jul 13 16:13:05 2016
>>>> New Revision: 275316
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=275316&view=rev
>>>> Log:
>>>> [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).
>>>>
>>>>
>>>> Modified:
>>>>     llvm/trunk/include/llvm/Object/Archive.h
>>>>     llvm/trunk/include/llvm/Support/Error.h
>>>>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>>>>     llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
>>>>     llvm/trunk/lib/Object/Archive.cpp
>>>>     llvm/trunk/lib/Support/Error.cpp
>>>>     llvm/trunk/tools/dsymutil/BinaryHolder.cpp
>>>>     llvm/trunk/tools/llvm-ar/llvm-ar.cpp
>>>>     llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp
>>>>     llvm/trunk/tools/llvm-nm/llvm-nm.cpp
>>>>     llvm/trunk/tools/llvm-objdump/MachODump.cpp
>>>>     llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
>>>>     llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
>>>>     llvm/trunk/tools/llvm-size/llvm-size.cpp
>>>>     llvm/trunk/tools/sancov/sancov.cc
>>>>
>>>> Modified: llvm/trunk/include/llvm/Object/Archive.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Archive.h?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/include/llvm/Object/Archive.h (original)
>>>> +++ llvm/trunk/include/llvm/Object/Archive.h Wed Jul 13 16:13:05 2016
>>>> @@ -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; }
>>>>
>>>> Modified: llvm/trunk/include/llvm/Support/Error.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Error.h?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/include/llvm/Support/Error.h (original)
>>>> +++ llvm/trunk/include/llvm/Support/Error.h Wed Jul 13 16:13:05 2016
>>>> @@ -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
>>>>
>>>> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)
>>>> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Wed Jul 13 16:13:05
>>>> 2016
>>>> @@ -327,13 +327,14 @@ RuntimeDyld::SymbolInfo MCJIT::findSymbo
>>>>    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());
>>>>
>>>> Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h (original)
>>>> +++ llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h Wed Jul 13
>>>> 16:13:05 2016
>>>> @@ -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());
>>>>
>>>> Modified: llvm/trunk/lib/Object/Archive.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Archive.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Object/Archive.cpp (original)
>>>> +++ llvm/trunk/lib/Object/Archive.cpp Wed Jul 13 16:13:05 2016
>>>> @@ -298,12 +298,9 @@ Archive::Archive(MemoryBufferRef Source,
>>>>    }
>>>>
>>>>    // 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,
>>>>      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,
>>>>      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,
>>>>    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() c
>>>>    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();
>>>>
>>>> Modified: llvm/trunk/lib/Support/Error.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Error.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Support/Error.cpp (original)
>>>> +++ llvm/trunk/lib/Support/Error.cpp Wed Jul 13 16:13:05 2016
>>>> @@ -64,6 +64,7 @@ void logAllUnhandledErrors(Error E, raw_
>>>>    });
>>>>  }
>>>>
>>>> +
>>>>  std::error_code ErrorList::convertToErrorCode() const {
>>>>    return
>>>> std::error_code(static_cast<int>(ErrorErrorCode::MultipleErrors),
>>>>                           *ErrorErrorCat);
>>>> @@ -99,4 +100,14 @@ std::error_code StringError::convertToEr
>>>>    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);
>>>> +}
>>>> +
>>>>  }
>>>>
>>>> Modified: llvm/trunk/tools/dsymutil/BinaryHolder.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/BinaryHolder.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/dsymutil/BinaryHolder.cpp (original)
>>>> +++ llvm/trunk/tools/dsymutil/BinaryHolder.cpp Wed Jul 13 16:13:05 2016
>>>> @@ -102,10 +102,8 @@ BinaryHolder::GetArchiveMemberBuffers(St
>>>>    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(St
>>>>          }
>>>>        }
>>>>      }
>>>> +    if (Err)
>>>> +      return errorToErrorCode(std::move(Err));
>>>>    }
>>>>
>>>>    if (Buffers.empty())
>>>>
>>>> Modified: llvm/trunk/tools/llvm-ar/llvm-ar.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ar/llvm-ar.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/llvm-ar/llvm-ar.cpp (original)
>>>> +++ llvm/trunk/tools/llvm-ar/llvm-ar.cpp Wed Jul 13 16:13:05 2016
>>>> @@ -405,35 +405,37 @@ static void performReadOperation(Archive
>>>>      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;
>>>> -
>>>> -    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);
>>>> -    }
>>>> +  {
>>>> +    Error Err;
>>>> +    for (auto &C : OldArchive->children(Err)) {
>>>> +      ErrorOr<StringRef> NameOrErr = C.getName();
>>>> +      failIfError(NameOrErr.getError());
>>>> +      StringRef Name = NameOrErr.get();
>>>>
>>>> -    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;
>>>> +      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;
>>>> +      }
>>>>      }
>>>> +    failIfError(std::move(Err));
>>>>    }
>>>> +
>>>>    if (Members.empty())
>>>>      return;
>>>>    for (StringRef Name : Members)
>>>> @@ -531,9 +533,8 @@ computeNewArchiveMembers(ArchiveOperatio
>>>>    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(ArchiveOperatio
>>>>        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;
>>>>      }
>>>>
>>>> Modified: llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp (original)
>>>> +++ llvm/trunk/tools/llvm-cxxdump/llvm-cxxdump.cpp Wed Jul 13 16:13:05
>>>> 2016
>>>> @@ -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
>>>>  }
>>>>
>>>>  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 *A
>>>>      else
>>>>        reportError(Arc->getFileName(),
>>>> cxxdump_error::unrecognized_file_format);
>>>>    }
>>>> +  error(std::move(Err));
>>>>  }
>>>>
>>>>  static void dumpInput(StringRef File) {
>>>>
>>>> Modified: llvm/trunk/tools/llvm-nm/llvm-nm.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/llvm-nm/llvm-nm.cpp (original)
>>>> +++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp Wed Jul 13 16:13:05 2016
>>>> @@ -1109,30 +1109,31 @@ static void dumpSymbolNamesFromFile(std:
>>>>        }
>>>>      }
>>>>
>>>> -    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:
>>>>              } 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:
>>>>                                              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:
>>>>            } 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:
>>>>                  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:
>>>>        } 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:
>>>>              dumpSymbolNamesFromObject(*O, false, ArchiveName,
>>>> ArchitectureName);
>>>>            }
>>>>          }
>>>> +        if (Err)
>>>> +          error(std::move(Err), A->getFileName());
>>>>        } else {
>>>>          consumeError(AOrErr.takeError());
>>>>          error(Filename + " for architecture " +
>>>>
>>>> Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
>>>> +++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Wed Jul 13 16:13:05 2016
>>>> @@ -1535,13 +1535,11 @@ static void printArchiveChild(const Arch
>>>>  }
>>>>
>>>>  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 Fil
>>>>      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 Fil
>>>>          ProcessMachO(Filename, O, O->getFileName());
>>>>        }
>>>>      }
>>>> +    if (Err)
>>>> +      report_error(Filename, std::move(Err));
>>>>      return;
>>>>    }
>>>>    if (UniversalHeaders) {
>>>> @@ -1630,12 +1627,8 @@ void llvm::ParseInputMachO(StringRef Fil
>>>>                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 Fil
>>>>                          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 Fil
>>>>              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 Fil
>>>>                        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 Fil
>>>>          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 Fil
>>>>                             ArchitectureName);
>>>>            }
>>>>          }
>>>> +        if (Err)
>>>> +          report_error(Filename, std::move(Err));
>>>>        } else {
>>>>          consumeError(AOrErr.takeError());
>>>>          error("Mach-O universal file: " + Filename + " for
>>>> architecture " +
>>>>
>>>> Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
>>>> +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Wed Jul 13 16:13:05
>>>> 2016
>>>> @@ -1702,10 +1702,8 @@ static void DumpObject(const ObjectFile
>>>>
>>>>  /// @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.
>>>>
>>>> Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
>>>> +++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Wed Jul 13 16:13:05
>>>> 2016
>>>> @@ -295,6 +295,17 @@ static void reportError(StringRef Input,
>>>>    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
>>>>
>>>>  /// @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 *A
>>>>      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;
>>>>
>>>> Modified: llvm/trunk/tools/llvm-size/llvm-size.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-size/llvm-size.cpp?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/llvm-size/llvm-size.cpp (original)
>>>> +++ llvm/trunk/tools/llvm-size/llvm-size.cpp Wed Jul 13 16:13:05 2016
>>>> @@ -527,15 +527,12 @@ static void printFileSectionSizes(String
>>>>
>>>>    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(String
>>>>          }
>>>>        }
>>>>      }
>>>> +    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(String
>>>>                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(String
>>>>                    }
>>>>                  }
>>>>                }
>>>> +              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(String
>>>>              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(String
>>>>                  }
>>>>                }
>>>>              }
>>>> +            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(String
>>>>                           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(String
>>>>              }
>>>>            }
>>>>          }
>>>> +        if (Err)
>>>> +          error(std::move(Err), UA->getFileName());
>>>>        } else {
>>>>          consumeError(AOrErr.takeError());
>>>>          error("Mach-O universal file: " + file + " for architecture " +
>>>>
>>>> Modified: llvm/trunk/tools/sancov/sancov.cc
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/sancov/sancov.cc?rev=275316&r1=275315&r2=275316&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/tools/sancov/sancov.cc (original)
>>>> +++ llvm/trunk/tools/sancov/sancov.cc Wed Jul 13 16:13:05 2016
>>>> @@ -135,10 +135,15 @@ template <typename T> static void FailIf
>>>>    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(cons
>>>>  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 &
>>>>      else
>>>>        FailIfError(object::object_error::invalid_file_type);
>>>>    }
>>>> +  FailIfError(std::move(Err));
>>>>  }
>>>>
>>>>  static void
>>>>
>>>>
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>>
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160713/86fa4ff4/attachment.html>


More information about the llvm-commits mailing list