about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/comp/lib/llvm.rs2
-rw-r--r--src/comp/middle/trans.rs3
-rw-r--r--src/rustllvm/RustWrapper.cpp6
-rw-r--r--src/rustllvm/rustllvm.def.in1
-rw-r--r--src/test/run-pass/native-dupe.rs12
5 files changed, 23 insertions, 1 deletions
diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs
index f5b0fbeec8d..83edf143f33 100644
--- a/src/comp/lib/llvm.rs
+++ b/src/comp/lib/llvm.rs
@@ -448,6 +448,8 @@ native "cdecl" mod llvm = "rustllvm" {
     fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
     fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
     fn LLVMDeleteFunction(Fn: ValueRef);
+    fn LLVMGetOrInsertFunction(M: ModuleRef, Name: sbuf, FunctionTy: TypeRef)
+       -> ValueRef;
     fn LLVMGetIntrinsicID(Fn: ValueRef) -> uint;
     fn LLVMGetFunctionCallConv(Fn: ValueRef) -> uint;
     fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: uint);
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 8478061bc88..36393213fb3 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -301,7 +301,8 @@ fn log_fn_time(ccx: @crate_ctxt, name: str, start: time::timeval,
 
 fn decl_fn(llmod: ModuleRef, name: str, cc: uint, llty: TypeRef) -> ValueRef {
     let llfn: ValueRef =
-        str::as_buf(name, {|buf| llvm::LLVMAddFunction(llmod, buf, llty) });
+        str::as_buf(name, {|buf|
+            llvm::LLVMGetOrInsertFunction(llmod, buf, llty) });
     llvm::LLVMSetFunctionCallConv(llfn, cc);
     ret llfn;
 }
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 26d0764934e..c0553b3c1d9 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -141,3 +141,9 @@ extern "C" void LLVMRustEnableSegmentedStacks() {
   EnableSegmentedStacks = true;
 }
 
+extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
+                                                const char* Name,
+                                                LLVMTypeRef FunctionTy) {
+  return wrap(unwrap(M)->getOrInsertFunction(Name,
+                                             unwrap<FunctionType>(FunctionTy)));
+}
diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in
index b418ba168c8..9712ea60371 100644
--- a/src/rustllvm/rustllvm.def.in
+++ b/src/rustllvm/rustllvm.def.in
@@ -364,6 +364,7 @@ LLVMGetNextParam
 LLVMGetNextUse
 LLVMGetNumOperands
 LLVMGetOperand
+LLVMGetOrInsertFunction
 LLVMGetParam
 LLVMGetParamParent
 LLVMGetParamTypes
diff --git a/src/test/run-pass/native-dupe.rs b/src/test/run-pass/native-dupe.rs
new file mode 100644
index 00000000000..717db324348
--- /dev/null
+++ b/src/test/run-pass/native-dupe.rs
@@ -0,0 +1,12 @@
+native "cdecl" mod rustrt1 = "rustrt" {
+    fn pin_task();
+}
+
+native "cdecl" mod rustrt2 = "rustrt" {
+    fn pin_task();
+}
+
+fn main() {
+    rustrt1::pin_task();
+    rustrt2::pin_task();
+}