[llvm] r270967 - Linker: teach the IR mover to return llvm::Error.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Thu May 26 22:21:36 PDT 2016


Author: pcc
Date: Fri May 27 00:21:35 2016
New Revision: 270967

URL: http://llvm.org/viewvc/llvm-project?rev=270967&view=rev
Log:
Linker: teach the IR mover to return llvm::Error.

This will be needed in order to consistently return an Error
to clients of the API being developed in D20268.

Differential Revision: http://reviews.llvm.org/D20550

Added:
    llvm/trunk/test/tools/gold/X86/Inputs/irmover-error.ll
    llvm/trunk/test/tools/gold/X86/irmover-error.ll
Modified:
    llvm/trunk/include/llvm/Linker/IRMover.h
    llvm/trunk/lib/Linker/IRMover.cpp
    llvm/trunk/lib/Linker/LinkModules.cpp
    llvm/trunk/lib/Support/Error.cpp
    llvm/trunk/test/Linker/module-flags-4-a.ll
    llvm/trunk/test/Linker/module-flags-4-b.ll
    llvm/trunk/tools/gold/gold-plugin.cpp

Modified: llvm/trunk/include/llvm/Linker/IRMover.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Linker/IRMover.h?rev=270967&r1=270966&r2=270967&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Linker/IRMover.h (original)
+++ llvm/trunk/include/llvm/Linker/IRMover.h Fri May 27 00:21:35 2016
@@ -15,6 +15,7 @@
 #include <functional>
 
 namespace llvm {
+class Error;
 class GlobalValue;
 class Metadata;
 class Module;
@@ -70,10 +71,8 @@ public:
   ///   not present in ValuesToLink. The GlobalValue and a ValueAdder callback
   ///   are passed as an argument, and the callback is expected to be called
   ///   if the GlobalValue needs to be added to the \p ValuesToLink and linked.
-  ///
-  /// Returns true on error.
-  bool move(std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
-            std::function<void(GlobalValue &GV, ValueAdder Add)> AddLazyFor);
+  Error move(std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
+             std::function<void(GlobalValue &GV, ValueAdder Add)> AddLazyFor);
   Module &getModule() { return Composite; }
 
 private:

Modified: llvm/trunk/lib/Linker/IRMover.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/IRMover.cpp?rev=270967&r1=270966&r2=270967&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/IRMover.cpp (original)
+++ llvm/trunk/lib/Linker/IRMover.cpp Fri May 27 00:21:35 2016
@@ -17,6 +17,7 @@
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/GVMaterializer.h"
 #include "llvm/IR/TypeFinder.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Transforms/Utils/Cloning.h"
 using namespace llvm;
 
@@ -399,7 +400,19 @@ class IRLinker {
   /// references.
   bool DoneLinkingBodies = false;
 
-  bool HasError = false;
+  /// The Error encountered during materialization. We use an Optional here to
+  /// avoid needing to manage an unconsumed success value.
+  Optional<Error> FoundError;
+  void setError(Error E) {
+    if (E)
+      FoundError = std::move(E);
+  }
+
+  /// Most of the errors produced by this module are inconvertible StringErrors.
+  /// This convenience function lets us return one of those more easily.
+  Error stringErr(const Twine &T) {
+    return make_error<StringError>(T, inconvertibleErrorCode());
+  }
 
   /// Entry point for mapping values and alternate context for mapping aliases.
   ValueMapper Mapper;
@@ -409,13 +422,6 @@ class IRLinker {
   /// the destination module, including setting the attributes and visibility.
   GlobalValue *copyGlobalValueProto(const GlobalValue *SGV, bool ForDefinition);
 
-  /// Helper method for setting a message and returning an error code.
-  bool emitError(const Twine &Message) {
-    SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message));
-    HasError = true;
-    return true;
-  }
-
   void emitWarning(const Twine &Message) {
     SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Warning, Message));
   }
