about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-27 08:58:33 -0700
committerbors <bors@rust-lang.org>2013-07-27 08:58:33 -0700
commit0522955d10f76ac2ca3182de9ff5b774982243cb (patch)
tree6d7418c10a7b29a38cea5fc79d50cd41448c104e
parentaa8f79d6cf89eca0764f5c578825ffd92e6b0e69 (diff)
parentc32b26be1000673e06ef2e5d114e39a28a5d6cd5 (diff)
downloadrust-0522955d10f76ac2ca3182de9ff5b774982243cb.tar.gz
rust-0522955d10f76ac2ca3182de9ff5b774982243cb.zip
auto merge of #8070 : luqmana/rust/nom, r=alexcrichton
Fixes #5972.
-rw-r--r--src/librustc/middle/trans/base.rs321
-rw-r--r--src/librustc/middle/trans/foreign.rs11
2 files changed, 172 insertions, 160 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index e467f91d1b1..a985416968b 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2244,47 +2244,38 @@ pub fn trans_mod(ccx: @mut CrateContext, m: &ast::_mod) {
 
 pub fn register_fn(ccx: @mut CrateContext,
                    sp: span,
-                   path: path,
-                   node_id: ast::node_id,
-                   attrs: &[ast::Attribute])
+                   sym: ~str,
+                   node_id: ast::node_id)
                 -> ValueRef {
     let t = ty::node_id_to_type(ccx.tcx, node_id);
-    register_fn_full(ccx, sp, path, node_id, attrs, t)
+    register_fn_full(ccx, sp, sym, node_id, t)
 }
 
 pub fn register_fn_full(ccx: @mut CrateContext,
                         sp: span,
-                        path: path,
+                        sym: ~str,
                         node_id: ast::node_id,
-                        attrs: &[ast::Attribute],
                         node_type: ty::t)
                      -> ValueRef {
     let llfty = type_of_fn_from_ty(ccx, node_type);
-    register_fn_fuller(ccx, sp, path, node_id, attrs, node_type,
+    register_fn_fuller(ccx, sp, sym, node_id, node_type,
                        lib::llvm::CCallConv, llfty)
 }
 
 pub fn register_fn_fuller(ccx: @mut CrateContext,
                           sp: span,
-                          path: path,
+                          sym: ~str,
                           node_id: ast::node_id,
-                          attrs: &[ast::Attribute],
                           node_type: ty::t,
                           cc: lib::llvm::CallConv,
                           fn_ty: Type)
                           -> ValueRef {
     debug!("register_fn_fuller creating fn for item %d with path %s",
            node_id,
-           ast_map::path_to_str(path, token::get_ident_interner()));
-
-    let ps = if attr::contains_name(attrs, "no_mangle") {
-        path_elt_to_str(*path.last(), token::get_ident_interner())
-    } else {
-        mangle_exported_name(ccx, path, node_type)
-    };
+           ast_map::path_to_str(item_path(ccx, &node_id), token::get_ident_interner()));
 
-    let llfn = decl_fn(ccx.llmod, ps, cc, fn_ty);
-    ccx.item_symbols.insert(node_id, ps);
+    let llfn = decl_fn(ccx.llmod, sym, cc, fn_ty);
+    ccx.item_symbols.insert(node_id, sym);
 
     // FIXME #4404 android JNI hacks
     let is_entry = is_entry_fn(&ccx.sess, node_id) && (!*ccx.sess.building_library ||
@@ -2430,162 +2421,182 @@ pub fn fill_fn_pair(bcx: @mut Block, pair: ValueRef, llfn: ValueRef,
     Store(bcx, llenvblobptr, env_cell);
 }
 
-pub fn item_path(ccx: &CrateContext, i: &ast::item) -> path {
-    let base = match ccx.tcx.items.get_copy(&i.id) {
-        ast_map::node_item(_, p) => p,
-            // separate map for paths?
+pub fn item_path(ccx: &CrateContext, id: &ast::node_id) -> path {
+    match ccx.tcx.items.get_copy(id) {
+        ast_map::node_item(i, p) =>
+            vec::append((*p).clone(), [path_name(i.ident)]),
+        // separate map for paths?
         _ => fail!("item_path")
-    };
-    vec::append((*base).clone(), [path_name(i.ident)])
+    }
+}
+
+fn exported_name(ccx: @mut CrateContext, path: path, ty: ty::t, attrs: &[ast::Attribute]) -> ~str {
+    if attr::contains_name(attrs, "no_mangle") {
+        path_elt_to_str(*path.last(), token::get_ident_interner())
+    } else {
+        mangle_exported_name(ccx, path, ty)
+    }
 }
 
 pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef {
     debug!("get_item_val(id=`%?`)", id);
+
     let val = ccx.item_vals.find_copy(&id);
     match val {
-      Some(v) => v,
-      None => {
-        let mut exprt = false;
-        let item = ccx.tcx.items.get_copy(&id);
-        let val = match item {
-          ast_map::node_item(i, pth) => {
-            let my_path = vec::append((*pth).clone(), [path_name(i.ident)]);
-            let v = match i.node {
-              ast::item_static(_, m, expr) => {
-                let typ = ty::node_id_to_type(ccx.tcx, i.id);
-                let s = mangle_exported_name(ccx, my_path, typ);
-                // We need the translated value here, because for enums the
-                // LLVM type is not fully determined by the Rust type.
-                let v = consts::const_expr(ccx, expr);
-                ccx.const_values.insert(id, v);
-                exprt = m == ast::m_mutbl;
-                unsafe {
-                    let llty = llvm::LLVMTypeOf(v);
-                    let g = do s.as_c_str |buf| {
-                        llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
+        Some(v) => v,
+        None => {
+            let mut exprt = false;
+            let item = ccx.tcx.items.get_copy(&id);
+            let val = match item {
+                ast_map::node_item(i, pth) => {
+
+                    let my_path = vec::append((*pth).clone(), [path_name(i.ident)]);
+                    let ty = ty::node_id_to_type(ccx.tcx, i.id);
+                    let sym = exported_name(ccx, my_path, ty, i.attrs);
+
+                    let v = match i.node {
+                        ast::item_static(_, m, expr) => {
+                            // We need the translated value here, because for enums the
+                            // LLVM type is not fully determined by the Rust type.
+                            let v = consts::const_expr(ccx, expr);
+                            ccx.const_values.insert(id, v);
+                            exprt = m == ast::m_mutbl;
+
+                            unsafe {
+                                let llty = llvm::LLVMTypeOf(v);
+                                let g = do sym.as_c_str |buf| {
+                                    llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
+                                };
+
+                                ccx.item_symbols.insert(i.id, sym);
+                                g
+                            }
+                        }
+
+                        ast::item_fn(_, purity, _, _, _) => {
+                            let llfn = if purity != ast::extern_fn {
+                                register_fn_full(ccx, i.span, sym, i.id, ty)
+                            } else {
+                                foreign::register_foreign_fn(ccx, i.span, sym, i.id)
+                            };
+                            set_inline_hint_if_appr(i.attrs, llfn);
+                            llfn
+                        }
+
+                        _ => fail!("get_item_val: weird result in table")
                     };
-                    ccx.item_symbols.insert(i.id, s);
-                    g
-                }
-              }
-              ast::item_fn(_, purity, _, _, _) => {
-                let llfn = if purity != ast::extern_fn {
-                    register_fn(ccx, i.span, my_path, i.id, i.attrs)
-                } else {
-                    foreign::register_foreign_fn(ccx,
-                                                 i.span,
-                                                 my_path,
-                                                 i.id,
-                                                 i.attrs)
-                };
-                set_inline_hint_if_appr(i.attrs, llfn);
-                llfn
-              }
-              _ => fail!("get_item_val: weird result in table")
-            };
-            match (attr::first_attr_value_str_by_name(i.attrs, "link_section")) {
-                Some(sect) => unsafe {
-                    do sect.as_c_str |buf| {
-                        llvm::LLVMSetSection(v, buf);
+
+                    match (attr::first_attr_value_str_by_name(i.attrs, "link_section")) {
+                        Some(sect) => unsafe {
+                            do sect.as_c_str |buf| {
+                                llvm::LLVMSetSection(v, buf);
+                            }
+                        },
+                        None => ()
                     }
-                },
-                None => ()
-            }
-            v
-          }
-          ast_map::node_trait_method(trait_method, _, pth) => {
-            debug!("get_item_val(): processing a node_trait_method");
-            match *trait_method {
-              ast::required(_) => {
-                ccx.sess.bug("unexpected variant: required trait method in \
-                              get_item_val()");
-              }
-              ast::provided(m) => {
-                exprt = true;
-                register_method(ccx, id, pth, m)
-              }
-            }
-          }
-          ast_map::node_method(m, _, pth) => {
-            register_method(ccx, id, pth, m)
-          }
-          ast_map::node_foreign_item(ni, _, _, pth) => {
-            exprt = true;
-            match ni.node {
-                ast::foreign_item_fn(*) => {
-                    register_fn(ccx, ni.span,
-                                vec::append((*pth).clone(),
-                                            [path_name(ni.ident)]),
-                                ni.id,
-                                ni.attrs)
+
+                    v
                 }
-                ast::foreign_item_static(*) => {
-                    let typ = ty::node_id_to_type(ccx.tcx, ni.id);
-                    let ident = token::ident_to_str(&ni.ident);
-                    let g = do ident.as_c_str |buf| {
-                        unsafe {
-                            let ty = type_of(ccx, typ);
-                            llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
+
+                ast_map::node_trait_method(trait_method, _, pth) => {
+                    debug!("get_item_val(): processing a node_trait_method");
+                    match *trait_method {
+                        ast::required(_) => {
+                            ccx.sess.bug("unexpected variant: required trait method in \
+                                         get_item_val()");
                         }
-                    };
-                    g
+                        ast::provided(m) => {
+                            exprt = true;
+                            register_method(ccx, id, pth, m)
+                        }
+                    }
                 }
-            }
-          }
 
-          ast_map::node_variant(ref v, enm, pth) => {
-            let llfn;
-            match v.node.kind {
-                ast::tuple_variant_kind(ref args) => {
-                    assert!(args.len() != 0u);
-                    let pth = vec::append((*pth).clone(),
-                                          [path_name(enm.ident),
-                                           path_name((*v).node.name)]);
-                    llfn = match enm.node {
-                      ast::item_enum(_, _) => {
-                        register_fn(ccx, (*v).span, pth, id, enm.attrs)
-                      }
-                      _ => fail!("node_variant, shouldn't happen")
-                    };
-                }
-                ast::struct_variant_kind(_) => {
-                    fail!("struct variant kind unexpected in get_item_val")
+                ast_map::node_method(m, _, pth) => {
+                    register_method(ccx, id, pth, m)
                 }
-            }
-            set_inline_hint(llfn);
-            llfn
-          }
 
-          ast_map::node_struct_ctor(struct_def, struct_item, struct_path) => {
-            // Only register the constructor if this is a tuple-like struct.
-            match struct_def.ctor_id {
-                None => {
-                    ccx.tcx.sess.bug("attempt to register a constructor of \
-                                  a non-tuple-like struct")
+                ast_map::node_foreign_item(ni, _, _, pth) => {
+                    let ty = ty::node_id_to_type(ccx.tcx, ni.id);
+                    exprt = true;
+
+                    match ni.node {
+                        ast::foreign_item_fn(*) => {
+                            let path = vec::append((*pth).clone(), [path_name(ni.ident)]);
+                            let sym = exported_name(ccx, path, ty, ni.attrs);
+
+                            register_fn_full(ccx, ni.span, sym, ni.id, ty)
+                        }
+                        ast::foreign_item_static(*) => {
+                            let ident = token::ident_to_str(&ni.ident);
+                            let g = do ident.as_c_str |buf| {
+                                unsafe {
+                                    let ty = type_of(ccx, ty);
+                                    llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
+                                }
+                            };
+                            g
+                        }
+                    }
                 }
-                Some(ctor_id) => {
-                    let llfn = register_fn(ccx,
-                                           struct_item.span,
-                                           (*struct_path).clone(),
-                                           ctor_id,
-                                           struct_item.attrs);
+
+                ast_map::node_variant(ref v, enm, pth) => {
+                    let llfn;
+                    match v.node.kind {
+                        ast::tuple_variant_kind(ref args) => {
+                            assert!(args.len() != 0u);
+                            let pth = vec::append((*pth).clone(),
+                                                  [path_name(enm.ident),
+                                                   path_name((*v).node.name)]);
+                            let ty = ty::node_id_to_type(ccx.tcx, id);
+                            let sym = exported_name(ccx, pth, ty, enm.attrs);
+
+                            llfn = match enm.node {
+                                ast::item_enum(_, _) => {
+                                    register_fn_full(ccx, (*v).span, sym, id, ty)
+                                }
+                                _ => fail!("node_variant, shouldn't happen")
+                            };
+                        }
+                        ast::struct_variant_kind(_) => {
+                            fail!("struct variant kind unexpected in get_item_val")
+                        }
+                    }
                     set_inline_hint(llfn);
                     llfn
                 }
+
+                ast_map::node_struct_ctor(struct_def, struct_item, struct_path) => {
+                    // Only register the constructor if this is a tuple-like struct.
+                    match struct_def.ctor_id {
+                        None => {
+                            ccx.tcx.sess.bug("attempt to register a constructor of \
+                                              a non-tuple-like struct")
+                        }
+                        Some(ctor_id) => {
+                            let ty = ty::node_id_to_type(ccx.tcx, ctor_id);
+                            let sym = exported_name(ccx, (*struct_path).clone(), ty,
+                                                    struct_item.attrs);
+                            let llfn = register_fn_full(ccx, struct_item.span, sym, ctor_id, ty);
+                            set_inline_hint(llfn);
+                            llfn
+                        }
+                    }
+                }
+
+                ref variant => {
+                    ccx.sess.bug(fmt!("get_item_val(): unexpected variant: %?",
+                                 variant))
+                }
+            };
+
+            if !exprt && !ccx.reachable.contains(&id) {
+                lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage);
             }
-          }
 
-          ref variant => {
-            ccx.sess.bug(fmt!("get_item_val(): unexpected variant: %?",
-                              variant))
-          }
-        };
-        if !exprt && !ccx.reachable.contains(&id) {
-            lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage);
+            ccx.item_vals.insert(id, val);
+            val
         }
-        ccx.item_vals.insert(id, val);
-        val
-      }
     }
 }
 
@@ -2599,7 +2610,9 @@ pub fn register_method(ccx: @mut CrateContext,
     path.push(path_name(gensym_name("meth")));
     path.push(path_name(m.ident));
 
-    let llfn = register_fn_full(ccx, m.span, path, id, m.attrs, mty);
+    let sym = exported_name(ccx, path, mty, m.attrs);
+
+    let llfn = register_fn_full(ccx, m.span, sym, id, mty);
     set_inline_hint_if_appr(m.attrs, llfn);
     llfn
 }
@@ -2613,7 +2626,7 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) {
                                    ast::def_id { crate: ast::local_crate,
                                                  node: it.id });
         let mut i = 0;
-        let path = item_path(ccx, it);
+        let path = item_path(ccx, &it.id);
         for (*enum_definition).variants.iter().advance |variant| {
             let p = vec::append(path.clone(), [
                 path_name(variant.node.name),
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 372d24e664c..6e198af448b 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -32,6 +32,7 @@ use middle::ty;
 use middle::ty::FnSig;
 use util::ppaux::ty_to_str;
 
+use std::cell::Cell;
 use std::uint;
 use std::vec;
 use syntax::codemap::span;
@@ -1139,22 +1140,20 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext,
 
 pub fn register_foreign_fn(ccx: @mut CrateContext,
                            sp: span,
-                           path: ast_map::path,
-                           node_id: ast::node_id,
-                           attrs: &[ast::Attribute])
+                           sym: ~str,
+                           node_id: ast::node_id)
                            -> ValueRef {
     let _icx = push_ctxt("foreign::register_foreign_fn");
 
     let t = ty::node_id_to_type(ccx.tcx, node_id);
+    let sym = Cell::new(sym);
 
     let tys = shim_types(ccx, node_id);
     do tys.fn_ty.decl_fn |fnty| {
-        // XXX(pcwalton): We should not copy the path.
         register_fn_fuller(ccx,
                            sp,
-                           path.clone(),
+                           sym.take(),
                            node_id,
-                           attrs,
                            t,
                            lib::llvm::CCallConv,
                            fnty)