sdmitriev created this revision.
sdmitriev added a reviewer: ABataev.
Herald added a reviewer: alexshap.
Herald added a reviewer: jdoerfert.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D67031

Files:
  clang/test/Driver/clang-offload-bundler.c
  clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp

Index: clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
===================================================================
--- clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
+++ clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
@@ -25,23 +25,17 @@
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/StringSaver.h"
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <system_error>
-#include <vector>
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 using namespace llvm::object;
@@ -98,6 +92,9 @@
 /// Path to the current binary.
 static std::string BundlerExecutable;
 
+/// Saved argv[0].
+static StringRef Argv0;
+
 /// Obtain the offload kind and real machine triple out of the target
 /// information specified by the user.
 static void getOffloadKindAndTriple(StringRef Target, StringRef &OffloadKind,
@@ -113,6 +110,15 @@
   return OffloadKind == "host";
 }
 
+/// Error reporting functions.
+static void reportError(Error E) {
+  logAllUnhandledErrors(std::move(E), WithColor::error(errs(), Argv0));
+}
+
+static void reportFileError(StringRef File, std::error_code EC) {
+  reportError(createFileError(File, EC));
+}
+
 /// Generic file handler interface.
 class FileHandler {
 public:
@@ -146,7 +152,6 @@
 
   /// Write the marker that closes a bundle for the triple \a TargetTriple to \a
   /// OS. Return true if any error was found.
-
   virtual bool WriteBundleEnd(raw_fd_ostream &OS, StringRef TargetTriple) = 0;
 
   /// Write the bundle from \a Input into \a OS.
@@ -327,7 +332,7 @@
 
     unsigned Idx = 0;
     for (auto &T : TargetNames) {
-      MemoryBuffer &MB = *Inputs[Idx++].get();
+      MemoryBuffer &MB = *Inputs[Idx++];
       // Bundle offset.
       Write8byteIntegerToBuffer(OS, HeaderSize);
       // Size of the bundle (adds to the next bundle's offset)
@@ -467,7 +472,8 @@
     ErrorOr<std::string> Objcopy = sys::findProgramByName(
         "llvm-objcopy", sys::path::parent_path(BundlerExecutable));
     if (!Objcopy) {
-      errs() << "error: unable to find 'llvm-objcopy' in path.\n";
+      reportError(createStringError(Objcopy.getError(),
+                                    "unable to find 'llvm-objcopy' in path."));
       return true;
     }
 
@@ -489,13 +495,14 @@
     // If the user asked for the commands to be printed out, we do that instead
     // of executing it.
     if (PrintExternalCommands) {
-      errs() << "\"" << Objcopy.get() << "\"";
+      errs() << "\"" << *Objcopy << "\"";
       for (StringRef Arg : drop_begin(ObjcopyArgs, 1))
         errs() << " \"" << Arg << "\"";
       errs() << "\n";
     } else {
-      if (sys::ExecuteAndWait(Objcopy.get(), ObjcopyArgs)) {
-        errs() << "error: llvm-objcopy tool failed.\n";
+      if (sys::ExecuteAndWait(*Objcopy, ObjcopyArgs)) {
+        reportError(createStringError(inconvertibleErrorCode(),
+                                      "'llvm-objcopy' tool failed."));
         return true;
       }
     }
@@ -622,13 +629,11 @@
   // We only support regular object files. If this is not an object file,
   // default to the binary handler. The handler will be owned by the client of
   // this function.
-  std::unique_ptr<ObjectFile> Obj(
-      dyn_cast<ObjectFile>(BinaryOrErr.get().release()));
-
-  if (!Obj)
-    return new BinaryFileHandler();
-
-  return new ObjectFileHandler(std::move(Obj));
+  if (auto *Obj = dyn_cast<ObjectFile>(BinaryOrErr->get())) {
+      BinaryOrErr->release();
+      return new ObjectFileHandler(std::unique_ptr<ObjectFile>(Obj));
+  }
+  return new BinaryFileHandler();
 }
 
 /// Return an appropriate handler given the input files and options.
@@ -650,7 +655,10 @@
   if (FilesType == "ast")
     return new BinaryFileHandler();
 
-  errs() << "error: invalid file type specified.\n";
+  reportError(
+      createStringError(errc::invalid_argument,
+                        "'" + FilesType + "': invalid file type specified."));
+
   return nullptr;
 }
 
@@ -662,7 +670,7 @@
   raw_fd_ostream OutputFile(OutputFileNames.front(), EC, sys::fs::OF_None);
 
   if (EC) {
-    errs() << "error: Can't open file " << OutputFileNames.front() << ".\n";
+    reportFileError(OutputFileNames.front(), EC);
     return true;
   }
 
@@ -675,31 +683,31 @@
     ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
         MemoryBuffer::getFileOrSTDIN(I);
     if (std::error_code EC = CodeOrErr.getError()) {
-      errs() << "error: Can't open file " << I << ": " << EC.message() << "\n";
+      reportFileError(I, EC);
       return true;
     }
-    InputBuffers[Idx++] = std::move(CodeOrErr.get());
+    InputBuffers[Idx++] = std::move(*CodeOrErr);
   }
 
   // Get the file handler. We use the host buffer as reference.
   assert(HostInputIndex != ~0u && "Host input index undefined??");
   std::unique_ptr<FileHandler> FH;