@@ -444,8 +450,8 @@ class IRLinker {
 
   void computeTypeMapping();
 
-  Constant *linkAppendingVarProto(GlobalVariable *DstGV,
-                                  const GlobalVariable *SrcGV);
+  Expected<Constant *> linkAppendingVarProto(GlobalVariable *DstGV,
+                                             const GlobalVariable *SrcGV);
 
   /// Given the GlobaValue \p SGV in the source module, and the matching
   /// GlobalValue \p DGV (if any), return true if the linker will pull \p SGV
@@ -453,14 +459,14 @@ class IRLinker {
   ///
   /// Note this code may call the client-provided \p AddLazyFor.
   bool shouldLink(GlobalValue *DGV, GlobalValue &SGV);
-  Constant *linkGlobalValueProto(GlobalValue *GV, bool ForAlias);
+  Expected<Constant *> linkGlobalValueProto(GlobalValue *GV, bool ForAlias);
 
-  bool linkModuleFlagsMetadata();
+  Error linkModuleFlagsMetadata();
 
   void linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src);
-  bool linkFunctionBody(Function &Dst, Function &Src);
+  Error linkFunctionBody(Function &Dst, Function &Src);
   void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src);
-  bool linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src);
+  Error linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src);
 
   /// Functions that take care of cloning a specific global value type
   /// into the destination module.
@@ -487,7 +493,7 @@ public:
   }
   ~IRLinker() { SharedMDs = std::move(*ValueMap.getMDMap()); }
 
-  bool run();
+  Error run();
   Value *materialize(Value *V, bool ForAlias);
 };
 }
@@ -526,13 +532,17 @@ Value *IRLinker::materialize(Value *V, b
   if (!SGV)
     return nullptr;
 
-  Constant *NewProto = linkGlobalValueProto(SGV, ForAlias);
-  if (!NewProto)
-    return NewProto;
+  Expected<Constant *> NewProto = linkGlobalValueProto(SGV, ForAlias);
+  if (!NewProto) {
+    setError(NewProto.takeError());
+    return nullptr;
+  }
+  if (!*NewProto)
+    return nullptr;
 
-  GlobalValue *New = dyn_cast<GlobalValue>(NewProto);
+  GlobalValue *New = dyn_cast<GlobalValue>(*NewProto);
   if (!New)
-    return NewProto;
+    return *NewProto;
 
   // If we already created the body, just return.
   if (auto *F = dyn_cast<Function>(New)) {
@@ -559,7 +569,7 @@ Value *IRLinker::materialize(Value *V, b
     return New;
 
   if (ForAlias || shouldLink(New, *SGV))
-    linkGlobalValueBody(*New, *SGV);
+    setError(linkGlobalValueBody(*New, *SGV));
 
   return New;
 }
@@ -727,9 +737,9 @@ static void getArrayElements(const Const
 }
 
 /// If there were any appending global variables, link them together now.
-/// Return true on error.
-Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
-                                          const GlobalVariable *SrcGV) {
+Expected<Constant *>
+IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
+                                const GlobalVariable *SrcGV) {
   Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getValueType()))
                     ->getElementType();
 
@@ -759,46 +769,33 @@ Constant *IRLinker::linkAppendingVarProt
     ArrayType *DstTy = cast<ArrayType>(DstGV->getValueType());
     DstNumElements = DstTy->getNumElements();
 
-    if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) {
-      emitError(
+    if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
+      return stringErr(
           "Linking globals named '" + SrcGV->getName() +
-          "': can only link appending global with another appending global!");
-      return nullptr;
-    }
+          "': can only link appending global with another appending "
+          "global!");
 
     // Check to see that they two arrays agree on type.
-    if (EltTy != DstTy->getElementType()) {
-      emitError("Appending variables with different element types!");
-      return nullptr;
-    }
-    if (DstGV->isConstant() != SrcGV->isConstant()) {
-      emitError("Appending variables linked with different const'ness!");
-      return nullptr;
-    }
+    if (EltTy != DstTy->getElementType())
+      return stringErr("Appending variables with different element types!");
+    if (DstGV->isConstant() != SrcGV->isConstant())
+      return stringErr("Appending variables linked with different const'ness!");
 
