brintos

brintos / llvm-project-archived public Read only

0
0
Text · 22.4 KiB · 485ac10 Raw
656 lines · cpp
1//===- lib/Linker/LinkModules.cpp - Module Linker Implementation ----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the LLVM module linker.10//11//===----------------------------------------------------------------------===//12 13#include "LinkDiagnosticInfo.h"14#include "llvm-c/Linker.h"15#include "llvm/ADT/SetVector.h"16#include "llvm/IR/Comdat.h"17#include "llvm/IR/GlobalValue.h"18#include "llvm/IR/LLVMContext.h"19#include "llvm/IR/Module.h"20#include "llvm/Linker/Linker.h"21#include "llvm/Support/Error.h"22using namespace llvm;23 24namespace {25 26enum class LinkFrom { Dst, Src, Both };27 28/// This is an implementation class for the LinkModules function, which is the29/// entrypoint for this file.30class ModuleLinker {31  IRMover &Mover;32  std::unique_ptr<Module> SrcM;33 34  SetVector<GlobalValue *> ValuesToLink;35 36  /// For symbol clashes, prefer those from Src.37  unsigned Flags;38 39  /// List of global value names that should be internalized.40  StringSet<> Internalize;41 42  /// Function that will perform the actual internalization. The reason for a43  /// callback is that the linker cannot call internalizeModule without44  /// creating a circular dependency between IPO and the linker.45  std::function<void(Module &, const StringSet<> &)> InternalizeCallback;46 47  /// Used as the callback for lazy linking.48  /// The mover has just hit GV and we have to decide if it, and other members49  /// of the same comdat, should be linked. Every member to be linked is passed50  /// to Add.51  void addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add);52 53  bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; }54  bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; }55 56  bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest,57                            const GlobalValue &Src);58 59  /// Should we have mover and linker error diag info?60  bool emitError(const Twine &Message) {61    SrcM->getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message));62    return true;63  }64 65  bool getComdatLeader(Module &M, StringRef ComdatName,66                       const GlobalVariable *&GVar);67  bool computeResultingSelectionKind(StringRef ComdatName,68                                     Comdat::SelectionKind Src,69                                     Comdat::SelectionKind Dst,70                                     Comdat::SelectionKind &Result,71                                     LinkFrom &From);72  DenseMap<const Comdat *, std::pair<Comdat::SelectionKind, LinkFrom>>73      ComdatsChosen;74  bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK,75                       LinkFrom &From);76  // Keep track of the lazy linked global members of each comdat in source.77  DenseMap<const Comdat *, std::vector<GlobalValue *>> LazyComdatMembers;78 79  /// Given a global in the source module, return the global in the80  /// destination module that is being linked to, if any.81  GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) {82    Module &DstM = Mover.getModule();83    // If the source has no name it can't link.  If it has local linkage,84    // there is no name match-up going on.85    if (!SrcGV->hasName() || GlobalValue::isLocalLinkage(SrcGV->getLinkage()))86      return nullptr;87 88    // Otherwise see if we have a match in the destination module's symtab.89    GlobalValue *DGV = DstM.getNamedValue(SrcGV->getName());90    if (!DGV)91      return nullptr;92 93    // If we found a global with the same name in the dest module, but it has94    // internal linkage, we are really not doing any linkage here.95    if (DGV->hasLocalLinkage())96      return nullptr;97 98    // Otherwise, we do in fact link to the destination global.99    return DGV;100  }101 102  /// Drop GV if it is a member of a comdat that we are dropping.103  /// This can happen with COFF's largest selection kind.104  void dropReplacedComdat(GlobalValue &GV,105                          const DenseSet<const Comdat *> &ReplacedDstComdats);106 107  bool linkIfNeeded(GlobalValue &GV, SmallVectorImpl<GlobalValue *> &GVToClone);108 109public:110  ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags,111               std::function<void(Module &, const StringSet<> &)>112                   InternalizeCallback = {})113      : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags),114        InternalizeCallback(std::move(InternalizeCallback)) {}115 116  bool run();117};118} // namespace119 120static GlobalValue::VisibilityTypes121getMinVisibility(GlobalValue::VisibilityTypes A,122                 GlobalValue::VisibilityTypes B) {123  if (A == GlobalValue::HiddenVisibility || B == GlobalValue::HiddenVisibility)124    return GlobalValue::HiddenVisibility;125  if (A == GlobalValue::ProtectedVisibility ||126      B == GlobalValue::ProtectedVisibility)127    return GlobalValue::ProtectedVisibility;128  return GlobalValue::DefaultVisibility;129}130 131bool ModuleLinker::getComdatLeader(Module &M, StringRef ComdatName,132                                   const GlobalVariable *&GVar) {133  const GlobalValue *GVal = M.getNamedValue(ComdatName);134  if (const auto *GA = dyn_cast_or_null<GlobalAlias>(GVal)) {135    GVal = GA->getAliaseeObject();136    if (!GVal)137      // We cannot resolve the size of the aliasee yet.138      return emitError("Linking COMDATs named '" + ComdatName +139                       "': COMDAT key involves incomputable alias size.");140  }141 142  GVar = dyn_cast_or_null<GlobalVariable>(GVal);143  if (!GVar)144    return emitError(145        "Linking COMDATs named '" + ComdatName +146        "': GlobalVariable required for data dependent selection!");147 148  return false;149}150 151bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName,152                                                 Comdat::SelectionKind Src,153                                                 Comdat::SelectionKind Dst,154                                                 Comdat::SelectionKind &Result,155                                                 LinkFrom &From) {156  Module &DstM = Mover.getModule();157  // The ability to mix Comdat::SelectionKind::Any with158  // Comdat::SelectionKind::Largest is a behavior that comes from COFF.159  bool DstAnyOrLargest = Dst == Comdat::SelectionKind::Any ||160                         Dst == Comdat::SelectionKind::Largest;161  bool SrcAnyOrLargest = Src == Comdat::SelectionKind::Any ||162                         Src == Comdat::SelectionKind::Largest;163  if (DstAnyOrLargest && SrcAnyOrLargest) {164    if (Dst == Comdat::SelectionKind::Largest ||165        Src == Comdat::SelectionKind::Largest)166      Result = Comdat::SelectionKind::Largest;167    else168      Result = Comdat::SelectionKind::Any;169  } else if (Src == Dst) {170    Result = Dst;171  } else {172    return emitError("Linking COMDATs named '" + ComdatName +173                     "': invalid selection kinds!");174  }175 176  switch (Result) {177  case Comdat::SelectionKind::Any:178    // Go with Dst.179    From = LinkFrom::Dst;180    break;181  case Comdat::SelectionKind::NoDeduplicate:182    From = LinkFrom::Both;183    break;184  case Comdat::SelectionKind::ExactMatch:185  case Comdat::SelectionKind::Largest:186  case Comdat::SelectionKind::SameSize: {187    const GlobalVariable *DstGV;188    const GlobalVariable *SrcGV;189    if (getComdatLeader(DstM, ComdatName, DstGV) ||190        getComdatLeader(*SrcM, ComdatName, SrcGV))191      return true;192 193    const DataLayout &DstDL = DstM.getDataLayout();194    const DataLayout &SrcDL = SrcM->getDataLayout();195    uint64_t DstSize = DstDL.getTypeAllocSize(DstGV->getValueType());196    uint64_t SrcSize = SrcDL.getTypeAllocSize(SrcGV->getValueType());197    if (Result == Comdat::SelectionKind::ExactMatch) {198      if (SrcGV->getInitializer() != DstGV->getInitializer())199        return emitError("Linking COMDATs named '" + ComdatName +200                         "': ExactMatch violated!");201      From = LinkFrom::Dst;202    } else if (Result == Comdat::SelectionKind::Largest) {203      From = SrcSize > DstSize ? LinkFrom::Src : LinkFrom::Dst;204    } else if (Result == Comdat::SelectionKind::SameSize) {205      if (SrcSize != DstSize)206        return emitError("Linking COMDATs named '" + ComdatName +207                         "': SameSize violated!");208      From = LinkFrom::Dst;209    } else {210      llvm_unreachable("unknown selection kind");211    }212    break;213  }214  }215 216  return false;217}218 219bool ModuleLinker::getComdatResult(const Comdat *SrcC,220                                   Comdat::SelectionKind &Result,221                                   LinkFrom &From) {222  Module &DstM = Mover.getModule();223  Comdat::SelectionKind SSK = SrcC->getSelectionKind();224  StringRef ComdatName = SrcC->getName();225  Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable();226  Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(ComdatName);227 228  if (DstCI == ComdatSymTab.end()) {229    // Use the comdat if it is only available in one of the modules.230    From = LinkFrom::Src;231    Result = SSK;232    return false;233  }234 235  const Comdat *DstC = &DstCI->second;236  Comdat::SelectionKind DSK = DstC->getSelectionKind();237  return computeResultingSelectionKind(ComdatName, SSK, DSK, Result, From);238}239 240bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,241                                        const GlobalValue &Dest,242                                        const GlobalValue &Src) {243 244  // Should we unconditionally use the Src?245  if (shouldOverrideFromSrc()) {246    LinkFromSrc = true;247    return false;248  }249 250  // We always have to add Src if it has appending linkage.251  if (Src.hasAppendingLinkage() || Dest.hasAppendingLinkage()) {252    LinkFromSrc = true;253    return false;254  }255 256  bool SrcIsDeclaration = Src.isDeclarationForLinker();257  bool DestIsDeclaration = Dest.isDeclarationForLinker();258 259  if (SrcIsDeclaration) {260    // If Src is external or if both Src & Dest are external..  Just link the261    // external globals, we aren't adding anything.262    if (Src.hasDLLImportStorageClass()) {263      // If one of GVs is marked as DLLImport, result should be dllimport'ed.264      LinkFromSrc = DestIsDeclaration;265      return false;266    }267    // If the Dest is weak, use the source linkage.268    if (Dest.hasExternalWeakLinkage()) {269      LinkFromSrc = true;270      return false;271    }272    // Link an available_externally over a declaration.273    LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration();274    return false;275  }276 277  if (DestIsDeclaration) {278    // If Dest is external but Src is not:279    LinkFromSrc = true;280    return false;281  }282 283  if (Src.hasCommonLinkage()) {284    if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) {285      LinkFromSrc = true;286      return false;287    }288 289    if (!Dest.hasCommonLinkage()) {290      LinkFromSrc = false;291      return false;292    }293 294    const DataLayout &DL = Dest.getDataLayout();295    uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType());296    uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType());297    LinkFromSrc = SrcSize > DestSize;298    return false;299  }300 301  if (Src.isWeakForLinker()) {302    assert(!Dest.hasExternalWeakLinkage());303    assert(!Dest.hasAvailableExternallyLinkage());304 305    if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) {306      LinkFromSrc = true;307      return false;308    }309 310    LinkFromSrc = false;311    return false;312  }313 314  if (Dest.isWeakForLinker()) {315    assert(Src.hasExternalLinkage());316    LinkFromSrc = true;317    return false;318  }319 320  assert(!Src.hasExternalWeakLinkage());321  assert(!Dest.hasExternalWeakLinkage());322  assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() &&323         "Unexpected linkage type!");324  return emitError("Linking globals named '" + Src.getName() +325                   "': symbol multiply defined!");326}327 328bool ModuleLinker::linkIfNeeded(GlobalValue &GV,329                                SmallVectorImpl<GlobalValue *> &GVToClone) {330  GlobalValue *DGV = getLinkedToGlobal(&GV);331 332  if (shouldLinkOnlyNeeded()) {333    // Always import variables with appending linkage.334    if (!GV.hasAppendingLinkage()) {335      // Don't import globals unless they are referenced by the destination336      // module.337      if (!DGV)338        return false;339      // Don't import globals that are already defined in the destination module340      if (!DGV->isDeclaration())341        return false;342    }343  }344 345  if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) {346    auto *DGVar = dyn_cast<GlobalVariable>(DGV);347    auto *SGVar = dyn_cast<GlobalVariable>(&GV);348    if (DGVar && SGVar) {349      if (DGVar->isDeclaration() && SGVar->isDeclaration() &&350          (!DGVar->isConstant() || !SGVar->isConstant())) {351        DGVar->setConstant(false);352        SGVar->setConstant(false);353      }354      if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) {355        MaybeAlign DAlign = DGVar->getAlign();356        MaybeAlign SAlign = SGVar->getAlign();357        MaybeAlign Align = std::nullopt;358        if (DAlign || SAlign)359          Align = std::max(DAlign.valueOrOne(), SAlign.valueOrOne());360 361        SGVar->setAlignment(Align);362        DGVar->setAlignment(Align);363      }364    }365 366    GlobalValue::VisibilityTypes Visibility =367        getMinVisibility(DGV->getVisibility(), GV.getVisibility());368    DGV->setVisibility(Visibility);369    GV.setVisibility(Visibility);370 371    GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr(372        DGV->getUnnamedAddr(), GV.getUnnamedAddr());373    DGV->setUnnamedAddr(UnnamedAddr);374    GV.setUnnamedAddr(UnnamedAddr);375  }376 377  if (!DGV && !shouldOverrideFromSrc() &&378      (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() ||379       GV.hasAvailableExternallyLinkage()))380    return false;381 382  if (GV.isDeclaration())383    return false;384 385  LinkFrom ComdatFrom = LinkFrom::Dst;386  if (const Comdat *SC = GV.getComdat()) {387    std::tie(std::ignore, ComdatFrom) = ComdatsChosen[SC];388    if (ComdatFrom == LinkFrom::Dst)389      return false;390  }391 392  bool LinkFromSrc = true;393  if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV))394    return true;395  if (DGV && ComdatFrom == LinkFrom::Both)396    GVToClone.push_back(LinkFromSrc ? DGV : &GV);397  if (LinkFromSrc)398    ValuesToLink.insert(&GV);399  return false;400}401 402void ModuleLinker::addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add) {403  // Add these to the internalize list404  if (!GV.hasLinkOnceLinkage() && !GV.hasAvailableExternallyLinkage() &&405      !shouldLinkOnlyNeeded())406    return;407 408  if (InternalizeCallback)409    Internalize.insert(GV.getName());410  Add(GV);411 412  const Comdat *SC = GV.getComdat();413  if (!SC)414    return;415  for (GlobalValue *GV2 : LazyComdatMembers[SC]) {416    GlobalValue *DGV = getLinkedToGlobal(GV2);417    bool LinkFromSrc = true;418    if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2))419      return;420    if (!LinkFromSrc)421      continue;422    if (InternalizeCallback)423      Internalize.insert(GV2->getName());424    Add(*GV2);425  }426}427 428void ModuleLinker::dropReplacedComdat(429    GlobalValue &GV, const DenseSet<const Comdat *> &ReplacedDstComdats) {430  Comdat *C = GV.getComdat();431  if (!C)432    return;433  if (!ReplacedDstComdats.count(C))434    return;435  if (GV.use_empty()) {436    GV.eraseFromParent();437    return;438  }439 440  if (auto *F = dyn_cast<Function>(&GV)) {441    F->deleteBody();442  } else if (auto *Var = dyn_cast<GlobalVariable>(&GV)) {443    Var->setInitializer(nullptr);444  } else {445    auto &Alias = cast<GlobalAlias>(GV);446    Module &M = *Alias.getParent();447    GlobalValue *Declaration;448    if (auto *FTy = dyn_cast<FunctionType>(Alias.getValueType())) {449      Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, "", &M);450    } else {451      Declaration =452          new GlobalVariable(M, Alias.getValueType(), /*isConstant*/ false,453                             GlobalValue::ExternalLinkage,454                             /*Initializer*/ nullptr);455    }456    Declaration->takeName(&Alias);457    Alias.replaceAllUsesWith(Declaration);458    Alias.eraseFromParent();459  }460}461 462bool ModuleLinker::run() {463  Module &DstM = Mover.getModule();464  DenseSet<const Comdat *> ReplacedDstComdats;465  DenseSet<const Comdat *> NonPrevailingComdats;466 467  for (const auto &SMEC : SrcM->getComdatSymbolTable()) {468    const Comdat &C = SMEC.getValue();469    if (ComdatsChosen.count(&C))470      continue;471    Comdat::SelectionKind SK;472    LinkFrom From;473    if (getComdatResult(&C, SK, From))474      return true;475    ComdatsChosen[&C] = std::make_pair(SK, From);476 477    if (From == LinkFrom::Dst)478      NonPrevailingComdats.insert(&C);479 480    if (From != LinkFrom::Src)481      continue;482 483    Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable();484    Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(C.getName());485    if (DstCI == ComdatSymTab.end())486      continue;487 488    // The source comdat is replacing the dest one.489    const Comdat *DstC = &DstCI->second;490    ReplacedDstComdats.insert(DstC);491  }492 493  // Alias have to go first, since we are not able to find their comdats494  // otherwise.495  for (GlobalAlias &GV : llvm::make_early_inc_range(DstM.aliases()))496    dropReplacedComdat(GV, ReplacedDstComdats);497 498  for (GlobalVariable &GV : llvm::make_early_inc_range(DstM.globals()))499    dropReplacedComdat(GV, ReplacedDstComdats);500 501  for (Function &GV : llvm::make_early_inc_range(DstM))502    dropReplacedComdat(GV, ReplacedDstComdats);503 504  if (!NonPrevailingComdats.empty()) {505    DenseSet<GlobalObject *> AliasedGlobals;506    for (auto &GA : SrcM->aliases())507      if (GlobalObject *GO = GA.getAliaseeObject(); GO && GO->getComdat())508        AliasedGlobals.insert(GO);509    for (const Comdat *C : NonPrevailingComdats) {510      SmallVector<GlobalObject *> ToUpdate;511      for (GlobalObject *GO : C->getUsers())512        if (GO->hasPrivateLinkage() && !AliasedGlobals.contains(GO))513          ToUpdate.push_back(GO);514      for (GlobalObject *GO : ToUpdate) {515        GO->setLinkage(GlobalValue::AvailableExternallyLinkage);516        GO->setComdat(nullptr);517      }518    }519  }520 521  for (GlobalVariable &GV : SrcM->globals())522    if (GV.hasLinkOnceLinkage())523      if (const Comdat *SC = GV.getComdat())524        LazyComdatMembers[SC].push_back(&GV);525 526  for (Function &SF : *SrcM)527    if (SF.hasLinkOnceLinkage())528      if (const Comdat *SC = SF.getComdat())529        LazyComdatMembers[SC].push_back(&SF);530 531  for (GlobalAlias &GA : SrcM->aliases())532    if (GA.hasLinkOnceLinkage())533      if (const Comdat *SC = GA.getComdat())534        LazyComdatMembers[SC].push_back(&GA);535 536  // Insert all of the globals in src into the DstM module... without linking537  // initializers (which could refer to functions not yet mapped over).538  SmallVector<GlobalValue *, 0> GVToClone;539  for (GlobalVariable &GV : SrcM->globals())540    if (linkIfNeeded(GV, GVToClone))541      return true;542 543  for (Function &SF : *SrcM)544    if (linkIfNeeded(SF, GVToClone))545      return true;546 547  for (GlobalAlias &GA : SrcM->aliases())548    if (linkIfNeeded(GA, GVToClone))549      return true;550 551  for (GlobalIFunc &GI : SrcM->ifuncs())552    if (linkIfNeeded(GI, GVToClone))553      return true;554 555  // For a variable in a comdat nodeduplicate, its initializer should be556  // preserved (its content may be implicitly used by other members) even if557  // symbol resolution does not pick it. Clone it into an unnamed private558  // variable.559  for (GlobalValue *GV : GVToClone) {560    if (auto *Var = dyn_cast<GlobalVariable>(GV)) {561      auto *NewVar = new GlobalVariable(*Var->getParent(), Var->getValueType(),562                                        Var->isConstant(), Var->getLinkage(),563                                        Var->getInitializer());564      NewVar->copyAttributesFrom(Var);565      NewVar->setVisibility(GlobalValue::DefaultVisibility);566      NewVar->setLinkage(GlobalValue::PrivateLinkage);567      NewVar->setDSOLocal(true);568      NewVar->setComdat(Var->getComdat());569      if (Var->getParent() != &Mover.getModule())570        ValuesToLink.insert(NewVar);571    } else {572      emitError("linking '" + GV->getName() +573                "': non-variables in comdat nodeduplicate are not handled");574    }575  }576 577  for (unsigned I = 0; I < ValuesToLink.size(); ++I) {578    GlobalValue *GV = ValuesToLink[I];579    const Comdat *SC = GV->getComdat();580    if (!SC)581      continue;582    for (GlobalValue *GV2 : LazyComdatMembers[SC]) {583      GlobalValue *DGV = getLinkedToGlobal(GV2);584      bool LinkFromSrc = true;585      if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2))586        return true;587      if (LinkFromSrc)588        ValuesToLink.insert(GV2);589    }590  }591 592  if (InternalizeCallback) {593    for (GlobalValue *GV : ValuesToLink)594      Internalize.insert(GV->getName());595  }596 597  // FIXME: Propagate Errors through to the caller instead of emitting598  // diagnostics.599  bool HasErrors = false;600  if (Error E =601          Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(),602                     IRMover::LazyCallback(603                         [this](GlobalValue &GV, IRMover::ValueAdder Add) {604                           addLazyFor(GV, Add);605                         }),606                     /* IsPerformingImport */ false)) {607    handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {608      DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message()));609      HasErrors = true;610    });611  }612  if (HasErrors)613    return true;614 615  if (InternalizeCallback)616    InternalizeCallback(DstM, Internalize);617 618  return false;619}620 621Linker::Linker(Module &M) : Mover(M) {}622 623bool Linker::linkInModule(624    std::unique_ptr<Module> Src, unsigned Flags,625    std::function<void(Module &, const StringSet<> &)> InternalizeCallback) {626  ModuleLinker ModLinker(Mover, std::move(Src), Flags,627                         std::move(InternalizeCallback));628  return ModLinker.run();629}630 631//===----------------------------------------------------------------------===//632// LinkModules entrypoint.633//===----------------------------------------------------------------------===//634 635/// This function links two modules together, with the resulting Dest module636/// modified to be the composite of the two input modules. If an error occurs,637/// true is returned and ErrorMsg (if not null) is set to indicate the problem.638/// Upon failure, the Dest module could be in a modified state, and shouldn't be639/// relied on to be consistent.640bool Linker::linkModules(641    Module &Dest, std::unique_ptr<Module> Src, unsigned Flags,642    std::function<void(Module &, const StringSet<> &)> InternalizeCallback) {643  Linker L(Dest);644  return L.linkInModule(std::move(Src), Flags, std::move(InternalizeCallback));645}646 647//===----------------------------------------------------------------------===//648// C API.649//===----------------------------------------------------------------------===//650 651LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) {652  Module *D = unwrap(Dest);653  std::unique_ptr<Module> M(unwrap(Src));654  return Linker::linkModules(*D, std::move(M));655}656