Skip to content

Commit a0c2a9b

Browse files
committed
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`.
1 parent 0c05a6c commit a0c2a9b

File tree

7 files changed

+59
-31
lines changed

7 files changed

+59
-31
lines changed

src/librustc/front/test.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,7 @@ fn is_test_fn(i: @ast::item) -> bool {
171171
}
172172

173173
fn is_ignored(cx: test_ctxt, i: @ast::item) -> bool {
174-
let ignoreattrs = attr::find_attrs_by_name(/*bad*/copy i.attrs,
175-
~"ignore");
174+
let ignoreattrs = attr::find_attrs_by_name(i.attrs, "ignore");
176175
let ignoreitems = attr::attr_metas(ignoreattrs);
177176
let cfg_metas = vec::concat(vec::filter_map(ignoreitems,
178177
|i| attr::get_meta_item_list(*i)));

src/librustc/metadata/creader.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,7 @@ fn visit_item(e: env, i: @ast::item) {
147147

148148
let cstore = e.cstore;
149149
let mut already_added = false;
150-
let link_args = attr::find_attrs_by_name(/*bad*/copy i.attrs,
151-
~"link_args");
150+
let link_args = attr::find_attrs_by_name(i.attrs, "link_args");
152151

153152
match fm.sort {
154153
ast::named => {

src/librustc/middle/lint.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,7 @@ impl ctxt {
329329
for [allow, warn, deny, forbid].each |level| {
330330
let level_name = level_to_str(*level);
331331
let metas =
332-
attr::attr_metas(attr::find_attrs_by_name(/*bad*/copy attrs,
333-
level_name));
332+
attr::attr_metas(attr::find_attrs_by_name(attrs, level_name));
334333
for metas.each |meta| {
335334
match /*bad*/copy meta.node {
336335
ast::meta_list(_, metas) => {

src/librustc/middle/trans/base.rs

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use core::uint;
7676
use std::map::HashMap;
7777
use std::smallintmap;
7878
use std::{map, time, list};
79-
use syntax::ast_map::{path, path_mod, path_name};
79+
use syntax::ast_map::{path, path_elt_to_str, path_mod, path_name};
8080
use syntax::ast_util::{def_id_of_def, local_def, path_to_ident};
8181
use syntax::attr;
8282
use syntax::codemap::span;
@@ -2086,28 +2086,44 @@ fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef {
20862086
fn register_fn(ccx: @crate_ctxt,
20872087
sp: span,
20882088
+path: path,
2089-
node_id: ast::node_id)
2089+
node_id: ast::node_id,
2090+
attrs: &[ast::attribute])
20902091
-> ValueRef {
20912092
let t = ty::node_id_to_type(ccx.tcx, node_id);
2092-
register_fn_full(ccx, sp, path, node_id, t)
2093+
register_fn_full(ccx, sp, path, node_id, attrs, t)
20932094
}
20942095

2095-
fn register_fn_full(ccx: @crate_ctxt, sp: span, +path: path,
2096-
node_id: ast::node_id, node_type: ty::t) -> ValueRef {
2096+
fn register_fn_full(ccx: @crate_ctxt,
2097+
sp: span,
2098+
+path: path,
2099+
node_id: ast::node_id,
2100+
attrs: &[ast::attribute],
2101+
node_type: ty::t)
2102+
-> ValueRef {
20972103
let llfty = type_of_fn_from_ty(ccx, node_type);
2098-
register_fn_fuller(ccx, sp, path, node_id, node_type,
2104+
register_fn_fuller(ccx, sp, path, node_id, attrs, node_type,
20992105
lib::llvm::CCallConv, llfty)
21002106
}
21012107

2102-
fn register_fn_fuller(ccx: @crate_ctxt, sp: span, +path: path,
2103-
node_id: ast::node_id, node_type: ty::t,
2104-
cc: lib::llvm::CallConv, llfty: TypeRef) -> ValueRef {
2108+
fn register_fn_fuller(ccx: @crate_ctxt,
2109+
sp: span,
2110+
+path: path,
2111+
node_id: ast::node_id,
2112+
attrs: &[ast::attribute],
2113+
node_type: ty::t,
2114+
cc: lib::llvm::CallConv,
2115+
llfty: TypeRef)
2116+
-> ValueRef {
21052117
debug!("register_fn_fuller creating fn for item %d with path %s",
21062118
node_id,
21072119
ast_map::path_to_str(path, ccx.sess.parse_sess.interner));
21082120

2109-
// XXX: Bad copy.
2110-
let ps: ~str = mangle_exported_name(ccx, copy path, node_type);
2121+
let ps = if attr::attrs_contains_name(attrs, "no_mangle") {
2122+
path_elt_to_str(path.last(), ccx.sess.parse_sess.interner)
2123+
} else {
2124+
mangle_exported_name(ccx, /*bad*/copy path, node_type)
2125+
};
2126+
21112127
// XXX: Bad copy.
21122128
let llfn: ValueRef = decl_fn(ccx.llmod, copy ps, cc, llfty);
21132129
ccx.item_symbols.insert(node_id, ps);
@@ -2281,9 +2297,13 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
22812297
}
22822298
ast::item_fn(_, purity, _, _) => {
22832299
let llfn = if purity != ast::extern_fn {
2284-
register_fn(ccx, i.span, my_path, i.id)
2300+
register_fn(ccx, i.span, my_path, i.id, i.attrs)
22852301
} else {
2286-
foreign::register_foreign_fn(ccx, i.span, my_path, i.id)
2302+
foreign::register_foreign_fn(ccx,
2303+
i.span,
2304+
my_path,
2305+
i.id,
2306+
i.attrs)
22872307
};
22882308
set_inline_hint_if_appr(/*bad*/copy i.attrs, llfn);
22892309
llfn
@@ -2315,7 +2335,8 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
23152335
register_fn(ccx, ni.span,
23162336
vec::append(/*bad*/copy *pth,
23172337
~[path_name(ni.ident)]),
2318-
ni.id)
2338+
ni.id,
2339+
ni.attrs)
23192340
}
23202341
ast::foreign_item_const(*) => {
23212342
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 {
23662387
path_name((*v).node.name)]);
23672388
llfn = match enm.node {
23682389
ast::item_enum(_, _) => {
2369-
register_fn(ccx, (*v).span, pth, id)
2390+
register_fn(ccx, (*v).span, pth, id, enm.attrs)
23702391
}
23712392
_ => fail ~"node_variant, shouldn't happen"
23722393
};
@@ -2390,8 +2411,11 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
23902411
a non-tuple-like struct")
23912412
}
23922413
Some(ctor_id) => {
2393-
let llfn = register_fn(ccx, struct_item.span,
2394-
/*bad*/copy *struct_path, ctor_id);
2414+
let llfn = register_fn(ccx,
2415+
struct_item.span,
2416+
/*bad*/copy *struct_path,
2417+
ctor_id,
2418+
struct_item.attrs);
23952419
set_inline_hint(llfn);
23962420
llfn
23972421
}
@@ -2416,7 +2440,7 @@ fn register_method(ccx: @crate_ctxt, id: ast::node_id, pth: @ast_map::path,
24162440
let mty = ty::node_id_to_type(ccx.tcx, id);
24172441
let pth = vec::append(/*bad*/copy *pth, ~[path_name((ccx.names)(~"meth")),
24182442
path_name(m.ident)]);
2419-
let llfn = register_fn_full(ccx, m.span, pth, id, mty);
2443+
let llfn = register_fn_full(ccx, m.span, pth, id, m.attrs, mty);
24202444
set_inline_hint_if_appr(/*bad*/copy m.attrs, llfn);
24212445
llfn
24222446
}

src/librustc/middle/trans/foreign.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -809,8 +809,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
809809
if abi != ast::foreign_abi_rust_intrinsic {
810810
let llwrapfn = get_item_val(ccx, id);
811811
let tys = c_stack_tys(ccx, id);
812-
if attr::attrs_contains_name(/*bad*/copy foreign_item.attrs,
813-
~"rust_stack") {
812+
if attr::attrs_contains_name(foreign_item.attrs, "rust_stack") {
814813
build_direct_fn(ccx, llwrapfn, *foreign_item, tys, cc);
815814
} else {
816815
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,
14791478
fn register_foreign_fn(ccx: @crate_ctxt,
14801479
sp: span,
14811480
+path: ast_map::path,
1482-
node_id: ast::node_id)
1481+
node_id: ast::node_id,
1482+
attrs: &[ast::attribute])
14831483
-> ValueRef {
14841484
let _icx = ccx.insn_ctxt("foreign::register_foreign_fn");
14851485
let t = ty::node_id_to_type(ccx.tcx, node_id);
@@ -1488,12 +1488,12 @@ fn register_foreign_fn(ccx: @crate_ctxt,
14881488
let ret_def = !ty::type_is_bot(ret_ty) && !ty::type_is_nil(ret_ty);
14891489
let x86_64 = x86_64_tys(llargtys, llretty, ret_def);
14901490
do decl_x86_64_fn(x86_64) |fnty| {
1491-
register_fn_fuller(ccx, sp, /*bad*/copy path, node_id,
1491+
register_fn_fuller(ccx, sp, /*bad*/copy path, node_id, attrs,
14921492
t, lib::llvm::CCallConv, fnty)
14931493
}
14941494
} else {
14951495
let llfty = T_fn(llargtys, llretty);
1496-
register_fn_fuller(ccx, sp, path, node_id,
1496+
register_fn_fuller(ccx, sp, path, node_id, attrs,
14971497
t, lib::llvm::CCallConv, llfty)
14981498
}
14991499
}

src/libsyntax/ast_map.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ fn path_to_str(p: path, itr: @ident_interner) -> ~str {
8080
path_to_str_with_sep(p, ~"::", itr)
8181
}
8282

83+
fn path_elt_to_str(pe: path_elt, itr: @ident_interner) -> ~str {
84+
match pe {
85+
path_mod(s) => *itr.get(s),
86+
path_name(s) => *itr.get(s)
87+
}
88+
}
89+
8390
enum ast_node {
8491
node_item(@item, @path),
8592
node_foreign_item(@foreign_item, foreign_abi, @path),

src/libsyntax/attr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ fn get_name_value_str_pair(item: @ast::meta_item) -> Option<(~str, ~str)> {
180180
/* Searching */
181181

182182
/// Search a list of attributes and return only those with a specific name
183-
fn find_attrs_by_name(attrs: ~[ast::attribute], name: &str) ->
183+
fn find_attrs_by_name(attrs: &[ast::attribute], name: &str) ->
184184
~[ast::attribute] {
185185
let filter: &fn(a: &ast::attribute) -> Option<ast::attribute> = |a| {
186186
if name == get_attr_name(*a) {
@@ -242,7 +242,7 @@ fn contains_name(metas: ~[@ast::meta_item], name: ~str) -> bool {
242242
return vec::len(matches) > 0u;
243243
}
244244

245-
fn attrs_contains_name(attrs: ~[ast::attribute], name: ~str) -> bool {
245+
fn attrs_contains_name(attrs: &[ast::attribute], name: &str) -> bool {
246246
vec::is_not_empty(find_attrs_by_name(attrs, name))
247247
}
248248

0 commit comments

Comments
 (0)