-  FH.reset(CreateFileHandler(*InputBuffers[HostInputIndex].get()));
+  FH.reset(CreateFileHandler(*InputBuffers[HostInputIndex]));
 
   // Quit if we don't have a handler.
-  if (!FH.get())
+  if (!FH)
     return true;
 
   // Write header.
-  FH.get()->WriteHeader(OutputFile, InputBuffers);
+  FH->WriteHeader(OutputFile, InputBuffers);
 
   // Write all bundles along with the start/end markers. If an error was found
   // writing the end of the bundle component, abort the bundle writing.
   auto Input = InputBuffers.begin();
   for (auto &Triple : TargetNames) {
-    FH.get()->WriteBundleStart(OutputFile, Triple);
-    FH.get()->WriteBundle(OutputFile, *Input->get());
-    if (FH.get()->WriteBundleEnd(OutputFile, Triple))
+    FH->WriteBundleStart(OutputFile, Triple);
+    FH->WriteBundle(OutputFile, **Input);
+    if (FH->WriteBundleEnd(OutputFile, Triple))
       return true;
     ++Input;
   }
@@ -712,23 +720,22 @@
   ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
       MemoryBuffer::getFileOrSTDIN(InputFileNames.front());
   if (std::error_code EC = CodeOrErr.getError()) {
-    errs() << "error: Can't open file " << InputFileNames.front() << ": "
-           << EC.message() << "\n";
+    reportFileError(InputFileNames.front(), EC);
     return true;
   }
 
-  MemoryBuffer &Input = *CodeOrErr.get();
+  MemoryBuffer &Input = **CodeOrErr;
 
   // Select the right files handler.
   std::unique_ptr<FileHandler> FH;
   FH.reset(CreateFileHandler(Input));
 
   // Quit if we don't have a handler.
-  if (!FH.get())
+  if (!FH)
     return true;
 
   // Read the header of the bundled file.
-  FH.get()->ReadHeader(Input);
+  FH->ReadHeader(Input);
 
   // Create a work list that consist of the map triple/output file.
   StringMap<StringRef> Worklist;
@@ -742,7 +749,7 @@
   // assume the file is meant for the host target.
   bool FoundHostBundle = false;
   while (!Worklist.empty()) {
-    StringRef CurTriple = FH.get()->ReadBundleStart(Input);
+    StringRef CurTriple = FH->ReadBundleStart(Input);
 
     // We don't have more bundles.
     if (CurTriple.empty())
@@ -759,12 +766,11 @@
     std::error_code EC;
     raw_fd_ostream OutputFile(Output->second, EC, sys::fs::OF_None);
     if (EC) {
-      errs() << "error: Can't open file " << Output->second << ": "
-             << EC.message() << "\n";
+      reportFileError(Output->second, EC);
       return true;
     }
-    FH.get()->ReadBundle(OutputFile, Input);
-    FH.get()->ReadBundleEnd(Input);
+    FH->ReadBundle(OutputFile, Input);
+    FH->ReadBundleEnd(Input);
     Worklist.erase(Output);
 
     // Record if we found the host bundle.
@@ -779,8 +785,7 @@
       std::error_code EC;
       raw_fd_ostream OutputFile(E.second, EC, sys::fs::OF_None);
       if (EC) {
-        errs() << "error: Can't open file " << E.second << ": " << EC.message()
-               << "\n";
+        reportFileError(E.second, EC);
         return true;
       }
 
@@ -794,7 +799,8 @@
   // If we found elements, we emit an error if none of those were for the host
   // in case host bundle name was provided in command line.
   if (!FoundHostBundle && HostInputIndex != ~0u) {
-    errs() << "error: Can't find bundle for the host target\n";
+    reportError(createStringError(inconvertibleErrorCode(),
+                                  "Can't find bundle for the host target."));
     return true;
   }
 
@@ -803,8 +809,7 @@
     std::error_code EC;
     raw_fd_ostream OutputFile(E.second, EC, sys::fs::OF_None);
     if (EC) {
-      errs() << "error: Can't open file " << E.second << ": "  << EC.message()
-             << "\n";
+      reportFileError(E.second, EC);
       return true;
     }
   }
