[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 14:13:07 PDT 2016


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




More information about the llvm-commits mailing list