about summary refs log tree commit diff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-03-19 17:33:46 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-03-19 17:33:46 -0700
commit277d42f589966f105cb4cba8da0b80c64fa7d28b (patch)
treeba11f2e807afeb18aa355b93031e3f06fe77613f /src/comp/middle
parenta1aad2869061b9ecf9d22f93c2d42e9dbe550d17 (diff)
rustc: Only declare each native function once. std.rc now links.
Diffstat (limited to 'src/comp/middle')
-rw-r--r--src/comp/middle/trans.rs16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 9e1c8fdd121..50ce6716115 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -71,6 +71,7 @@ state type crate_ctxt = rec(session.session sess,
                             hashmap[str, ValueRef] upcalls,
                             hashmap[str, ValueRef] intrinsics,
                             hashmap[str, ValueRef] item_names,
+                            hashmap[str, ValueRef] native_fns,
                             hashmap[ast.def_id, ValueRef] item_ids,
                             hashmap[ast.def_id, @ast.item] items,
                             hashmap[ast.def_id,
@@ -5452,7 +5453,19 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
     auto abi = ty.ty_fn_abi(fn_type);
     auto llfnty = type_of_native_fn(cx, abi, ty.ty_fn_args(fn_type),
                                     ty.ty_fn_ret(fn_type), num_ty_param);
-    auto function = decl_cdecl_fn(cx.llmod, name, llfnty);
+
+    // We can only declare a native function with a given name once; LLVM
+    // unhelpfully mangles the names if we try to multiply declare one.
+    auto function;
+    if (!cx.native_fns.contains_key(name)) {
+        function = decl_cdecl_fn(cx.llmod, name, llfnty);
+        cx.native_fns.insert(name, function);
+    } else {
+        // We support type-punning a native function by giving it different
+        // Rust types.
+        auto llorigfn = cx.native_fns.get(name);
+        function = bcx.build.PointerCast(llorigfn, T_ptr(llfnty));
+    }
 
     let vec[ValueRef] call_args = vec();
     auto arg_n = 3u;
@@ -6200,6 +6213,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
                    upcalls = new_str_hash[ValueRef](),
                    intrinsics = intrinsics,
                    item_names = new_str_hash[ValueRef](),
+                   native_fns = new_str_hash[ValueRef](),
                    item_ids = new_def_hash[ValueRef](),
                    items = new_def_hash[@ast.item](),
                    native_items = new_def_hash[@ast.native_item](),