librustc: Implement a #[no_mangle] attribute to suppress name mangling. r=brson
This is very helpful for SDL, as SDL wants you to define a function named `SDL_main`.
This commit is contained in:
parent
0c05a6c092
commit
a0c2a9b743
@ -171,8 +171,7 @@ fn is_test_fn(i: @ast::item) -> bool {
|
||||
}
|
||||
|
||||
fn is_ignored(cx: test_ctxt, i: @ast::item) -> bool {
|
||||
let ignoreattrs = attr::find_attrs_by_name(/*bad*/copy i.attrs,
|
||||
~"ignore");
|
||||
let ignoreattrs = attr::find_attrs_by_name(i.attrs, "ignore");
|
||||
let ignoreitems = attr::attr_metas(ignoreattrs);
|
||||
let cfg_metas = vec::concat(vec::filter_map(ignoreitems,
|
||||
|i| attr::get_meta_item_list(*i)));
|
||||
|
@ -147,8 +147,7 @@ fn visit_item(e: env, i: @ast::item) {
|
||||
|
||||
let cstore = e.cstore;
|
||||
let mut already_added = false;
|
||||
let link_args = attr::find_attrs_by_name(/*bad*/copy i.attrs,
|
||||
~"link_args");
|
||||
let link_args = attr::find_attrs_by_name(i.attrs, "link_args");
|
||||
|
||||
match fm.sort {
|
||||
ast::named => {
|
||||
|
@ -329,8 +329,7 @@ impl ctxt {
|
||||
for [allow, warn, deny, forbid].each |level| {
|
||||
let level_name = level_to_str(*level);
|
||||
let metas =
|
||||
attr::attr_metas(attr::find_attrs_by_name(/*bad*/copy attrs,
|
||||
level_name));
|
||||
attr::attr_metas(attr::find_attrs_by_name(attrs, level_name));
|
||||
for metas.each |meta| {
|
||||
match /*bad*/copy meta.node {
|
||||
ast::meta_list(_, metas) => {
|
||||
|
@ -76,7 +76,7 @@ use core::uint;
|
||||
use std::map::HashMap;
|
||||
use std::smallintmap;
|
||||
use std::{map, time, list};
|
||||
use syntax::ast_map::{path, path_mod, path_name};
|
||||
use syntax::ast_map::{path, path_elt_to_str, path_mod, path_name};
|
||||
use syntax::ast_util::{def_id_of_def, local_def, path_to_ident};
|
||||
use syntax::attr;
|
||||
use syntax::codemap::span;
|
||||
@ -2086,28 +2086,44 @@ fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef {
|
||||
fn register_fn(ccx: @crate_ctxt,
|
||||
sp: span,
|
||||
+path: path,
|
||||
node_id: ast::node_id)
|
||||
node_id: ast::node_id,
|
||||
attrs: &[ast::attribute])
|
||||
-> ValueRef {
|
||||
let t = ty::node_id_to_type(ccx.tcx, node_id);
|
||||
register_fn_full(ccx, sp, path, node_id, t)
|
||||
register_fn_full(ccx, sp, path, node_id, attrs, t)
|
||||
}
|
||||
|
||||
fn register_fn_full(ccx: @crate_ctxt, sp: span, +path: path,
|
||||
node_id: ast::node_id, node_type: ty::t) -> ValueRef {
|
||||
fn register_fn_full(ccx: @crate_ctxt,
|
||||
sp: span,
|
||||
+path: path,
|
||||
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, node_type,
|
||||
register_fn_fuller(ccx, sp, path, node_id, attrs, node_type,
|
||||
lib::llvm::CCallConv, llfty)
|
||||
}
|
||||
|
||||
fn register_fn_fuller(ccx: @crate_ctxt, sp: span, +path: path,
|
||||
node_id: ast::node_id, node_type: ty::t,
|
||||
cc: lib::llvm::CallConv, llfty: TypeRef) -> ValueRef {
|
||||
fn register_fn_fuller(ccx: @crate_ctxt,
|
||||
sp: span,
|
||||
+path: path,
|
||||
node_id: ast::node_id,
|
||||
attrs: &[ast::attribute],
|
||||
node_type: ty::t,
|
||||
cc: lib::llvm::CallConv,
|
||||
llfty: TypeRef)
|
||||
-> ValueRef {
|
||||
debug!("register_fn_fuller creating fn for item %d with path %s",
|
||||
node_id,
|
||||
ast_map::path_to_str(path, ccx.sess.parse_sess.interner));
|
||||
|
||||
// XXX: Bad copy.
|
||||
let ps: ~str = mangle_exported_name(ccx, copy path, node_type);
|
||||
let ps = if attr::attrs_contains_name(attrs, "no_mangle") {
|
||||
path_elt_to_str(path.last(), ccx.sess.parse_sess.interner)
|
||||
} else {
|
||||
mangle_exported_name(ccx, /*bad*/copy path, node_type)
|
||||
};
|
||||
|
||||
// XXX: Bad copy.
|
||||
let llfn: ValueRef = decl_fn(ccx.llmod, copy ps, cc, llfty);
|
||||
ccx.item_symbols.insert(node_id, ps);
|
||||
@ -2281,9 +2297,13 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
||||
}
|
||||
ast::item_fn(_, purity, _, _) => {
|
||||
let llfn = if purity != ast::extern_fn {
|
||||
register_fn(ccx, i.span, my_path, i.id)
|
||||
register_fn(ccx, i.span, my_path, i.id, i.attrs)
|
||||
} else {
|
||||
foreign::register_foreign_fn(ccx, i.span, my_path, i.id)
|
||||
foreign::register_foreign_fn(ccx,
|
||||
i.span,
|
||||
my_path,
|
||||
i.id,
|
||||
i.attrs)
|
||||
};
|
||||
set_inline_hint_if_appr(/*bad*/copy i.attrs, llfn);
|
||||
llfn
|
||||
@ -2315,7 +2335,8 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
||||
register_fn(ccx, ni.span,
|
||||
vec::append(/*bad*/copy *pth,
|
||||
~[path_name(ni.ident)]),
|
||||
ni.id)
|
||||
ni.id,
|
||||
ni.attrs)
|
||||
}
|
||||
ast::foreign_item_const(*) => {
|
||||
let typ = ty::node_id_to_type(ccx.tcx, ni.id);
|
||||
@ -2366,7 +2387,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
||||
path_name((*v).node.name)]);
|
||||
llfn = match enm.node {
|
||||
ast::item_enum(_, _) => {
|
||||
register_fn(ccx, (*v).span, pth, id)
|
||||
register_fn(ccx, (*v).span, pth, id, enm.attrs)
|
||||
}
|
||||
_ => fail ~"node_variant, shouldn't happen"
|
||||
};
|
||||
@ -2390,8 +2411,11 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
||||
a non-tuple-like struct")
|
||||
}
|
||||
Some(ctor_id) => {
|
||||
let llfn = register_fn(ccx, struct_item.span,
|
||||
/*bad*/copy *struct_path, ctor_id);
|
||||
let llfn = register_fn(ccx,
|
||||
struct_item.span,
|
||||
/*bad*/copy *struct_path,
|
||||
ctor_id,
|
||||
struct_item.attrs);
|
||||
set_inline_hint(llfn);
|
||||
llfn
|
||||
}
|
||||
@ -2416,7 +2440,7 @@ fn register_method(ccx: @crate_ctxt, id: ast::node_id, pth: @ast_map::path,
|
||||
let mty = ty::node_id_to_type(ccx.tcx, id);
|
||||
let pth = vec::append(/*bad*/copy *pth, ~[path_name((ccx.names)(~"meth")),
|
||||
path_name(m.ident)]);
|
||||
let llfn = register_fn_full(ccx, m.span, pth, id, mty);
|
||||
let llfn = register_fn_full(ccx, m.span, pth, id, m.attrs, mty);
|
||||
set_inline_hint_if_appr(/*bad*/copy m.attrs, llfn);
|
||||
llfn
|
||||
}
|
||||
|
@ -809,8 +809,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
|
||||
if abi != ast::foreign_abi_rust_intrinsic {
|
||||
let llwrapfn = get_item_val(ccx, id);
|
||||
let tys = c_stack_tys(ccx, id);
|
||||
if attr::attrs_contains_name(/*bad*/copy foreign_item.attrs,
|
||||
~"rust_stack") {
|
||||
if attr::attrs_contains_name(foreign_item.attrs, "rust_stack") {
|
||||
build_direct_fn(ccx, llwrapfn, *foreign_item, tys, cc);
|
||||
} else {
|
||||
let llshimfn = build_shim_fn(ccx, *foreign_item, tys, cc);
|
||||
@ -1479,7 +1478,8 @@ fn trans_foreign_fn(ccx: @crate_ctxt, +path: ast_map::path,
|
||||
fn register_foreign_fn(ccx: @crate_ctxt,
|
||||
sp: span,
|
||||
+path: ast_map::path,
|
||||
node_id: ast::node_id)
|
||||
node_id: ast::node_id,
|
||||
attrs: &[ast::attribute])
|
||||
-> ValueRef {
|
||||
let _icx = ccx.insn_ctxt("foreign::register_foreign_fn");
|
||||
let t = ty::node_id_to_type(ccx.tcx, node_id);
|
||||
@ -1488,12 +1488,12 @@ fn register_foreign_fn(ccx: @crate_ctxt,
|
||||
let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
|
||||
let x86_64 = x86_64_tys(llargtys, llretty, ret_def);
|
||||
do decl_x86_64_fn(x86_64) |fnty| {
|
||||
register_fn_fuller(ccx, sp, /*bad*/copy path, node_id,
|
||||
register_fn_fuller(ccx, sp, /*bad*/copy path, node_id, attrs,
|
||||
t, lib::llvm::CCallConv, fnty)
|
||||
}
|
||||
} else {
|
||||
let llfty = T_fn(llargtys, llretty);
|
||||
register_fn_fuller(ccx, sp, path, node_id,
|
||||
register_fn_fuller(ccx, sp, path, node_id, attrs,
|
||||
t, lib::llvm::CCallConv, llfty)
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +80,13 @@ fn path_to_str(p: path, itr: @ident_interner) -> ~str {
|
||||
path_to_str_with_sep(p, ~"::", itr)
|
||||
}
|
||||
|
||||
fn path_elt_to_str(pe: path_elt, itr: @ident_interner) -> ~str {
|
||||
match pe {
|
||||
path_mod(s) => *itr.get(s),
|
||||
path_name(s) => *itr.get(s)
|
||||
}
|
||||
}
|
||||
|
||||
enum ast_node {
|
||||
node_item(@item, @path),
|
||||
node_foreign_item(@foreign_item, foreign_abi, @path),
|
||||
|
@ -180,7 +180,7 @@ fn get_name_value_str_pair(item: @ast::meta_item) -> Option<(~str, ~str)> {
|
||||
/* Searching */
|
||||
|
||||
/// Search a list of attributes and return only those with a specific name
|
||||
fn find_attrs_by_name(attrs: ~[ast::attribute], name: &str) ->
|
||||
fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) ->
|
||||
~[ast::attribute] {
|
||||
let filter: &fn(a: &ast::attribute) -> Option<ast::attribute> = |a| {
|
||||
if name == get_attr_name(*a) {
|
||||
@ -242,7 +242,7 @@ fn contains_name(metas: ~[@ast::meta_item], name: ~str) -> bool {
|
||||
return vec::len(matches) > 0u;
|
||||
}
|
||||
|
||||
fn attrs_contains_name(attrs: ~[ast::attribute], name: ~str) -> bool {
|
||||
fn attrs_contains_name(attrs: &[ast::attribute], name: &str) -> bool {
|
||||
vec::is_not_empty(find_attrs_by_name(attrs, name))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user