// Functions dealing with attributes and meta_items
-import std::{vec, map, option};
+import std::{either, vec, map, option};
import syntax::{ast, ast_util};
import driver::session;
export mk_list_item;
export mk_word_item;
export mk_attr;
+export native_abi;
// From a list of crate attributes get only the meta_items that impact crate
// linkage
}
}
+fn native_abi(attrs: [ast::attribute]) -> either::t<str, ast::native_abi> {
+ ret alt attr::get_meta_item_value_str_by_name(attrs, "abi") {
+ option::none. {
+ either::right(ast::native_abi_cdecl)
+ }
+ option::some("rust-intrinsic") {
+ either::right(ast::native_abi_rust_intrinsic)
+ }
+ option::some("cdecl") {
+ either::right(ast::native_abi_cdecl)
+ }
+ option::some("stdcall") {
+ either::right(ast::native_abi_stdcall)
+ }
+ option::some(t) {
+ either::left("unsupported abi: " + t)
+ }
+ };
+}
+
fn span<copy T>(item: T) -> ast::spanned<T> {
ret {node: item, span: ast_util::dummy_sp()};
}
fld: fold::ast_fold) -> ast::native_mod {
let filter = bind filter_native_item(cfg, _);
let filtered_items = vec::filter_map(filter, nm.items);
- ret {abi: nm.abi,
- view_items: vec::map(fld.fold_view_item, nm.view_items),
+ ret {view_items: vec::map(fld.fold_view_item, nm.view_items),
items: filtered_items};
}
import syntax::visit;
import syntax::codemap::span;
import util::{filesearch};
-import std::{vec, str, fs, io, option};
+import std::{either, vec, str, fs, io, option};
import std::option::{none, some};
import std::map::{hashmap, new_int_hash};
import syntax::print::pprust;
fn visit_item(e: env, i: @ast::item) {
alt i.node {
ast::item_native_mod(m) {
- if m.abi != ast::native_abi_cdecl &&
- m.abi != ast::native_abi_stdcall {
- ret;
+ alt attr::native_abi(i.attrs) {
+ either::right(abi) {
+ if abi != ast::native_abi_cdecl &&
+ abi != ast::native_abi_stdcall { ret; }
+ }
+ either::left(msg) { e.sess.span_fatal(i.span, msg); }
}
let cstore = e.sess.get_cstore();
let native_name = i.ident;
func.cs);
}
'N' {
- let abi;
- alt next(st) as char {
- 'i' { abi = ast::native_abi_rust_intrinsic; }
- 'C' { abi = ast::native_abi_cdecl; }
- 'S' { abi = ast::native_abi_stdcall; }
- }
let func = parse_ty_fn(st, sd);
- ret ty::mk_native_fn(st.tcx, abi, func.args, func.ty);
+ ret ty::mk_native_fn(st.tcx, func.args, func.ty);
}
'O' {
assert (next(st) as char == '[');
enc_proto(w, proto);
enc_ty_fn(w, cx, args, out, cf, constrs);
}
- ty::ty_native_fn(abi, args, out) {
+ ty::ty_native_fn(args, out) {
w.write_char('N');
- alt abi {
- native_abi_rust_intrinsic. { w.write_char('i'); }
- native_abi_cdecl. { w.write_char('C'); }
- native_abi_stdcall. { w.write_char('S'); }
- }
enc_ty_fn(w, cx, args, out, return_val, []);
}
ty::ty_obj(methods) {
ty::ty_ptr(_) { 1u }
ty::ty_box(_) { 3u }
ty::ty_constr(t, _) | ty::ty_res(_, t, _) { score_ty(tcx, t) }
- ty::ty_fn(_, _, _, _, _) | ty::ty_native_fn(_, _, _) |
+ ty::ty_fn(_, _, _, _, _) | ty::ty_native_fn(_, _) |
ty::ty_obj(_) { 4u }
ty::ty_str. | ty::ty_vec(_) | ty::ty_param(_, _) { 50u }
ty::ty_uniq(mt) { 1u + score_ty(tcx, mt.ty) }
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_fn(_, _, _, _, _) |
- ty::ty_native_fn(_, _, _) | ty::ty_obj(_) | ty::ty_param(_, _) |
+ ty::ty_native_fn(_, _) | ty::ty_obj(_) | ty::ty_param(_, _) |
ty::ty_res(_, _, _) {
ret true;
}
ty::ty_fn(_, _, _, _, _) {
s += [shape_fn];
}
- ty::ty_native_fn(_, _, _) { s += [shape_u32]; }
+ ty::ty_native_fn(_, _) { s += [shape_u32]; }
ty::ty_obj(_) { s += [shape_obj]; }
// pcwalton). You can, instead, find out its TypeRef by calling val_ty,
// but many TypeRefs correspond to one ty::t; for instance, tup(int, int,
// int) and rec(x=int, y=int, z=int) will have the same TypeRef.
-import std::{str, uint, map, option, time, vec};
+import std::{either, str, uint, map, option, time, vec};
import std::map::hashmap;
import std::map::{new_int_hash, new_str_hash};
import std::option::{some, none};
check returns_non_ty_var(cx, t);
T_fn_pair(cx, type_of_fn_from_ty(cx, sp, t, 0u))
}
- ty::ty_native_fn(abi, args, out) {
+ ty::ty_native_fn(args, out) {
let nft = native_fn_wrapper_type(cx, sp, 0u, t);
T_fn_pair(cx, nft)
}
let cx = lcx.ccx;
let t = tpt.ty;
alt ty::struct(cx.tcx, t) {
- ty::ty_fn(_, _, _, _, _) | ty::ty_native_fn(_, _, _) {
+ ty::ty_fn(_, _, _, _, _) | ty::ty_native_fn(_, _) {
check returns_non_ty_var(cx, t);
ret type_of_fn_from_ty(cx, sp, t, std::vec::len(tpt.kinds));
}
}
ret next_cx;
}
- ty::ty_fn(_, _, _, _, _) | ty::ty_native_fn(_, _, _) {
+ ty::ty_fn(_, _, _, _, _) | ty::ty_native_fn(_, _) {
let box_cell_a = GEPi(cx, av, [0, abi::fn_field_box]);
ret iter_boxpp(cx, box_cell_a, f);
}
sp: span,
id: ast::node_id) -> @c_stack_tys {
alt ty::struct(ccx.tcx, ty::node_id_to_type(ccx.tcx, id)) {
- ty::ty_native_fn(_, arg_tys, ret_ty) {
+ ty::ty_native_fn(arg_tys, ret_ty) {
let tcx = ccx.tcx;
let llargtys = type_of_explicit_args(ccx, sp, arg_tys);
check non_ty_var(ccx, ret_ty); // NDM does this truly hold?
// stack pointer appropriately to avoid a round of copies. (In fact, the shim
// function itself is unnecessary). We used to do this, in fact, and will
// perhaps do so in the future.
-fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod) {
+fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod,
+ abi: ast::native_abi) {
fn build_shim_fn(lcx: @local_ctxt,
native_item: @ast::native_item,
tys: @c_stack_tys,
let ccx = lcx_ccx(lcx);
let cc: uint = lib::llvm::LLVMCCallConv;
- alt native_mod.abi {
+ alt abi {
ast::native_abi_rust_intrinsic. { ret; }
ast::native_abi_cdecl. { cc = lib::llvm::LLVMCCallConv; }
ast::native_abi_stdcall. { cc = lib::llvm::LLVMX86StdcallCallConv; }
}
ast::item_const(_, expr) { trans_const(cx.ccx, expr, item.id); }
ast::item_native_mod(native_mod) {
- trans_native_mod(cx, native_mod);
+ let abi = alt attr::native_abi(item.attrs) {
+ either::right(abi_) { abi_ }
+ either::left(msg) { cx.ccx.sess.span_fatal(item.span, msg) }
+ };
+ trans_native_mod(cx, native_mod, abi);
}
_ {/* fall through */ }
}
}
-
// Translate a module. Doing this amounts to translating the items in the
// module; there ends up being no artifact (aside from linkage names) of
// separate modules in the compiled program. That's because modules exist
fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span, ty_param_count: uint,
x: ty::t) -> TypeRef {
alt ty::struct(cx.tcx, x) {
- ty::ty_native_fn(abi, args, out) {
+ ty::ty_native_fn(args, out) {
check non_ty_var(cx, out);
ret type_of_fn(cx, sp, false, false, args, out, ty_param_count);
}
}
}
-fn collect_native_item(ccx: @crate_ctxt, i: @ast::native_item, &&pt: [str],
+fn collect_native_item(ccx: @crate_ctxt,
+ abi: @mutable option::t<ast::native_abi>,
+ i: @ast::native_item,
+ &&pt: [str],
_v: vt<[str]>) {
alt i.node {
ast::native_item_fn(_, tps) {
let sp = i.span;
let id = i.id;
let node_type = node_id_type(ccx, id);
- // FIXME NDM abi should come from attr
- let abi = ty::ty_fn_abi(ccx.tcx, node_type);
-
- alt abi {
+ let fn_abi =
+ alt attr::get_meta_item_value_str_by_name(i.attrs, "abi") {
+ option::none. {
+ // if abi isn't specified for this function, inherit from
+ // its enclosing native module
+ option::get(*abi)
+ }
+ _ {
+ alt attr::native_abi(i.attrs) {
+ either::right(abi_) { abi_ }
+ either::left(msg) { ccx.sess.span_fatal(i.span, msg) }
+ }
+ }
+ };
+ alt fn_abi {
ast::native_abi_rust_intrinsic. {
// For intrinsics: link the function directly to the intrinsic
// function itself.
}
}
-fn collect_item_1(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
- v: vt<[str]>) {
- visit::visit_item(i, pt + item_path(i), v);
+fn collect_item_1(ccx: @crate_ctxt, abi: @mutable option::t<ast::native_abi>,
+ i: @ast::item, &&pt: [str], v: vt<[str]>) {
alt i.node {
ast::item_const(_, _) {
let typ = node_id_type(ccx, i.id);
ccx.item_symbols.insert(i.id, s);
ccx.consts.insert(i.id, g);
}
+ ast::item_native_mod(native_mod) {
+ // Propagate the native ABI down to collect_native_item(),
+ alt attr::native_abi(i.attrs) {
+ either::left(msg) { ccx.sess.span_fatal(i.span, msg); }
+ either::right(abi_) {
+ *abi = option::some(abi_);
+ }
+ }
+ }
_ { }
}
+ visit::visit_item(i, pt + item_path(i), v);
}
fn collect_item_2(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
}
fn collect_items(ccx: @crate_ctxt, crate: @ast::crate) {
+ let abi = @mutable none::<ast::native_abi>;
let visitor0 = visit::default_visitor();
let visitor1 =
- @{visit_native_item: bind collect_native_item(ccx, _, _, _),
- visit_item: bind collect_item_1(ccx, _, _, _) with *visitor0};
+ @{visit_native_item: bind collect_native_item(ccx, abi, _, _, _),
+ visit_item: bind collect_item_1(ccx, abi, _, _, _) with *visitor0};
let visitor2 =
@{visit_item: bind collect_item_2(ccx, _, _, _) with *visitor0};
visit::visit_crate(*crate, [], visit::mk_vt(visitor1));
ty::type_autoderef(fcx.ccx.tcx,
ty::node_id_to_type(fcx.ccx.tcx, callee));
alt ty::struct(fcx.ccx.tcx, ty) {
- ty::ty_fn(_, args, _, _, _) | ty::ty_native_fn(_, args, _) {
+ ty::ty_fn(_, args, _, _, _) | ty::ty_native_fn(args, _) {
let modes = [];
for arg: ty::arg in args { modes += [arg.mode]; }
ret modes;
export ty_constr_arg;
export ty_float;
export ty_fn;
-export ty_fn_abi;
export ty_fn_proto;
export ty_fn_ret;
export ty_fn_ret_style;
ty_ptr(mt);
ty_rec([field]);
ty_fn(ast::proto, [arg], t, ret_style, [@constr]);
- ty_native_fn(ast::native_abi, [arg], t);
+ ty_native_fn([arg], t);
ty_obj([method]);
ty_res(def_id, t, [t]);
ty_tup([t]);
ty_fn(_, args, tt, _, _) {
derive_flags_sig(cx, has_params, has_vars, args, tt);
}
- ty_native_fn(_, args, tt) {
+ ty_native_fn(args, tt) {
derive_flags_sig(cx, has_params, has_vars, args, tt);
}
ty_obj(meths) {
ret gen_ty(cx, ty_fn(proto, args, ty, cf, constrs));
}
-fn mk_native_fn(cx: ctxt, abi: ast::native_abi, args: [arg], ty: t) -> t {
- ret gen_ty(cx, ty_native_fn(abi, args, ty));
+fn mk_native_fn(cx: ctxt, args: [arg], ty: t) -> t {
+ ret gen_ty(cx, ty_native_fn(args, ty));
}
fn mk_obj(cx: ctxt, meths: [method]) -> t { ret gen_ty(cx, ty_obj(meths)); }
for a: arg in args { walk_ty(cx, walker, a.ty); }
walk_ty(cx, walker, ret_ty);
}
- ty_native_fn(abi, args, ret_ty) {
+ ty_native_fn(args, ret_ty) {
for a: arg in args { walk_ty(cx, walker, a.ty); }
walk_ty(cx, walker, ret_ty);
}
mk_fn(cx, proto, new_args, fold_ty(cx, fld, ret_ty),
cf, constrs), ty);
}
- ty_native_fn(abi, args, ret_ty) {
+ ty_native_fn(args, ret_ty) {
let new_args: [arg] = [];
for a: arg in args {
let new_ty = fold_ty(cx, fld, a.ty);
}
ty =
copy_cname(cx,
- mk_native_fn(cx, abi, new_args,
+ mk_native_fn(cx, new_args,
fold_ty(cx, fld, ret_ty)), ty);
}
ty_obj(methods) {
ty_tup(_) { ret true; }
ty_tag(_, _) { ret true; }
ty_fn(_, _, _, _, _) { ret true; }
- ty_native_fn(_, _, _) { ret true; }
+ ty_native_fn(_, _) { ret true; }
ty_obj(_) { ret true; }
ty_res(_, _, _) { ret true; }
_ { ret false; }
// Scalar and unique types are sendable
ty_nil. | ty_bot. | ty_bool. | ty_int. | ty_uint. | ty_float. |
ty_machine(_) | ty_char. | ty_native(_) |
- ty_type. | ty_str. | ty_native_fn(_, _, _) { ast::kind_sendable }
+ ty_type. | ty_str. | ty_native_fn(_, _) { ast::kind_sendable }
// FIXME: obj is broken for now, since we aren't asserting
// anything about its fields.
ty_obj(_) { kind_copyable }
}
// Boxed types
ty_str. | ty_box(_) | ty_uniq(_) | ty_vec(_) | ty_fn(_, _, _, _, _) |
- ty_native_fn(_, _, _) | ty_obj(_) {
+ ty_native_fn(_, _) | ty_obj(_) {
result = false;
}
// Structural types
ty_fn(_, args, rty, _, _) {
ret hash_fn(27u, args, rty);
}
- ty_native_fn(_, args, rty) { ret hash_fn(28u, args, rty); }
+ ty_native_fn(args, rty) { ret hash_fn(28u, args, rty); }
ty_obj(methods) {
let h = 29u;
for m: method in methods { h += h << 5u + str::hash(m.ident); }
fn ty_fn_args(cx: ctxt, fty: t) -> [arg] {
alt struct(cx, fty) {
ty::ty_fn(_, a, _, _, _) { ret a; }
- ty::ty_native_fn(_, a, _) { ret a; }
+ ty::ty_native_fn(a, _) { ret a; }
_ { cx.sess.bug("ty_fn_args() called on non-fn type"); }
}
}
fn ty_fn_proto(cx: ctxt, fty: t) -> ast::proto {
alt struct(cx, fty) {
ty::ty_fn(p, _, _, _, _) { ret p; }
- ty::ty_native_fn(_, _, _) {
+ ty::ty_native_fn(_, _) {
// FIXME: This should probably be proto_bare
ret ast::proto_shared(ast::sugar_normal);
}
}
}
-fn ty_fn_abi(cx: ctxt, fty: t) -> ast::native_abi {
- alt struct(cx, fty) {
- ty::ty_native_fn(a, _, _) { ret a; }
- _ { cx.sess.bug("ty_fn_abi() called on non-native-fn type"); }
- }
-}
-
pure fn ty_fn_ret(cx: ctxt, fty: t) -> t {
let sty = struct(cx, fty);
alt sty {
ty::ty_fn(_, _, r, _, _) { ret r; }
- ty::ty_native_fn(_, _, r) { ret r; }
+ ty::ty_native_fn(_, r) { ret r; }
_ {
// Unchecked is ok since we diverge here
// (might want to change the typechecker to allow
fn ty_fn_ret_style(cx: ctxt, fty: t) -> ast::ret_style {
alt struct(cx, fty) {
ty::ty_fn(_, _, _, rs, _) { rs }
- ty::ty_native_fn(_, _, _) { ast::return_val }
+ ty::ty_native_fn(_, _) { ast::return_val }
_ { cx.sess.bug("ty_fn_ret_style() called on non-fn type"); }
}
}
fn is_fn_ty(cx: ctxt, fty: t) -> bool {
alt struct(cx, fty) {
ty::ty_fn(_, _, _, _, _) { ret true; }
- ty::ty_native_fn(_, _, _) { ret true; }
+ ty::ty_native_fn(_, _) { ret true; }
_ { ret false; }
}
}
}
}
}
- fn unify_native_fn(cx: @ctxt, e_abi: ast::native_abi,
- a_abi: ast::native_abi, expected: t, actual: t,
+ fn unify_native_fn(cx: @ctxt, expected: t, actual: t,
expected_inputs: [arg], expected_output: t,
actual_inputs: [arg], actual_output: t,
variance: variance) -> result {
- if e_abi != a_abi { ret ures_err(terr_mismatch); }
let t =
unify_fn_common(cx, expected, actual, expected_inputs,
expected_output, actual_inputs, actual_output,
alt t {
fn_common_res_err(r) { ret r; }
fn_common_res_ok(result_ins, result_out) {
- let t2 = mk_native_fn(cx.tcx, e_abi, result_ins, result_out);
+ let t2 = mk_native_fn(cx.tcx, result_ins, result_out);
ret ures_ok(t2);
}
}
_ { ret ures_err(terr_mismatch); }
}
}
- ty::ty_native_fn(e_abi, expected_inputs, expected_output) {
+ ty::ty_native_fn(expected_inputs, expected_output) {
alt struct(cx.tcx, actual) {
- ty::ty_native_fn(a_abi, actual_inputs, actual_output) {
- ret unify_native_fn(cx, e_abi, a_abi, expected, actual,
+ ty::ty_native_fn(actual_inputs, actual_output) {
+ ret unify_native_fn(cx, expected, actual,
expected_inputs, expected_output,
actual_inputs, actual_output, variance);
}
}
fn ty_of_native_fn_decl(cx: @ctxt, convert: fn@(&&@ast::ty) -> ty::t,
ty_of_arg: fn@(ast::arg) -> arg,
- decl: ast::fn_decl, abi: ast::native_abi,
+ decl: ast::fn_decl,
ty_params: [ast::ty_param], def_id: ast::def_id)
-> ty::ty_param_kinds_and_ty {
let input_tys = [];
for a: ast::arg in decl.inputs { input_tys += [ty_of_arg(a)]; }
let output_ty = convert(decl.output);
- let t_fn = ty::mk_native_fn(cx.tcx, abi, input_tys, output_ty);
+ let t_fn = ty::mk_native_fn(cx.tcx, input_tys, output_ty);
let tpt = {kinds: ty_param_kinds(ty_params), ty: t_fn};
cx.tcx.tcache.insert(def_id, tpt);
ret tpt;
alt it {
some(ast_map::node_item(item)) { tpt = ty_of_item(cx, item); }
some(ast_map::node_native_item(native_item)) {
- tpt = ty_of_native_item(cx, native_item,
- ast::native_abi_cdecl);
+ tpt = ty_of_native_item(cx, native_item);
}
_ { cx.tcx.sess.fatal("internal error " + std::int::str(id.node)); }
}
ast::item_native_mod(_) { fail; }
}
}
- fn ty_of_native_item(cx: @ctxt, it: @ast::native_item,
- abi: ast::native_abi) -> ty::ty_param_kinds_and_ty {
+ fn ty_of_native_item(cx: @ctxt, it: @ast::native_item)
+ -> ty::ty_param_kinds_and_ty {
let no_kinds: [ast::kind] = [];
alt it.node {
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, _);
- ret ty_of_native_fn_decl(cx, convert, f, fn_decl, abi, params,
+ ret ty_of_native_fn_decl(cx, convert, f, fn_decl, params,
ast_util::local_def(it.id));
}
ast::native_item_ty. {
}
ret meths;
}
- fn convert(cx: @ctxt, abi: @mutable option::t<ast::native_abi>,
- it: @ast::item) {
+ fn convert(cx: @ctxt, it: @ast::item) {
alt it.node {
ast::item_mod(_) {
// ignore item_mod, it has no type.
}
ast::item_native_mod(native_mod) {
- // Propagate the native ABI down to convert_native() below,
- // but otherwise do nothing, as native modules have no types.
- *abi = some::<ast::native_abi>(native_mod.abi);
+ // do nothing, as native modules have no types.
}
ast::item_tag(variants, ty_params) {
let tpt = ty_of_item(cx, it);
}
}
}
- fn convert_native(cx: @ctxt, abi: @mutable option::t<ast::native_abi>,
- i: @ast::native_item) {
+ fn convert_native(cx: @ctxt, i: @ast::native_item) {
// As above, this call populates the type table with the converted
// type of the native item. We simply write it into the node type
// table.
- let tpt =
- ty_of_native_item(cx, i,
- option::get::<ast::native_abi>({ *abi }));
+ let tpt = ty_of_native_item(cx, i);
alt i.node {
ast::native_item_ty. {
// FIXME: Native types have no annotation. Should they? --pcw
}
}
fn collect_item_types(tcx: ty::ctxt, crate: @ast::crate) {
- // We have to propagate the surrounding ABI to the native items
- // contained within the native module.
- let abi = @mutable none::<ast::native_abi>;
let cx = @{tcx: tcx};
let visit =
- visit::mk_simple_visitor(@{visit_item: bind convert(cx, abi, _),
+ visit::mk_simple_visitor(@{visit_item: bind convert(cx, _),
visit_native_item:
- bind convert_native(cx, abi, _)
+ bind convert_native(cx, _)
with
*visit::default_simple_visitor()});
visit::visit_crate(*crate, (), visit);
// Grab the argument types
let arg_tys =
alt sty {
- ty::ty_fn(_, arg_tys, _, _, _) | ty::ty_native_fn(_, arg_tys, _)
+ ty::ty_fn(_, arg_tys, _, _, _) | ty::ty_native_fn(arg_tys, _)
{
arg_tys
}
bot |= cf == ast::noreturn;
rt_1 = rt;
}
- ty::ty_native_fn(_, _, rt) { rt_1 = rt; }
+ ty::ty_native_fn(_, rt) { rt_1 = rt; }
_ { fcx.ccx.tcx.sess.span_fatal(sp, "calling non-function"); }
}
write::ty_only_fixup(fcx, id, rt_1);
cf = cf_;
constrs = constrs_;
}
- ty::ty_native_fn(_, arg_tys_, rt_) {
+ ty::ty_native_fn(arg_tys_, rt_) {
proto = ast::proto_bare;
arg_tys = arg_tys_;
rt = rt_;
}
type native_mod =
- {// FIXME: Removing abi from AST. Depends on Issue #1179.
- abi: native_abi,
- view_items: [@view_item],
+ {view_items: [@view_item],
items: [@native_item]};
type variant_arg = {ty: @ty, id: node_id};
}
fn noop_fold_native_mod(nm: native_mod, fld: ast_fold) -> native_mod {
- ret {abi: nm.abi,
- view_items: vec::map(fld.fold_view_item, nm.view_items),
+ ret {view_items: vec::map(fld.fold_view_item, nm.view_items),
items: vec::map(fld.fold_native_item, nm.items)}
}
} else { unexpected(p, p.peek()); }
}
-fn parse_native_mod_items(p: parser, abi: ast::native_abi,
- first_item_attrs: [ast::attribute]) ->
+fn parse_native_mod_items(p: parser, first_item_attrs: [ast::attribute]) ->
ast::native_mod {
// Shouldn't be any view items since we've already parsed an item attr
let view_items =
initial_attrs = [];
items += [parse_native_item(p, attrs)];
}
- ret {abi: abi,
- view_items: view_items,
+ ret {view_items: view_items,
items: items};
}
let more_attrs = parse_inner_attrs_and_next(p);
let inner_attrs = more_attrs.inner;
let first_item_outer_attrs = more_attrs.next;
- let abi =
- alt attr::get_meta_item_value_str_by_name(
- attrs + inner_attrs, "abi") {
- none. { ast::native_abi_cdecl }
- some("rust-intrinsic") {
- ast::native_abi_rust_intrinsic
- }
- some("cdecl") {
- ast::native_abi_cdecl
- }
- some("stdcall") {
- ast::native_abi_stdcall
- }
- some(t) {
- p.fatal("unsupported abi: " + t);
- }
- };
- let m = parse_native_mod_items(p, abi, first_item_outer_attrs);
+ let m = parse_native_mod_items(p, first_item_outer_attrs);
let hi = p.get_hi_pos();
expect(p, token::RBRACE);
ret mk_item(p, lo, hi, id, ast::item_native_mod(m), attrs + inner_attrs);
ty_fn(proto, inputs, output, cf, constrs) {
fn_to_str(cx, proto, none, inputs, output, cf, constrs)
}
- ty_native_fn(_, inputs, output) {
+ ty_native_fn(inputs, output) {
fn_to_str(cx, ast::proto_bare, none, inputs, output,
ast::return_val, [])
}