From 3b683f52052b0cbf514c89a4da08df2b8e017fd4 Mon Sep 17 00:00:00 2001 From: Haitao Li Date: Mon, 14 Nov 2011 21:06:39 +0800 Subject: [PATCH] rustc: Use link_name attribute for native function Fixes issue #906 --- src/comp/front/attr.rs | 10 ++++++++++ src/comp/metadata/encoder.rs | 2 +- src/comp/middle/resolve.rs | 4 ++-- src/comp/middle/trans.rs | 16 ++++++++-------- src/comp/middle/typeck.rs | 4 ++-- src/comp/syntax/ast.rs | 2 +- src/comp/syntax/fold.rs | 5 ++--- src/comp/syntax/parse/parser.rs | 4 +--- src/comp/syntax/print/pprust.rs | 6 +----- src/comp/syntax/visit.rs | 2 +- src/lib/win32_os.rs | 6 ++++-- src/test/run-pass/native-fn-linkname.rs | 3 ++- 12 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/comp/front/attr.rs b/src/comp/front/attr.rs index 34b1e5c430b..ff1633212f7 100644 --- a/src/comp/front/attr.rs +++ b/src/comp/front/attr.rs @@ -17,6 +17,7 @@ export get_attr_name; export get_meta_item_name; export get_meta_item_value_str; +export get_meta_item_value_str_by_name; export get_meta_item_list; export mk_name_value_item_str; export mk_name_value_item; @@ -85,6 +86,15 @@ fn get_meta_item_value_str(meta: @ast::meta_item) -> option::t { } } +fn get_meta_item_value_str_by_name(attrs: [ast::attribute], name: ast::ident) + -> option::t { + let mattrs = find_attrs_by_name(attrs, name); + if vec::len(mattrs) > 0u { + ret get_meta_item_value_str(attr_meta(mattrs[0])); + } + ret option::none; +} + fn get_meta_item_list(meta: @ast::meta_item) -> option::t<[@ast::meta_item]> { alt meta.node { ast::meta_list(_, l) { option::some(l) } diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index ec4e57ae56b..73da789b505 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -348,7 +348,7 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer, encode_type(ecx, ebml_w, ty::mk_native(ecx.ccx.tcx, local_def(nitem.id))); } - native_item_fn(_, fn_decl, tps) { + native_item_fn(fn_decl, tps) { let letter = alt fn_decl.purity { unsafe_fn. { 'U' } diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index aa5d5ebaaa4..ff9ee2a504f 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -656,7 +656,7 @@ fn in_scope(e: env, sp: span, name: ident, s: scope, ns: namespace) -> } scope_native_item(it) { alt it.node { - ast::native_item_fn(_, decl, ty_params) { + ast::native_item_fn(decl, ty_params) { ret lookup_in_fn(name, decl, ty_params, ns); } } @@ -1077,7 +1077,7 @@ fn lookup_in_mie(e: env, mie: mod_index_entry, ns: namespace) -> ret some(ast::def_native_ty(local_def(native_item.id))); } } - ast::native_item_fn(_, decl, _) { + ast::native_item_fn(decl, _) { if ns == ns_value { ret some(ast::def_native_fn( local_def(native_item.id), diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index e9e58cf52bb..823d9306ce2 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -17,6 +17,7 @@ import std::map::{new_int_hash, new_str_hash}; import std::option::{some, none}; import driver::session; +import front::attr; import middle::{ty, gc}; import middle::freevars::*; import back::{link, abi, upcall}; @@ -5585,7 +5586,7 @@ fn native_fn_ty_param_count(cx: @crate_ctxt, id: ast::node_id) -> uint { cx.sess.bug("register_native_fn(): native fn isn't \ actually a fn"); } - ast::native_item_fn(_, _, tps) { + ast::native_item_fn(_, tps) { count = std::vec::len::(tps); } } @@ -5805,14 +5806,13 @@ fn trans_simple_native_abi(bcx: @block_ctxt, name: str, fn collect_native_item(ccx: @crate_ctxt, i: @ast::native_item, &&pt: [str], _v: vt<[str]>) { alt i.node { - ast::native_item_fn(link_name, _, _) { + ast::native_item_fn(_, _) { if !ccx.obj_methods.contains_key(i.id) { - let name = - if option::is_some(link_name) { - option::get(link_name) - } else { - i.ident - }; + let name = i.ident; + alt attr::get_meta_item_value_str_by_name(i.attrs, "link_name") { + none. { } + option::some(ln) { name = ln; } + } register_native_fn(ccx, i.span, pt, name, i.id); } } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index fabd2b069bd..8436d761882 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -668,7 +668,7 @@ fn ty_of_native_item(cx: @ctxt, it: @ast::native_item, abi: ast::native_abi) -> ty::ty_param_kinds_and_ty { let no_kinds: [ast::kind] = []; alt it.node { - ast::native_item_fn(_, fn_decl, params) { + ast::native_item_fn(fn_decl, params) { let get = bind getter(cx, _); let convert = bind ast_ty_to_ty(cx.tcx, get, _); let f = bind ty_of_arg(cx, _); @@ -819,7 +819,7 @@ fn convert_native(cx: @ctxt, abi: @mutable option::t, ast::native_item_ty. { // FIXME: Native types have no annotation. Should they? --pcw } - ast::native_item_fn(_, _, _) { + ast::native_item_fn(_, _) { write::ty_only(cx.tcx, i.id, tpt.ty); } } diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index ebac944d64a..16d0d0d53c8 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -501,7 +501,7 @@ tag native_item_ { native_item_ty; - native_item_fn(option::t, fn_decl, [ty_param]); + native_item_fn(fn_decl, [ty_param]); } // diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs index 126487aed98..56e6aecbab1 100644 --- a/src/comp/syntax/fold.rs +++ b/src/comp/syntax/fold.rs @@ -187,9 +187,8 @@ fn noop_fold_native_item(&&ni: @native_item, fld: ast_fold) -> @native_item { node: alt ni.node { native_item_ty. { native_item_ty } - native_item_fn(st, fdec, typms) { - native_item_fn(st, - {inputs: vec::map(fold_arg, fdec.inputs), + native_item_fn(fdec, typms) { + native_item_fn({inputs: vec::map(fold_arg, fdec.inputs), output: fld.fold_ty(fdec.output), purity: fdec.purity, il: fdec.il, diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 4fa5baa7af4..bb5bf4f7faa 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -1956,13 +1956,11 @@ fn parse_item_native_fn(p: parser, attrs: [ast::attribute], let lo = p.get_last_lo_pos(); let t = parse_fn_header(p); let decl = parse_fn_decl(p, purity, ast::il_normal); - let link_name = none; - if p.peek() == token::EQ { p.bump(); link_name = some(parse_str(p)); } let hi = p.get_hi_pos(); expect(p, token::SEMI); ret @{ident: t.ident, attrs: attrs, - node: ast::native_item_fn(link_name, decl, t.tps), + node: ast::native_item_fn(decl, t.tps), id: p.get_id(), span: ast_util::mk_sp(lo, hi)}; } diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index d45c8a8a43a..21cfaa9e072 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -350,13 +350,9 @@ fn print_native_item(s: ps, item: @ast::native_item) { - ast::native_item_fn(lname, decl, typarams) { + ast::native_item_fn(decl, typarams) { print_fn(s, decl, ast::proto_bare, item.ident, typarams, decl.constraints); - alt lname { - none. { } - some(ss) { space(s.s); word_space(s, "="); print_string(s, ss); } - } end(s); // end head-ibox word(s.s, ";"); end(s); // end the outer fn box diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs index 0725611eb04..0ad6ea2fca2 100644 --- a/src/comp/syntax/visit.rs +++ b/src/comp/syntax/visit.rs @@ -179,7 +179,7 @@ fn visit_pat(p: @pat, e: E, v: vt) { fn visit_native_item(ni: @native_item, e: E, v: vt) { alt ni.node { - native_item_fn(_, fd, _) { visit_fn_decl(fd, e, v); } + native_item_fn(fd, _) { visit_fn_decl(fd, e, v); } native_item_ty. { } } } diff --git a/src/lib/win32_os.rs b/src/lib/win32_os.rs index 3779058cd7b..006dd17fa23 100644 --- a/src/lib/win32_os.rs +++ b/src/lib/win32_os.rs @@ -4,8 +4,10 @@ fn write(fd: int, buf: *u8, count: uint) -> int; fn fread(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; fn fwrite(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; - fn open(s: str::sbuf, flags: int, mode: uint) -> int = "_open"; - fn close(fd: int) -> int = "_close"; + #[link_name = "_open"] + fn open(s: str::sbuf, flags: int, mode: uint) -> int; + #[link_name = "_close"] + fn close(fd: int) -> int; type FILE; fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE; fn _fdopen(fd: int, mode: str::sbuf) -> FILE; diff --git a/src/test/run-pass/native-fn-linkname.rs b/src/test/run-pass/native-fn-linkname.rs index 7cd4a86bba2..5dc6faac898 100644 --- a/src/test/run-pass/native-fn-linkname.rs +++ b/src/test/run-pass/native-fn-linkname.rs @@ -4,7 +4,8 @@ import std::str; native "cdecl" mod libc = "" { - fn my_strlen(str: *u8) -> uint = "strlen"; + #[link_name = "strlen"] + fn my_strlen(str: *u8) -> uint; } fn strlen(str: str) -> uint unsafe { -- GitLab