1 //===- lib/Linker/LinkModules.cpp - Module Linker Implementation ----------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the LLVM module linker.
11 //===----------------------------------------------------------------------===//
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"
26 enum class LinkFrom
{ Dst
, Src
, Both
};
28 /// This is an implementation class for the LinkModules function, which is the
29 /// entrypoint for this file.
32 std::unique_ptr
<Module
> SrcM
;
34 SetVector
<GlobalValue
*> ValuesToLink
;
36 /// For symbol clashes, prefer those from Src.
39 /// List of global value names that should be internalized.
40 StringSet
<> Internalize
;
42 /// Function that will perform the actual internalization. The reason for a
43 /// callback is that the linker cannot call internalizeModule without
44 /// creating a circular dependency between IPO and the linker.
45 std::function
<void(Module
&, const StringSet
<> &)> InternalizeCallback
;
47 /// Used as the callback for lazy linking.
48 /// The mover has just hit GV and we have to decide if it, and other members
49 /// of the same comdat, should be linked. Every member to be linked is passed
51 void addLazyFor(GlobalValue
&GV
, const IRMover::ValueAdder
&Add
);
53 bool shouldOverrideFromSrc() { return Flags
& Linker::OverrideFromSrc
; }
54 bool shouldLinkOnlyNeeded() { return Flags
& Linker::LinkOnlyNeeded
; }
56 bool shouldLinkFromSource(bool &LinkFromSrc
, const GlobalValue
&Dest
,
57 const GlobalValue
&Src
);
59 /// Should we have mover and linker error diag info?
60 bool emitError(const Twine
&Message
) {
61 SrcM
->getContext().diagnose(LinkDiagnosticInfo(DS_Error
, Message
));
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
,
72 DenseMap
<const Comdat
*, std::pair
<Comdat::SelectionKind
, LinkFrom
>>
74 bool getComdatResult(const Comdat
*SrcC
, Comdat::SelectionKind
&SK
,
76 // Keep track of the lazy linked global members of each comdat in source.
77 DenseMap
<const Comdat
*, std::vector
<GlobalValue
*>> LazyComdatMembers
;
79 /// Given a global in the source module, return the global in the
80 /// 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()))
88 // Otherwise see if we have a match in the destination module's symtab.
89 GlobalValue
*DGV
= DstM
.getNamedValue(SrcGV
->getName());
93 // If we found a global with the same name in the dest module, but it has
94 // internal linkage, we are really not doing any linkage here.
95 if (DGV
->hasLocalLinkage())
98 // Otherwise, we do in fact link to the destination global.
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
);
107 bool linkIfNeeded(GlobalValue
&GV
, SmallVectorImpl
<GlobalValue
*> &GVToClone
);
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
)) {}
120 static GlobalValue::VisibilityTypes
121 getMinVisibility(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
;
131 bool 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();
137 // We cannot resolve the size of the aliasee yet.
138 return emitError("Linking COMDATs named '" + ComdatName
+
139 "': COMDAT key involves incomputable alias size.");
142 GVar
= dyn_cast_or_null
<GlobalVariable
>(GVal
);
145 "Linking COMDATs named '" + ComdatName
+
146 "': GlobalVariable required for data dependent selection!");
151 bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName
,
152 Comdat::SelectionKind Src
,
153 Comdat::SelectionKind Dst
,
154 Comdat::SelectionKind
&Result
,
156 Module
&DstM
= Mover
.getModule();
157 // The ability to mix Comdat::SelectionKind::Any with
158 // 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
;
168 Result
= Comdat::SelectionKind::Any
;
169 } else if (Src
== Dst
) {
172 return emitError("Linking COMDATs named '" + ComdatName
+
173 "': invalid selection kinds!");
177 case Comdat::SelectionKind::Any
:
179 From
= LinkFrom::Dst
;
181 case Comdat::SelectionKind::NoDeduplicate
:
182 From
= LinkFrom::Both
;
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
))
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
;
210 llvm_unreachable("unknown selection kind");
219 bool ModuleLinker::getComdatResult(const Comdat
*SrcC
,
220 Comdat::SelectionKind
&Result
,
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
);
228 if (DstCI
== ComdatSymTab
.end()) {
229 // Use the comdat if it is only available in one of the modules.
230 From
= LinkFrom::Src
;
235 const Comdat
*DstC
= &DstCI
->second
;
236 Comdat::SelectionKind DSK
= DstC
->getSelectionKind();
237 return computeResultingSelectionKind(ComdatName
, SSK
, DSK
, Result
, From
);
240 bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc
,
241 const GlobalValue
&Dest
,
242 const GlobalValue
&Src
) {
244 // Should we unconditionally use the Src?
245 if (shouldOverrideFromSrc()) {
250 // We always have to add Src if it has appending linkage.
251 if (Src
.hasAppendingLinkage() || Dest
.hasAppendingLinkage()) {
256 bool SrcIsDeclaration
= Src
.isDeclarationForLinker();
257 bool DestIsDeclaration
= Dest
.isDeclarationForLinker();
259 if (SrcIsDeclaration
) {
260 // If Src is external or if both Src & Dest are external.. Just link the
261 // 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
;
267 // If the Dest is weak, use the source linkage.
268 if (Dest
.hasExternalWeakLinkage()) {
272 // Link an available_externally over a declaration.
273 LinkFromSrc
= !Src
.isDeclaration() && Dest
.isDeclaration();
277 if (DestIsDeclaration
) {
278 // If Dest is external but Src is not:
283 if (Src
.hasCommonLinkage()) {
284 if (Dest
.hasLinkOnceLinkage() || Dest
.hasWeakLinkage()) {
289 if (!Dest
.hasCommonLinkage()) {
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
;
301 if (Src
.isWeakForLinker()) {
302 assert(!Dest
.hasExternalWeakLinkage());
303 assert(!Dest
.hasAvailableExternallyLinkage());
305 if (Dest
.hasLinkOnceLinkage() && Src
.hasWeakLinkage()) {
314 if (Dest
.isWeakForLinker()) {
315 assert(Src
.hasExternalLinkage());
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!");
328 bool ModuleLinker::linkIfNeeded(GlobalValue
&GV
,
329 SmallVectorImpl
<GlobalValue
*> &GVToClone
) {
330 GlobalValue
*DGV
= getLinkedToGlobal(&GV
);
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 destination
339 // Don't import globals that are already defined in the destination module
340 if (!DGV
->isDeclaration())
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);
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());
361 SGVar
->setAlignment(Align
);
362 DGVar
->setAlignment(Align
);
366 GlobalValue::VisibilityTypes Visibility
=
367 getMinVisibility(DGV
->getVisibility(), GV
.getVisibility());
368 DGV
->setVisibility(Visibility
);
369 GV
.setVisibility(Visibility
);
371 GlobalValue::UnnamedAddr UnnamedAddr
= GlobalValue::getMinUnnamedAddr(
372 DGV
->getUnnamedAddr(), GV
.getUnnamedAddr());
373 DGV
->setUnnamedAddr(UnnamedAddr
);
374 GV
.setUnnamedAddr(UnnamedAddr
);
377 if (!DGV
&& !shouldOverrideFromSrc() &&
378 (GV
.hasLocalLinkage() || GV
.hasLinkOnceLinkage() ||
379 GV
.hasAvailableExternallyLinkage()))
382 if (GV
.isDeclaration())
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
)
392 bool LinkFromSrc
= true;
393 if (DGV
&& shouldLinkFromSource(LinkFromSrc
, *DGV
, GV
))
395 if (DGV
&& ComdatFrom
== LinkFrom::Both
)
396 GVToClone
.push_back(LinkFromSrc
? DGV
: &GV
);
398 ValuesToLink
.insert(&GV
);
402 void ModuleLinker::addLazyFor(GlobalValue
&GV
, const IRMover::ValueAdder
&Add
) {
403 // Add these to the internalize list
404 if (!GV
.hasLinkOnceLinkage() && !GV
.hasAvailableExternallyLinkage() &&
405 !shouldLinkOnlyNeeded())
408 if (InternalizeCallback
)
409 Internalize
.insert(GV
.getName());
412 const Comdat
*SC
= GV
.getComdat();
415 for (GlobalValue
*GV2
: LazyComdatMembers
[SC
]) {
416 GlobalValue
*DGV
= getLinkedToGlobal(GV2
);
417 bool LinkFromSrc
= true;
418 if (DGV
&& shouldLinkFromSource(LinkFromSrc
, *DGV
, *GV2
))
422 if (InternalizeCallback
)
423 Internalize
.insert(GV2
->getName());
428 void ModuleLinker::dropReplacedComdat(
429 GlobalValue
&GV
, const DenseSet
<const Comdat
*> &ReplacedDstComdats
) {
430 Comdat
*C
= GV
.getComdat();
433 if (!ReplacedDstComdats
.count(C
))
435 if (GV
.use_empty()) {
436 GV
.eraseFromParent();
440 if (auto *F
= dyn_cast
<Function
>(&GV
)) {
442 } else if (auto *Var
= dyn_cast
<GlobalVariable
>(&GV
)) {
443 Var
->setInitializer(nullptr);
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
);
452 new GlobalVariable(M
, Alias
.getValueType(), /*isConstant*/ false,
453 GlobalValue::ExternalLinkage
,
454 /*Initializer*/ nullptr);
456 Declaration
->takeName(&Alias
);
457 Alias
.replaceAllUsesWith(Declaration
);
458 Alias
.eraseFromParent();
462 bool ModuleLinker::run() {
463 Module
&DstM
= Mover
.getModule();
464 DenseSet
<const Comdat
*> ReplacedDstComdats
;
465 DenseSet
<const Comdat
*> NonPrevailingComdats
;
467 for (const auto &SMEC
: SrcM
->getComdatSymbolTable()) {
468 const Comdat
&C
= SMEC
.getValue();
469 if (ComdatsChosen
.count(&C
))
471 Comdat::SelectionKind SK
;
473 if (getComdatResult(&C
, SK
, From
))
475 ComdatsChosen
[&C
] = std::make_pair(SK
, From
);
477 if (From
== LinkFrom::Dst
)
478 NonPrevailingComdats
.insert(&C
);
480 if (From
!= LinkFrom::Src
)
483 Module::ComdatSymTabType
&ComdatSymTab
= DstM
.getComdatSymbolTable();
484 Module::ComdatSymTabType::iterator DstCI
= ComdatSymTab
.find(C
.getName());
485 if (DstCI
== ComdatSymTab
.end())
488 // The source comdat is replacing the dest one.
489 const Comdat
*DstC
= &DstCI
->second
;
490 ReplacedDstComdats
.insert(DstC
);
493 // Alias have to go first, since we are not able to find their comdats
495 for (GlobalAlias
&GV
: llvm::make_early_inc_range(DstM
.aliases()))
496 dropReplacedComdat(GV
, ReplacedDstComdats
);
498 for (GlobalVariable
&GV
: llvm::make_early_inc_range(DstM
.globals()))
499 dropReplacedComdat(GV
, ReplacedDstComdats
);
501 for (Function
&GV
: llvm::make_early_inc_range(DstM
))
502 dropReplacedComdat(GV
, ReplacedDstComdats
);
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);
521 for (GlobalVariable
&GV
: SrcM
->globals())
522 if (GV
.hasLinkOnceLinkage())
523 if (const Comdat
*SC
= GV
.getComdat())
524 LazyComdatMembers
[SC
].push_back(&GV
);
526 for (Function
&SF
: *SrcM
)
527 if (SF
.hasLinkOnceLinkage())
528 if (const Comdat
*SC
= SF
.getComdat())
529 LazyComdatMembers
[SC
].push_back(&SF
);
531 for (GlobalAlias
&GA
: SrcM
->aliases())
532 if (GA
.hasLinkOnceLinkage())
533 if (const Comdat
*SC
= GA
.getComdat())
534 LazyComdatMembers
[SC
].push_back(&GA
);
536 // Insert all of the globals in src into the DstM module... without linking
537 // 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
))
543 for (Function
&SF
: *SrcM
)
544 if (linkIfNeeded(SF
, GVToClone
))
547 for (GlobalAlias
&GA
: SrcM
->aliases())
548 if (linkIfNeeded(GA
, GVToClone
))
551 for (GlobalIFunc
&GI
: SrcM
->ifuncs())
552 if (linkIfNeeded(GI
, GVToClone
))
555 // For a variable in a comdat nodeduplicate, its initializer should be
556 // preserved (its content may be implicitly used by other members) even if
557 // symbol resolution does not pick it. Clone it into an unnamed private
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
);
572 emitError("linking '" + GV
->getName() +
573 "': non-variables in comdat nodeduplicate are not handled");
577 for (unsigned I
= 0; I
< ValuesToLink
.size(); ++I
) {
578 GlobalValue
*GV
= ValuesToLink
[I
];
579 const Comdat
*SC
= GV
->getComdat();
582 for (GlobalValue
*GV2
: LazyComdatMembers
[SC
]) {
583 GlobalValue
*DGV
= getLinkedToGlobal(GV2
);
584 bool LinkFromSrc
= true;
585 if (DGV
&& shouldLinkFromSource(LinkFromSrc
, *DGV
, *GV2
))
588 ValuesToLink
.insert(GV2
);
592 if (InternalizeCallback
) {
593 for (GlobalValue
*GV
: ValuesToLink
)
594 Internalize
.insert(GV
->getName());
597 // FIXME: Propagate Errors through to the caller instead of emitting
599 bool HasErrors
= false;
601 Mover
.move(std::move(SrcM
), ValuesToLink
.getArrayRef(),
602 IRMover::LazyCallback(
603 [this](GlobalValue
&GV
, IRMover::ValueAdder Add
) {
606 /* IsPerformingImport */ false)) {
607 handleAllErrors(std::move(E
), [&](ErrorInfoBase
&EIB
) {
608 DstM
.getContext().diagnose(LinkDiagnosticInfo(DS_Error
, EIB
.message()));
615 if (InternalizeCallback
)
616 InternalizeCallback(DstM
, Internalize
);
621 Linker::Linker(Module
&M
) : Mover(M
) {}
623 bool 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();
631 //===----------------------------------------------------------------------===//
632 // LinkModules entrypoint.
633 //===----------------------------------------------------------------------===//
635 /// This function links two modules together, with the resulting Dest module
636 /// 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 be
639 /// relied on to be consistent.
640 bool Linker::linkModules(
641 Module
&Dest
, std::unique_ptr
<Module
> Src
, unsigned Flags
,
642 std::function
<void(Module
&, const StringSet
<> &)> InternalizeCallback
) {
644 return L
.linkInModule(std::move(Src
), Flags
, std::move(InternalizeCallback
));
647 //===----------------------------------------------------------------------===//
649 //===----------------------------------------------------------------------===//
651 LLVMBool
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
));