@@ -817,6 +822,7 @@
 }
 
 int main(int argc, const char **argv) {
+  Argv0 = argv[0];
   sys::PrintStackTraceOnErrorSignal(argv[0]);
 
   cl::HideUnrelatedOptions(ClangOffloadBundlerCategory);
@@ -837,22 +843,28 @@
   if (Unbundle) {
     if (InputFileNames.size() != 1) {
       Error = true;
-      errs() << "error: only one input file supported in unbundling mode.\n";
+      reportError(createStringError(
+          errc::invalid_argument,
+          "only one input file supported in unbundling mode."));
     }
     if (OutputFileNames.size() != TargetNames.size()) {
       Error = true;
-      errs() << "error: number of output files and targets should match in "
-                "unbundling mode.\n";
+      reportError(createStringError(errc::invalid_argument,
+                                    "number of output files and targets should "
+                                    "match in unbundling mode."));
     }
   } else {
     if (OutputFileNames.size() != 1) {
       Error = true;
-      errs() << "error: only one output file supported in bundling mode.\n";
+      reportError(createStringError(
+          errc::invalid_argument,
+          "only one output file supported in bundling mode."));
     }
     if (InputFileNames.size() != TargetNames.size()) {
       Error = true;
-      errs() << "error: number of input files and targets should match in "
-                "bundling mode.\n";
+      reportError(createStringError(
+          errc::invalid_argument,
+          "number of input files and targets should match in bundling mode."));
     }
   }
 
@@ -878,13 +890,15 @@
 
     if (!KindIsValid || !TripleIsValid) {
       Error = true;
-      errs() << "error: invalid target '" << Target << "'";
 
+      SmallVector<char, 128u> Buf;
+      raw_svector_ostream Msg(Buf);
+      Msg << "invalid target '" << Target << "'";
       if (!KindIsValid)
-        errs() << ", unknown offloading kind '" << Kind << "'";
+        Msg << ", unknown offloading kind '" << Kind << "'";
       if (!TripleIsValid)
-        errs() << ", unknown target triple '" << Triple << "'";
-      errs() << ".\n";
+        Msg << ", unknown target triple '" << Triple << "'";
+      reportError(createStringError(errc::invalid_argument, Msg.str() + "."));
     }
 
     if (KindIsValid && Kind == "host") {
@@ -900,8 +914,9 @@
   // treat missing host triple as error if we do unbundling.
   if ((Unbundle && HostTargetNum > 1) || (!Unbundle && HostTargetNum != 1)) {
     Error = true;
-    errs() << "error: expecting exactly one host target but got "
-           << HostTargetNum << ".\n";
+    reportError(createStringError(errc::invalid_argument,
+                                  "expecting exactly one host target but got " +
+                                      Twine(HostTargetNum) + "."));
   }
 
   if (Error)
Index: clang/test/Driver/clang-offload-bundler.c
===================================================================
--- clang/test/Driver/clang-offload-bundler.c
+++ clang/test/Driver/clang-offload-bundler.c
@@ -68,12 +68,12 @@
 // RUN: not clang-offload-bundler -type=i -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.i,%t.tgt1 -inputs=%t.bundle.i -unbundle 2>&1 | FileCheck %s --check-prefix CK-ERR4
 // CK-ERR4: error: number of output files and targets should match in unbundling mode.
 
-// RUN: not clang-offload-bundler -type=i -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -inputs=%t.i,%t.tgt1,%t.tgt2.notexist -outputs=%t.bundle.i 2>&1 | FileCheck %s --check-prefix CK-ERR5
-// RUN: not clang-offload-bundler -type=i -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.i,%t.tgt1,%t.tgt2 -inputs=%t.bundle.i.notexist -unbundle 2>&1 | FileCheck %s --check-prefix CK-ERR5
-// CK-ERR5: error: Can't open file {{.+}}.notexist: {{N|n}}o such file or directory
+// RUN: not clang-offload-bundler -type=i -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -inputs=%t.i,%t.tgt1,%t.tgt2.notexist -outputs=%t.bundle.i 2>&1 | FileCheck %s -DFILE=%t.tgt2.notexist --check-prefix CK-ERR5
+// RUN: not clang-offload-bundler -type=i -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.i,%t.tgt1,%t.tgt2 -inputs=%t.bundle.i.notexist -unbundle 2>&1 | FileCheck %s -DFILE=%t.bundle.i.notexist --check-prefix CK-ERR5
+// CK-ERR5: error: '[[FILE]]': {{N|n}}o such file or directory
 
-// RUN: not clang-offload-bundler -type=invalid -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -inputs=%t.i,%t.tgt1,%t.tgt2 -outputs=%t.bundle.i 2>&1 | FileCheck %s --check-prefix CK-ERR6
-// CK-ERR6: error: invalid file type specified.
+// RUN: not clang-offload-bundler -type=invalid -targets=host-%itanium_abi_triple,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -inputs=%t.i,%t.tgt1,%t.tgt2 -outputs=%t.bundle.i 2>&1 | FileCheck %s -DTYPE=invalid --check-prefix CK-ERR6
+// CK-ERR6: error: '[[TYPE]]': invalid file type specified.
 
 // RUN: not clang-offload-bundler 2>&1 | FileCheck %s --check-prefix CK-ERR7
 // CK-ERR7-DAG: clang-offload-bundler: for the --type option: must be specified at least once!
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to