-    if (DstGV->getAlignment() != SrcGV->getAlignment()) {
-      emitError(
+    if (DstGV->getAlignment() != SrcGV->getAlignment())
+      return stringErr(
           "Appending variables with different alignment need to be linked!");
-      return nullptr;
-    }
 
-    if (DstGV->getVisibility() != SrcGV->getVisibility()) {
-      emitError(
+    if (DstGV->getVisibility() != SrcGV->getVisibility())
+      return stringErr(
           "Appending variables with different visibility need to be linked!");
-      return nullptr;
-    }
 
-    if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr()) {
-      emitError(
+    if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr())
+      return stringErr(
           "Appending variables with different unnamed_addr need to be linked!");
-      return nullptr;
-    }
 
-    if (DstGV->getSection() != SrcGV->getSection()) {
-      emitError(
+    if (DstGV->getSection() != SrcGV->getSection())
+      return stringErr(
           "Appending variables with different section name need to be linked!");
-      return nullptr;
-    }
   }
 
   SmallVector<Constant *, 16> SrcElements;
@@ -873,7 +870,8 @@ bool IRLinker::shouldLink(GlobalValue *D
   return LazilyAdded;
 }
 
-Constant *IRLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) {
+Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
+                                                    bool ForAlias) {
   GlobalValue *DGV = getLinkedToGlobal(SGV);
 
   bool ShouldLink = shouldLink(DGV, *SGV);
@@ -947,12 +945,12 @@ void IRLinker::linkGlobalInit(GlobalVari
 /// Copy the source function over into the dest function and fix up references
 /// to values. At this point we know that Dest is an external function, and
 /// that Src is not.
-bool IRLinker::linkFunctionBody(Function &Dst, Function &Src) {
+Error IRLinker::linkFunctionBody(Function &Dst, Function &Src) {
   assert(Dst.isDeclaration() && !Src.isDeclaration());
 
   // Materialize if needed.
   if (std::error_code EC = Src.materialize())
-    return emitError(EC.message());
+    return errorCodeToError(EC);
 
   // Link in the operands without remapping.
   if (Src.hasPrefixData())
@@ -974,22 +972,22 @@ bool IRLinker::linkFunctionBody(Function
 
   // Everything has been moved over.  Remap it.
   Mapper.scheduleRemapFunction(Dst);
-  return false;
+  return Error::success();
 }
 
 void IRLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) {
   Mapper.scheduleMapGlobalAliasee(Dst, *Src.getAliasee(), AliasMCID);
 }
 
-bool IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
+Error IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
   if (auto *F = dyn_cast<Function>(&Src))
     return linkFunctionBody(cast<Function>(Dst), *F);
   if (auto *GVar = dyn_cast<GlobalVariable>(&Src)) {
     linkGlobalInit(cast<GlobalVariable>(Dst), *GVar);
-    return false;
+    return Error::success();
   }
   linkAliasBody(cast<GlobalAlias>(Dst), cast<GlobalAlias>(Src));
-  return false;
+  return Error::success();
 }
 
 /// Insert all of the named MDNodes in Src into the Dest module.
@@ -1007,11 +1005,11 @@ void IRLinker::linkNamedMDNodes() {
 }
 
 /// Merge the linker flags in Src into the Dest module.
-bool IRLinker::linkModuleFlagsMetadata() {
+Error IRLinker::linkModuleFlagsMetadata() {
   // If the source module has no module flags, we are done.
   const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata();
   if (!SrcModFlags)
-    return false;
+    return Error::success();
 
   // If the destination module doesn't have module flags yet, then just copy
   // over the source module's flags.
@@ -1020,7 +1018,7 @@ bool IRLinker::linkModuleFlagsMetadata()
     for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I)
       DstModFlags->addOperand(SrcModFlags->getOperand(I));
 
-    return false;
+    return Error::success();
   }
 
   // First build a map of the existing module flags and requirements.
@@ -1076,10 +1074,9 @@ bool IRLinker::linkModuleFlagsMetadata()
     if (DstBehaviorValue == Module::Override) {
       // Diagnose inconsistent flags which both have override behavior.
       if (SrcBehaviorValue == Module::Override &&
-          SrcOp->getOperand(2) != DstOp->getOperand(2)) {
-        emitError("linking module flags '" + ID->getString() +
-                  "': IDs have conflicting override values");
-      }
+          SrcOp->getOperand(2) != DstOp->getOperand(2))
+        return stringErr("linking module flags '" + ID->getString() +
+                         "': IDs have conflicting override values");
       continue;
     } else if (SrcBehaviorValue == Module::Override) {
       // Update the destination flag to that of the source.
@@ -1089,11 +1086,9 @@ bool IRLinker::linkModuleFlagsMetadata()
     }
 
     // Diagnose inconsistent merge behavior types.
-    if (SrcBehaviorValue != DstBehaviorValue) {
-      emitError("linking module flags '" + ID->getString() +
-                "': IDs have conflicting behaviors");
-      continue;
-    }
+    if (SrcBehaviorValue != DstBehaviorValue)
+      return stringErr("linking module flags '" + ID->getString() +
+                       "': IDs have conflicting behaviors");
 
     auto replaceDstValue = [&](MDNode *New) {
       Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New};
@@ -1109,10 +1104,9 @@ bool IRLinker::linkModuleFlagsMetadata()
       llvm_unreachable("not possible");
     case Module::Error: {
       // Emit an error if the values differ.
-      if (SrcOp->getOperand(2) != DstOp->getOperand(2)) {
-        emitError("linking module flags '" + ID->getString() +
-                  "': IDs have conflicting values");
-      }
+      if (SrcOp->getOperand(2) != DstOp->getOperand(2))
+        return stringErr("linking module flags '" + ID->getString() +
+                         "': IDs have conflicting values");
       continue;
     }
     case Module::Warning: {
@@ -1155,14 +1149,11 @@ bool IRLinker::linkModuleFlagsMetadata()
     Metadata *ReqValue = Requirement->getOperand(1);
 
     MDNode *Op = Flags[Flag].first;
-    if (!Op || Op->getOperand(2) != ReqValue) {
-      emitError("linking module flags '" + Flag->getString() +
-                "': does not have the required value");
-      continue;
-    }
+    if (!Op || Op->getOperand(2) != ReqValue)
+      return stringErr("linking module flags '" + Flag->getString() +
+                       "': does not have the required value");
   }
-
-  return HasError;
+  return Error::success();
 }
 
 // This function returns true if the triples match.
