Index: include/llvm/Linker/Linker.h
===================================================================
--- include/llvm/Linker/Linker.h
+++ include/llvm/Linker/Linker.h
@@ -68,8 +68,10 @@
void deleteModule();
/// \brief Link \p Src into the composite. The source is destroyed.
+ /// Passing OverrideSymbols as true will have symbols from Src
+ /// shadow those in the Dest.
/// Returns true on error.
- bool linkInModule(Module *Src);
+ bool linkInModule(Module *Src, bool OverrideSymbols = false);
/// \brief Set the composite to the passed-in module.
void setModule(Module *Dst);
Index: lib/Linker/LinkModules.cpp
===================================================================
--- lib/Linker/LinkModules.cpp
+++ lib/Linker/LinkModules.cpp
@@ -424,12 +424,17 @@
DiagnosticHandlerFunction DiagnosticHandler;
+ /// For symbol clashes, prefer those from Src.
+ bool OverrideFromSrc;
+
public:
ModuleLinker(Module *dstM, Linker::IdentifiedStructTypeSet &Set, Module *srcM,
- DiagnosticHandlerFunction DiagnosticHandler)
+ DiagnosticHandlerFunction DiagnosticHandler,
+ bool Override = false)
: DstM(dstM), SrcM(srcM), TypeMap(Set),
ValMaterializer(TypeMap, DstM, LazilyLinkGlobalValues),
- DiagnosticHandler(DiagnosticHandler) {}
+ DiagnosticHandler(DiagnosticHandler),
+ OverrideFromSrc(Override) {}
bool run();
@@ -794,6 +799,12 @@
assert(!Dest.hasExternalWeakLinkage());
assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() &&
"Unexpected linkage type!");
+
+ if (OverrideFromSrc) {
+ LinkFromSrc = true;
+ return false;
+ }
+
return emitError("Linking globals named '" + Src.getName() +
"': symbol multiply defined!");
}
@@ -1738,9 +1749,9 @@
Composite = nullptr;
}
-bool Linker::linkInModule(Module *Src) {
+bool Linker::linkInModule(Module *Src, bool OverrideSymbols) {
ModuleLinker TheLinker(Composite, IdentifiedStructTypes, Src,
- DiagnosticHandler);
+ DiagnosticHandler, OverrideSymbols);
bool RetCode = TheLinker.run();
Composite->dropTriviallyDeadConstantArrays();
return RetCode;
Index: test/tools/llvm-link/Inputs/foo.ll
===================================================================
--- /dev/null
+++ test/tools/llvm-link/Inputs/foo.ll
@@ -0,0 +1,4 @@
+define i32 @foo(i32 %i) {
+entry:
+ ret i32 4
+}
Index: test/tools/llvm-link/hello.ll
===================================================================
--- /dev/null
+++ test/tools/llvm-link/hello.ll
@@ -0,0 +1,18 @@
+; RUN: llvm-link %s -override %p/Inputs/foo.ll -S | FileCheck %s
+
+
+; CHECK-LABEL: define i32 @foo
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i32 4
+define i32 @foo(i32 %i) {
+entry:
+ %add = add nsw i32 %i, %i
+ ret i32 %add
+}
+
+; Function Attrs: nounwind ssp uwtable
+define i32 @main(i32 %argc, i8** %argv) {
+entry:
+ %a = call i32 @foo(i32 2)
+ ret i32 %a
+}
Index: test/tools/llvm-link/lit.local.cfg
===================================================================
--- /dev/null
+++ test/tools/llvm-link/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = ['.ll']
Index: tools/llvm-link/llvm-link.cpp
===================================================================
--- tools/llvm-link/llvm-link.cpp
+++ tools/llvm-link/llvm-link.cpp
@@ -38,6 +38,11 @@
InputFilenames(cl::Positional, cl::OneOrMore,
cl::desc(""));
+static cl::list
+OverridingInputs("override", cl::ZeroOrMore, cl::value_desc("filename"),
+ cl::desc("input bitcode file which can "
+ "override previously defined symbol"));
+
static cl::opt
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
cl::value_desc("filename"));
@@ -119,24 +124,29 @@
auto Composite = make_unique("llvm-link", Context);
Linker L(Composite.get(), diagnosticHandler);
- for (unsigned i = 0; i < InputFilenames.size(); ++i) {
- std::unique_ptr M = loadFile(argv[0], InputFilenames[i], Context);
- if (!M.get()) {
- errs() << argv[0] << ": error loading file '" <& Files, bool Override) {
+ for (auto File : Files) {
+ std::unique_ptr M = loadFile(argv[0], File, Context);
+ if (!M.get()) {
+ errs() << argv[0] << ": error loading file '" << File << "'\n";
+ exit(1);
+ }
- if (verifyModule(*M, &errs())) {
- errs() << argv[0] << ": " << InputFilenames[i]
- << ": error: input module is broken!\n";
- return 1;
- }
+ if (verifyModule(*M, &errs())) {
+ errs() << argv[0] << ": " << File
+ << ": error: input module is broken!\n";
+ exit(1);
+ }
- if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n";
+ if (Verbose) errs() << "Linking in '" << File << "'\n";
- if (L.linkInModule(M.get()))
- return 1;
- }
+ if (L.linkInModule(M.get(), Override))
+ exit(1);
+ }
+ };
+
+ linkFiles(InputFilenames, false);
+ linkFiles(OverridingInputs, true);
if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;