@@ -1186,10 +1177,11 @@ static std::string mergeTriples(const Tr
   return DstTriple.str();
 }
 
-bool IRLinker::run() {
+Error IRLinker::run() {
   // Ensure metadata materialized before value mapping.
-  if (SrcM->getMaterializer() && SrcM->getMaterializer()->materializeMetadata())
-      return true;
+  if (SrcM->getMaterializer())
+    if (std::error_code EC = SrcM->getMaterializer()->materializeMetadata())
+      return errorCodeToError(EC);
 
   // Inherit the target data from the source module if the destination module
   // doesn't have one already.
@@ -1243,8 +1235,8 @@ bool IRLinker::run() {
 
     assert(!GV->isDeclaration());
     Mapper.mapValue(*GV);
-    if (HasError)
-      return true;
+    if (FoundError)
+      return std::move(*FoundError);
   }
 
   // Note that we are done linking global value bodies. This prevents
@@ -1258,10 +1250,7 @@ bool IRLinker::run() {
   linkNamedMDNodes();
 
   // Merge the module flags into the DstM module.
-  if (linkModuleFlagsMetadata())
-    return true;
-
-  return false;
+  return linkModuleFlagsMetadata();
 }
 
 IRMover::StructTypeKeyInfo::KeyTy::KeyTy(ArrayRef<Type *> E, bool P)
@@ -1365,12 +1354,12 @@ IRMover::IRMover(Module &M) : Composite(
   }
 }
 
-bool IRMover::move(
+Error IRMover::move(
     std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
     std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor) {
   IRLinker TheIRLinker(Composite, SharedMDs, IdentifiedStructTypes,
                        std::move(Src), ValuesToLink, AddLazyFor);
-  bool RetCode = TheIRLinker.run();
+  Error E = TheIRLinker.run();
   Composite.dropTriviallyDeadConstantArrays();
-  return RetCode;
+  return E;
 }

Modified: llvm/trunk/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=270967&r1=270966&r2=270967&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Fri May 27 00:21:35 2016
@@ -18,6 +18,7 @@
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/Linker/Linker.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
 using namespace llvm;
 
@@ -574,11 +575,21 @@ bool ModuleLinker::run() {
       Internalize.insert(GV->getName());
   }
 
-  if (Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(),
-                 [this](GlobalValue &GV, IRMover::ValueAdder Add) {
-                   addLazyFor(GV, Add);
-                 }))
+  // FIXME: Propagate Errors through to the caller instead of emitting
+  // diagnostics.
+  bool HasErrors = false;
+  if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(),
+                           [this](GlobalValue &GV, IRMover::ValueAdder Add) {
+                             addLazyFor(GV, Add);
+                           })) {
+    handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
+      DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message()));
+      HasErrors = true;
+    });
+  }
+  if (HasErrors)
     return true;
+
   for (auto &P : Internalize) {
     GlobalValue *GV = DstM.getNamedValue(P.first());
     GV->setLinkage(GlobalValue::InternalLinkage);

Modified: llvm/trunk/lib/Support/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Error.cpp?rev=270967&r1=270966&r2=270967&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Error.cpp (original)
+++ llvm/trunk/lib/Support/Error.cpp Fri May 27 00:21:35 2016
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/Error.h"
-
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"

Modified: llvm/trunk/test/Linker/module-flags-4-a.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/module-flags-4-a.ll?rev=270967&r1=270966&r2=270967&view=diff
==============================================================================
--- llvm/trunk/test/Linker/module-flags-4-a.ll (original)
+++ llvm/trunk/test/Linker/module-flags-4-a.ll Fri May 27 00:21:35 2016
@@ -5,6 +5,6 @@
 ; CHECK: linking module flags 'bar': does not have the required value
 
 !0 = !{ i32 1, !"foo", i32 37 }
-!1 = !{ i32 1, !"bar", i32 927 }
+!1 = !{ i32 4, !"bar", i32 927 }
 
 !llvm.module.flags = !{ !0, !1 }

Modified: llvm/trunk/test/Linker/module-flags-4-b.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/module-flags-4-b.ll?rev=270967&r1=270966&r2=270967&view=diff
==============================================================================
--- llvm/trunk/test/Linker/module-flags-4-b.ll (original)
+++ llvm/trunk/test/Linker/module-flags-4-b.ll Fri May 27 00:21:35 2016
@@ -2,6 +2,6 @@
 ; RUN: true
 
 !0 = !{i32 3, !"foo", !{!"bar", i32 42}}
-!1 = !{i32 2, !"bar", i32 42}
+!1 = !{i32 1, !"bar", i32 42}
 
 !llvm.module.flags = !{ !0, !1 }

Added: llvm/trunk/test/tools/gold/X86/Inputs/irmover-error.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/gold/X86/Inputs/irmover-error.ll?rev=270967&view=auto
==============================================================================
--- llvm/trunk/test/tools/gold/X86/Inputs/irmover-error.ll (added)
+++ llvm/trunk/test/tools/gold/X86/Inputs/irmover-error.ll Fri May 27 00:21:35 2016
@@ -0,0 +1,3 @@
+!0 = !{ i32 1, !"foo", i32 2 }
+
+!llvm.module.flags = !{ !0 }

Added: llvm/trunk/test/tools/gold/X86/irmover-error.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/gold/X86/irmover-error.ll?rev=270967&view=auto
==============================================================================
--- llvm/trunk/test/tools/gold/X86/irmover-error.ll (added)
+++ llvm/trunk/test/tools/gold/X86/irmover-error.ll Fri May 27 00:21:35 2016
@@ -0,0 +1,9 @@
+; RUN: llvm-as -o %t1.bc %s
+; RUN: llvm-as -o %t2.bc %S/Inputs/irmover-error.ll
+; RUN: not %gold -plugin %llvmshlibdir/LLVMgold.so -o %t %t1.bc %t2.bc 2>&1 | FileCheck %s
+
+; CHECK: fatal error: Failed to link module {{.*}}2.bc: linking module flags 'foo': IDs have conflicting values
+
+!0 = !{ i32 1, !"foo", i32 1 }
+
+!llvm.module.flags = !{ !0 }

Modified: llvm/trunk/tools/gold/gold-plugin.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=270967&r1=270966&r2=270967&view=diff
==============================================================================
--- llvm/trunk/tools/gold/gold-plugin.cpp (original)
+++ llvm/trunk/tools/gold/gold-plugin.cpp Fri May 27 00:21:35 2016
@@ -1131,8 +1131,8 @@ void CodeGen::runAll() {
 }
 
 /// Links the module in \p View from file \p F into the combined module
-/// saved in the IRMover \p L. Returns true on error, false on success.
-static bool linkInModule(LLVMContext &Context, IRMover &L, claimed_file &F,
+/// saved in the IRMover \p L.
+static void linkInModule(LLVMContext &Context, IRMover &L, claimed_file &F,
                          const void *View, StringRef Name,
                          raw_fd_ostream *ApiFile, StringSet<> &Internalize,
                          StringSet<> &Maybe) {
@@ -1141,15 +1141,20 @@ static bool linkInModule(LLVMContext &Co
   std::unique_ptr<Module> M = getModuleForFile(
       Context, F, View, Name, ApiFile, Internalize, Maybe, Keep, Realign);
   if (!M.get())
-    return false;
+    return;
   if (!options::triple.empty())
     M->setTargetTriple(options::triple.c_str());
   else if (M->getTargetTriple().empty()) {
     M->setTargetTriple(DefaultTriple);
   }
 
-  if (L.move(std::move(M), Keep, [](GlobalValue &, IRMover::ValueAdder) {}))
-    return true;
+  if (Error E = L.move(std::move(M), Keep,
+                       [](GlobalValue &, IRMover::ValueAdder) {})) {
+    handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
+      message(LDPL_FATAL, "Failed to link module %s: %s", Name.str().c_str(),
+              EIB.message().c_str());
+    });
+  }
 
   for (const auto &I : Realign) {
     GlobalValue *Dst = L.getModule().getNamedValue(I.first());
@@ -1157,8 +1162,6 @@ static bool linkInModule(LLVMContext &Co
       continue;
     cast<GlobalVariable>(Dst)->setAlignment(I.second);
   }
-
-  return false;
 }
 
 /// Perform the ThinLTO backend on a single module, invoking the LTO and codegen
@@ -1179,8 +1182,7 @@ static void thinLTOBackendTask(claimed_f
   IRMover L(*NewModule.get());
 
   StringSet<> Dummy;
-  if (linkInModule(Context, L, F, View, Name, ApiFile, Dummy, Dummy))
-    message(LDPL_FATAL, "Failed to rename module for ThinLTO");
+  linkInModule(Context, L, F, View, Name, ApiFile, Dummy, Dummy);
   if (renameModuleForThinLTO(*NewModule, CombinedIndex))
     message(LDPL_FATAL, "Failed to rename module for ThinLTO");
 
@@ -1420,8 +1422,7 @@ static ld_plugin_status allSymbolsReadHo
     const void *View = getSymbolsAndView(F);
     if (!View)
       continue;
-    if (linkInModule(Context, L, F, View, F.name, ApiFile, Internalize, Maybe))
-      message(LDPL_FATAL, "Failed to link module");
+    linkInModule(Context, L, F, View, F.name, ApiFile, Internalize, Maybe);
   }
 
   for (const auto &Name : Internalize) {




More information about the llvm-commits mailing list