1
Fork 0

syntax: Remove AbiSet, use one Abi

This change removes the AbiSet from the AST, converting all usage to have just
one Abi value. The current scheme selects a relevant ABI given a list of ABIs
based on the target architecture and how relevant each ABI is to that
architecture.

Instead of this mildly complicated scheme, only one ABI will be allowed in abi
strings, and pseudo-abis will be created for special cases as necessary. For
example the "system" abi exists for stdcall on win32 and C on win64.

Closes #10049
This commit is contained in:
Alex Crichton 2014-04-02 01:19:41 -07:00
parent 1a1c47b918
commit 57e0908af3
33 changed files with 205 additions and 460 deletions

View file

@ -90,7 +90,7 @@ fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod {
filter_view_item(cx, a).map(|x| cx.fold_view_item(x)) filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
}).collect(); }).collect();
ast::ForeignMod { ast::ForeignMod {
abis: nm.abis, abi: nm.abi,
view_items: filtered_view_items, view_items: filtered_view_items,
items: filtered_items items: filtered_items
} }

View file

@ -187,7 +187,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
fn visit_item(e: &Env, i: &ast::Item) { fn visit_item(e: &Env, i: &ast::Item) {
match i.node { match i.node {
ast::ItemForeignMod(ref fm) => { ast::ItemForeignMod(ref fm) => {
if fm.abis.is_rust() || fm.abis.is_intrinsic() { if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
return; return;
} }

View file

@ -33,7 +33,7 @@ use std::hash::Hash;
use std::io::MemWriter; use std::io::MemWriter;
use std::str; use std::str;
use collections::HashMap; use collections::HashMap;
use syntax::abi::AbiSet; use syntax::abi;
use syntax::ast::*; use syntax::ast::*;
use syntax::ast; use syntax::ast;
use syntax::ast_map::{PathElem, PathElems}; use syntax::ast_map::{PathElem, PathElems};
@ -1217,7 +1217,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
nitem: &ForeignItem, nitem: &ForeignItem,
index: @RefCell<Vec<entry<i64>> >, index: @RefCell<Vec<entry<i64>> >,
path: PathElems, path: PathElems,
abi: AbiSet) { abi: abi::Abi) {
index.borrow_mut().push(entry { index.borrow_mut().push(entry {
val: nitem.id as i64, val: nitem.id as i64,
pos: ebml_w.writer.tell().unwrap(), pos: ebml_w.writer.tell().unwrap(),
@ -1231,7 +1231,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
encode_bounds_and_type(ebml_w, ecx, encode_bounds_and_type(ebml_w, ecx,
&lookup_item_type(ecx.tcx,local_def(nitem.id))); &lookup_item_type(ecx.tcx,local_def(nitem.id)));
encode_name(ebml_w, nitem.ident.name); encode_name(ebml_w, nitem.ident.name);
if abi.is_intrinsic() { if abi == abi::RustIntrinsic {
(ecx.encode_inlined_item)(ecx, ebml_w, IIForeignRef(nitem)); (ecx.encode_inlined_item)(ecx, ebml_w, IIForeignRef(nitem));
} else { } else {
encode_symbol(ecx, ebml_w, nitem.id); encode_symbol(ecx, ebml_w, nitem.id);
@ -1279,11 +1279,11 @@ fn my_visit_foreign_item(ni: &ForeignItem,
let mut ebml_w = unsafe { let mut ebml_w = unsafe {
ebml_w.unsafe_clone() ebml_w.unsafe_clone()
}; };
let abis = ecx.tcx.map.get_foreign_abis(ni.id); let abi = ecx.tcx.map.get_foreign_abi(ni.id);
ecx.tcx.map.with_path(ni.id, |path| { ecx.tcx.map.with_path(ni.id, |path| {
encode_info_for_foreign_item(ecx, &mut ebml_w, encode_info_for_foreign_item(ecx, &mut ebml_w,
ni, index, ni, index,
path, abis); path, abi);
}); });
} }

View file

@ -20,7 +20,6 @@ use middle::ty;
use std::str; use std::str;
use std::uint; use std::uint;
use syntax::abi::AbiSet;
use syntax::abi; use syntax::abi;
use syntax::ast; use syntax::ast;
use syntax::ast::*; use syntax::ast::*;
@ -460,18 +459,12 @@ fn parse_purity(c: char) -> Purity {
} }
} }
fn parse_abi_set(st: &mut PState) -> AbiSet { fn parse_abi_set(st: &mut PState) -> abi::Abi {
assert_eq!(next(st), '['); assert_eq!(next(st), '[');
let mut abis = AbiSet::empty(); scan(st, |c| c == ']', |bytes| {
while peek(st) != ']' { let abi_str = str::from_utf8(bytes).unwrap().to_owned();
scan(st, |c| c == ',', |bytes| { abi::lookup(abi_str).expect(abi_str)
let abi_str = str::from_utf8(bytes).unwrap().to_owned(); })
let abi = abi::lookup(abi_str).expect(abi_str);
abis.add(abi);
});
}
assert_eq!(next(st), ']');
return abis;
} }
fn parse_onceness(c: char) -> ast::Onceness { fn parse_onceness(c: char) -> ast::Onceness {
@ -505,7 +498,7 @@ fn parse_bare_fn_ty(st: &mut PState, conv: conv_did) -> ty::BareFnTy {
let sig = parse_sig(st, |x,y| conv(x,y)); let sig = parse_sig(st, |x,y| conv(x,y));
ty::BareFnTy { ty::BareFnTy {
purity: purity, purity: purity,
abis: abi, abi: abi,
sig: sig sig: sig
} }
} }

View file

@ -23,7 +23,7 @@ use std::fmt;
use middle::ty::param_ty; use middle::ty::param_ty;
use middle::ty; use middle::ty;
use syntax::abi::AbiSet; use syntax::abi::Abi;
use syntax::ast; use syntax::ast;
use syntax::ast::*; use syntax::ast::*;
use syntax::diagnostic::SpanHandler; use syntax::diagnostic::SpanHandler;
@ -341,12 +341,9 @@ fn enc_purity(w: &mut MemWriter, p: Purity) {
} }
} }
fn enc_abi_set(w: &mut MemWriter, abis: AbiSet) { fn enc_abi(w: &mut MemWriter, abi: Abi) {
mywrite!(w, "["); mywrite!(w, "[");
abis.each(|abi| { mywrite!(w, "{}", abi.name());
mywrite!(w, "{},", abi.name());
true
});
mywrite!(w, "]") mywrite!(w, "]")
} }
@ -359,7 +356,7 @@ fn enc_onceness(w: &mut MemWriter, o: Onceness) {
pub fn enc_bare_fn_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::BareFnTy) { pub fn enc_bare_fn_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::BareFnTy) {
enc_purity(w, ft.purity); enc_purity(w, ft.purity);
enc_abi_set(w, ft.abis); enc_abi(w, ft.abi);
enc_fn_sig(w, cx, &ft.sig); enc_fn_sig(w, cx, &ft.sig);
} }

View file

@ -59,6 +59,7 @@ use std::u32;
use std::u64; use std::u64;
use std::u8; use std::u8;
use collections::SmallIntMap; use collections::SmallIntMap;
use syntax::abi;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util::IdVisitingOperation; use syntax::ast_util::IdVisitingOperation;
use syntax::attr::{AttrMetaMethods, AttributeMethods}; use syntax::attr::{AttrMetaMethods, AttributeMethods};
@ -892,7 +893,7 @@ fn check_item_ctypes(cx: &Context, it: &ast::Item) {
} }
match it.node { match it.node {
ast::ItemForeignMod(ref nmod) if !nmod.abis.is_intrinsic() => { ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => {
for ni in nmod.items.iter() { for ni in nmod.items.iter() {
match ni.node { match ni.node {
ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, decl), ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, decl),

View file

@ -855,8 +855,8 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
let name = csearch::get_symbol(&ccx.sess().cstore, did); let name = csearch::get_symbol(&ccx.sess().cstore, did);
match ty::get(t).sty { match ty::get(t).sty {
ty::ty_bare_fn(ref fn_ty) => { ty::ty_bare_fn(ref fn_ty) => {
match fn_ty.abis.for_target(ccx.sess().targ_cfg.os, match fn_ty.abi.for_target(ccx.sess().targ_cfg.os,
ccx.sess().targ_cfg.arch) { ccx.sess().targ_cfg.arch) {
Some(Rust) | Some(RustIntrinsic) => { Some(Rust) | Some(RustIntrinsic) => {
get_extern_rust_fn(ccx, get_extern_rust_fn(ccx,
fn_ty.sig.inputs.as_slice(), fn_ty.sig.inputs.as_slice(),
@ -865,7 +865,7 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
did) did)
} }
Some(..) | None => { Some(..) | None => {
let c = foreign::llvm_calling_convention(ccx, fn_ty.abis); let c = foreign::llvm_calling_convention(ccx, fn_ty.abi);
let cconv = c.unwrap_or(lib::llvm::CCallConv); let cconv = c.unwrap_or(lib::llvm::CCallConv);
let llty = type_of_fn_from_ty(ccx, t); let llty = type_of_fn_from_ty(ccx, t);
get_extern_fn(&mut *ccx.externs.borrow_mut(), ccx.llmod, get_extern_fn(&mut *ccx.externs.borrow_mut(), ccx.llmod,
@ -1601,7 +1601,7 @@ impl<'a> Visitor<()> for TransItemVisitor<'a> {
pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
let _icx = push_ctxt("trans_item"); let _icx = push_ctxt("trans_item");
match item.node { match item.node {
ast::ItemFn(decl, purity, _abis, ref generics, body) => { ast::ItemFn(decl, purity, _abi, ref generics, body) => {
if purity == ast::ExternFn { if purity == ast::ExternFn {
let llfndecl = get_item_val(ccx, item.id); let llfndecl = get_item_val(ccx, item.id);
foreign::trans_rust_fn_with_foreign_abi( foreign::trans_rust_fn_with_foreign_abi(
@ -1721,7 +1721,7 @@ fn register_fn(ccx: &CrateContext,
-> ValueRef { -> ValueRef {
let f = match ty::get(node_type).sty { let f = match ty::get(node_type).sty {
ty::ty_bare_fn(ref f) => { ty::ty_bare_fn(ref f) => {
assert!(f.abis.is_rust() || f.abis.is_intrinsic()); assert!(f.abi == Rust || f.abi == RustIntrinsic);
f f
} }
_ => fail!("expected bare rust fn or an intrinsic") _ => fail!("expected bare rust fn or an intrinsic")
@ -1997,8 +1997,8 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
match ni.node { match ni.node {
ast::ForeignItemFn(..) => { ast::ForeignItemFn(..) => {
let abis = ccx.tcx.map.get_foreign_abis(id); let abi = ccx.tcx.map.get_foreign_abi(id);
foreign::register_foreign_item_fn(ccx, abis, ni) foreign::register_foreign_item_fn(ccx, abi, ni)
} }
ast::ForeignItemStatic(..) => { ast::ForeignItemStatic(..) => {
foreign::register_static(ccx, ni) foreign::register_static(ccx, ni)

View file

@ -50,7 +50,7 @@ use util::ppaux::Repr;
use middle::trans::type_::Type; use middle::trans::type_::Type;
use syntax::ast; use syntax::ast;
use syntax::abi::AbiSet; use synabi = syntax::abi;
use syntax::ast_map; use syntax::ast_map;
pub struct MethodData { pub struct MethodData {
@ -363,7 +363,7 @@ pub fn trans_fn_ref_with_vtables(
match map_node { match map_node {
ast_map::NodeForeignItem(_) => { ast_map::NodeForeignItem(_) => {
tcx.map.get_foreign_abis(def_id.node).is_intrinsic() tcx.map.get_foreign_abi(def_id.node) == synabi::RustIntrinsic
} }
_ => false _ => false
} }
@ -572,13 +572,11 @@ pub fn trans_call_inner<'a>(
}; };
let (abi, ret_ty) = match ty::get(callee_ty).sty { let (abi, ret_ty) = match ty::get(callee_ty).sty {
ty::ty_bare_fn(ref f) => (f.abis, f.sig.output), ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
ty::ty_closure(ref f) => (AbiSet::Rust(), f.sig.output), ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
_ => fail!("expected bare rust fn or closure in trans_call_inner") _ => fail!("expected bare rust fn or closure in trans_call_inner")
}; };
let is_rust_fn = let is_rust_fn = abi == synabi::Rust || abi == synabi::RustIntrinsic;
abi.is_rust() ||
abi.is_intrinsic();
// Generate a location to store the result. If the user does // Generate a location to store the result. If the user does
// not care about the result, just make a stack slot. // not care about the result, just make a stack slot.

View file

@ -27,7 +27,7 @@ use middle::ty::FnSig;
use middle::ty; use middle::ty;
use std::cmp; use std::cmp;
use std::libc::c_uint; use std::libc::c_uint;
use syntax::abi::{Cdecl, Aapcs, C, AbiSet, Win64}; use syntax::abi::{Cdecl, Aapcs, C, Win64, Abi};
use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall, System}; use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall, System};
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::parse::token::{InternedString, special_idents}; use syntax::parse::token::{InternedString, special_idents};
@ -73,10 +73,10 @@ struct LlvmSignature {
// Calls to external functions // Calls to external functions
pub fn llvm_calling_convention(ccx: &CrateContext, pub fn llvm_calling_convention(ccx: &CrateContext,
abis: AbiSet) -> Option<CallConv> { abi: Abi) -> Option<CallConv> {
let os = ccx.sess().targ_cfg.os; let os = ccx.sess().targ_cfg.os;
let arch = ccx.sess().targ_cfg.arch; let arch = ccx.sess().targ_cfg.arch;
abis.for_target(os, arch).map(|abi| { abi.for_target(os, arch).map(|abi| {
match abi { match abi {
RustIntrinsic => { RustIntrinsic => {
// Intrinsics are emitted by monomorphic fn // Intrinsics are emitted by monomorphic fn
@ -180,27 +180,27 @@ pub fn register_static(ccx: &CrateContext,
} }
} }
pub fn register_foreign_item_fn(ccx: &CrateContext, abis: AbiSet, pub fn register_foreign_item_fn(ccx: &CrateContext, abi: Abi,
foreign_item: &ast::ForeignItem) -> ValueRef { foreign_item: &ast::ForeignItem) -> ValueRef {
/*! /*!
* Registers a foreign function found in a library. * Registers a foreign function found in a library.
* Just adds a LLVM global. * Just adds a LLVM global.
*/ */
debug!("register_foreign_item_fn(abis={}, \ debug!("register_foreign_item_fn(abi={}, \
path={}, \ path={}, \
foreign_item.id={})", foreign_item.id={})",
abis.repr(ccx.tcx()), abi.repr(ccx.tcx()),
ccx.tcx.map.path_to_str(foreign_item.id), ccx.tcx.map.path_to_str(foreign_item.id),
foreign_item.id); foreign_item.id);
let cc = match llvm_calling_convention(ccx, abis) { let cc = match llvm_calling_convention(ccx, abi) {
Some(cc) => cc, Some(cc) => cc,
None => { None => {
ccx.sess().span_fatal(foreign_item.span, ccx.sess().span_fatal(foreign_item.span,
format!("ABI `{}` has no suitable calling convention \ format!("ABI `{}` has no suitable calling convention \
for target architecture", for target architecture",
abis.user_string(ccx.tcx()))); abi.user_string(ccx.tcx())));
} }
}; };
@ -263,8 +263,8 @@ pub fn trans_native_call<'a>(
ccx.tn.val_to_str(llfn), ccx.tn.val_to_str(llfn),
ccx.tn.val_to_str(llretptr)); ccx.tn.val_to_str(llretptr));
let (fn_abis, fn_sig) = match ty::get(callee_ty).sty { let (fn_abi, fn_sig) = match ty::get(callee_ty).sty {
ty::ty_bare_fn(ref fn_ty) => (fn_ty.abis, fn_ty.sig.clone()), ty::ty_bare_fn(ref fn_ty) => (fn_ty.abi, fn_ty.sig.clone()),
_ => ccx.sess().bug("trans_native_call called on non-function type") _ => ccx.sess().bug("trans_native_call called on non-function type")
}; };
let llsig = foreign_signature(ccx, &fn_sig, passed_arg_tys.as_slice()); let llsig = foreign_signature(ccx, &fn_sig, passed_arg_tys.as_slice());
@ -354,14 +354,14 @@ pub fn trans_native_call<'a>(
llargs_foreign.push(llarg_foreign); llargs_foreign.push(llarg_foreign);
} }
let cc = match llvm_calling_convention(ccx, fn_abis) { let cc = match llvm_calling_convention(ccx, fn_abi) {
Some(cc) => cc, Some(cc) => cc,
None => { None => {
// FIXME(#8357) We really ought to report a span here // FIXME(#8357) We really ought to report a span here
ccx.sess().fatal( ccx.sess().fatal(
format!("ABI string `{}` has no suitable ABI \ format!("ABI string `{}` has no suitable ABI \
for target architecture", for target architecture",
fn_abis.user_string(ccx.tcx()))); fn_abi.user_string(ccx.tcx())));
} }
}; };
@ -435,9 +435,9 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
for &foreign_item in foreign_mod.items.iter() { for &foreign_item in foreign_mod.items.iter() {
match foreign_item.node { match foreign_item.node {
ast::ForeignItemFn(..) => { ast::ForeignItemFn(..) => {
let abis = foreign_mod.abis; match foreign_mod.abi {
if !(abis.is_rust() || abis.is_intrinsic()) { Rust | RustIntrinsic => {}
register_foreign_item_fn(ccx, abis, foreign_item); abi => { register_foreign_item_fn(ccx, abi, foreign_item); }
} }
} }
_ => {} _ => {}
@ -486,7 +486,7 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
let t = ty::node_id_to_type(ccx.tcx(), node_id); let t = ty::node_id_to_type(ccx.tcx(), node_id);
let (cconv, output) = match ty::get(t).sty { let (cconv, output) = match ty::get(t).sty {
ty::ty_bare_fn(ref fn_ty) => { ty::ty_bare_fn(ref fn_ty) => {
let c = llvm_calling_convention(ccx, fn_ty.abis); let c = llvm_calling_convention(ccx, fn_ty.abi);
(c.unwrap_or(lib::llvm::CCallConv), fn_ty.sig.output) (c.unwrap_or(lib::llvm::CCallConv), fn_ty.sig.output)
} }
_ => fail!("expected bare fn in register_rust_fn_with_foreign_abi") _ => fail!("expected bare fn in register_rust_fn_with_foreign_abi")
@ -534,7 +534,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext,
// normal Rust function. This will be the type of the wrappee fn. // normal Rust function. This will be the type of the wrappee fn.
let f = match ty::get(t).sty { let f = match ty::get(t).sty {
ty::ty_bare_fn(ref f) => { ty::ty_bare_fn(ref f) => {
assert!(!f.abis.is_rust() && !f.abis.is_intrinsic()); assert!(f.abi != Rust && f.abi != RustIntrinsic);
f f
} }
_ => { _ => {

View file

@ -34,6 +34,7 @@ use util::common::indenter;
use util::ppaux::Repr; use util::ppaux::Repr;
use std::c_str::ToCStr; use std::c_str::ToCStr;
use syntax::abi::Rust;
use syntax::parse::token; use syntax::parse::token;
use syntax::{ast, ast_map, visit}; use syntax::{ast, ast_map, visit};
@ -393,7 +394,7 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
debug!("(translating trait callee) loading method"); debug!("(translating trait callee) loading method");
// Replace the self type (&Self or ~Self) with an opaque pointer. // Replace the self type (&Self or ~Self) with an opaque pointer.
let llcallee_ty = match ty::get(callee_ty).sty { let llcallee_ty = match ty::get(callee_ty).sty {
ty::ty_bare_fn(ref f) if f.abis.is_rust() => { ty::ty_bare_fn(ref f) if f.abi == Rust => {
type_of_rust_fn(ccx, true, f.sig.inputs.slice_from(1), f.sig.output) type_of_rust_fn(ccx, true, f.sig.inputs.slice_from(1), f.sig.output)
} }
_ => { _ => {

View file

@ -23,6 +23,7 @@ use middle::ty;
use middle::typeck; use middle::typeck;
use util::ppaux::Repr; use util::ppaux::Repr;
use syntax::abi;
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_util::local_def; use syntax::ast_util::local_def;
@ -99,7 +100,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
match map_node { match map_node {
ast_map::NodeForeignItem(_) => { ast_map::NodeForeignItem(_) => {
if !ccx.tcx.map.get_foreign_abis(fn_id.node).is_intrinsic() { if ccx.tcx.map.get_foreign_abi(fn_id.node) != abi::RustIntrinsic {
// Foreign externs don't have to be monomorphized. // Foreign externs don't have to be monomorphized.
return (get_item_val(ccx, fn_id.node), true); return (get_item_val(ccx, fn_id.node), true);
} }
@ -150,7 +151,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
let f = match ty::get(mono_ty).sty { let f = match ty::get(mono_ty).sty {
ty::ty_bare_fn(ref f) => { ty::ty_bare_fn(ref f) => {
assert!(f.abis.is_rust() || f.abis.is_intrinsic()); assert!(f.abi == abi::Rust || f.abi == abi::RustIntrinsic);
f f
} }
_ => fail!("expected bare rust fn or an intrinsic") _ => fail!("expected bare rust fn or an intrinsic")

View file

@ -19,6 +19,7 @@ use util::ppaux::Repr;
use middle::trans::type_::Type; use middle::trans::type_::Type;
use syntax::abi;
use syntax::ast; use syntax::ast;
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
@ -75,7 +76,7 @@ pub fn type_of_fn_from_ty(cx: &CrateContext, fty: ty::t) -> Type {
type_of_rust_fn(cx, true, f.sig.inputs.as_slice(), f.sig.output) type_of_rust_fn(cx, true, f.sig.inputs.as_slice(), f.sig.output)
} }
ty::ty_bare_fn(ref f) => { ty::ty_bare_fn(ref f) => {
if f.abis.is_rust() || f.abis.is_intrinsic() { if f.abi == abi::Rust || f.abi == abi::RustIntrinsic {
type_of_rust_fn(cx, type_of_rust_fn(cx,
false, false,
f.sig.inputs.as_slice(), f.sig.inputs.as_slice(),

View file

@ -51,7 +51,7 @@ use syntax::parse::token;
use syntax::parse::token::InternedString; use syntax::parse::token::InternedString;
use syntax::{ast, ast_map}; use syntax::{ast, ast_map};
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
use syntax::abi::AbiSet; use syntax::abi;
use syntax; use syntax;
use collections::enum_set::{EnumSet, CLike}; use collections::enum_set::{EnumSet, CLike};
@ -416,8 +416,8 @@ pub fn type_id(t: t) -> uint { get(t).id }
#[deriving(Clone, Eq, TotalEq, Hash)] #[deriving(Clone, Eq, TotalEq, Hash)]
pub struct BareFnTy { pub struct BareFnTy {
pub purity: ast::Purity, pub purity: ast::Purity,
pub abis: AbiSet, pub abi: abi::Abi,
pub sig: FnSig pub sig: FnSig,
} }
#[deriving(Clone, Eq, TotalEq, Hash)] #[deriving(Clone, Eq, TotalEq, Hash)]
@ -796,7 +796,7 @@ pub enum type_err {
terr_mismatch, terr_mismatch,
terr_purity_mismatch(expected_found<Purity>), terr_purity_mismatch(expected_found<Purity>),
terr_onceness_mismatch(expected_found<Onceness>), terr_onceness_mismatch(expected_found<Onceness>),
terr_abi_mismatch(expected_found<AbiSet>), terr_abi_mismatch(expected_found<abi::Abi>),
terr_mutability, terr_mutability,
terr_sigil_mismatch(expected_found<ast::Sigil>), terr_sigil_mismatch(expected_found<ast::Sigil>),
terr_box_mutability, terr_box_mutability,
@ -1409,7 +1409,7 @@ pub fn mk_ctor_fn(cx: &ctxt,
mk_bare_fn(cx, mk_bare_fn(cx,
BareFnTy { BareFnTy {
purity: ast::ImpureFn, purity: ast::ImpureFn,
abis: AbiSet::Rust(), abi: abi::Rust,
sig: FnSig { sig: FnSig {
binder_id: binder_id, binder_id: binder_id,
inputs: input_args, inputs: input_args,
@ -4677,7 +4677,7 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
ty_bare_fn(ref b) => { ty_bare_fn(ref b) => {
byte!(14); byte!(14);
hash!(b.purity); hash!(b.purity);
hash!(b.abis); hash!(b.abi);
} }
ty_closure(ref c) => { ty_closure(ref c) => {
byte!(15); byte!(15);

View file

@ -48,7 +48,7 @@ pub trait TypeFolder {
fty: &ty::BareFnTy) fty: &ty::BareFnTy)
-> ty::BareFnTy { -> ty::BareFnTy {
ty::BareFnTy { sig: self.fold_sig(&fty.sig), ty::BareFnTy { sig: self.fold_sig(&fty.sig),
abis: fty.abis, abi: fty.abi,
purity: fty.purity } purity: fty.purity }
} }

View file

@ -60,7 +60,7 @@ use middle::typeck::rscope::{RegionScope};
use middle::typeck::lookup_def_tcx; use middle::typeck::lookup_def_tcx;
use util::ppaux::Repr; use util::ppaux::Repr;
use syntax::abi::AbiSet; use syntax::abi;
use syntax::{ast, ast_util}; use syntax::{ast, ast_util};
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
@ -519,12 +519,12 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
ty::mk_tup(tcx, flds) ty::mk_tup(tcx, flds)
} }
ast::TyBareFn(ref bf) => { ast::TyBareFn(ref bf) => {
if bf.decl.variadic && !bf.abis.is_c() { if bf.decl.variadic && bf.abi != abi::C {
tcx.sess.span_err(ast_ty.span, tcx.sess.span_err(ast_ty.span,
"variadic function must have C calling convention"); "variadic function must have C calling convention");
} }
ty::mk_bare_fn(tcx, ty_of_bare_fn(this, ast_ty.id, bf.purity, ty::mk_bare_fn(tcx, ty_of_bare_fn(this, ast_ty.id, bf.purity,
bf.abis, bf.decl)) bf.abi, bf.decl))
} }
ast::TyClosure(ref f) => { ast::TyClosure(ref f) => {
if f.sigil == ast::ManagedSigil { if f.sigil == ast::ManagedSigil {
@ -666,20 +666,20 @@ pub fn ty_of_method<AC:AstConv>(
untransformed_self_ty: ty::t, untransformed_self_ty: ty::t,
explicit_self: ast::ExplicitSelf, explicit_self: ast::ExplicitSelf,
decl: &ast::FnDecl) -> ty::BareFnTy { decl: &ast::FnDecl) -> ty::BareFnTy {
ty_of_method_or_bare_fn(this, id, purity, AbiSet::Rust(), Some(SelfInfo { ty_of_method_or_bare_fn(this, id, purity, abi::Rust, Some(SelfInfo {
untransformed_self_ty: untransformed_self_ty, untransformed_self_ty: untransformed_self_ty,
explicit_self: explicit_self explicit_self: explicit_self
}), decl) }), decl)
} }
pub fn ty_of_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId, pub fn ty_of_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
purity: ast::Purity, abi: AbiSet, purity: ast::Purity, abi: abi::Abi,
decl: &ast::FnDecl) -> ty::BareFnTy { decl: &ast::FnDecl) -> ty::BareFnTy {
ty_of_method_or_bare_fn(this, id, purity, abi, None, decl) ty_of_method_or_bare_fn(this, id, purity, abi, None, decl)
} }
fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId, fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
purity: ast::Purity, abi: AbiSet, purity: ast::Purity, abi: abi::Abi,
opt_self_info: Option<SelfInfo>, opt_self_info: Option<SelfInfo>,
decl: &ast::FnDecl) -> ty::BareFnTy { decl: &ast::FnDecl) -> ty::BareFnTy {
debug!("ty_of_method_or_bare_fn"); debug!("ty_of_method_or_bare_fn");
@ -726,7 +726,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
return ty::BareFnTy { return ty::BareFnTy {
purity: purity, purity: purity,
abis: abi, abi: abi,
sig: ty::FnSig { sig: ty::FnSig {
binder_id: id, binder_id: id,
inputs: self_and_input_tys, inputs: self_and_input_tys,

View file

@ -1164,7 +1164,7 @@ impl<'a> LookupContext<'a> {
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy { let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
sig: fn_sig, sig: fn_sig,
purity: bare_fn_ty.purity, purity: bare_fn_ty.purity,
abis: bare_fn_ty.abis.clone(), abi: bare_fn_ty.abi.clone(),
}); });
debug!("after replacing bound regions, fty={}", self.ty_to_str(fty)); debug!("after replacing bound regions, fty={}", self.ty_to_str(fty));

View file

@ -120,7 +120,7 @@ use std::mem::replace;
use std::result; use std::result;
use std::slice; use std::slice;
use std::vec::Vec; use std::vec::Vec;
use syntax::abi::AbiSet; use syntax::abi;
use syntax::ast::{Provided, Required}; use syntax::ast::{Provided, Required};
use syntax::ast; use syntax::ast;
use syntax::ast_util::local_def; use syntax::ast_util::local_def;
@ -599,7 +599,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
check_bounds_are_used(ccx, t.span, &generics.ty_params, tpt_ty); check_bounds_are_used(ccx, t.span, &generics.ty_params, tpt_ty);
} }
ast::ItemForeignMod(ref m) => { ast::ItemForeignMod(ref m) => {
if m.abis.is_intrinsic() { if m.abi == abi::RustIntrinsic {
for item in m.items.iter() { for item in m.items.iter() {
check_intrinsic_type(ccx, *item); check_intrinsic_type(ccx, *item);
} }
@ -612,7 +612,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
match item.node { match item.node {
ast::ForeignItemFn(ref fn_decl, _) => { ast::ForeignItemFn(ref fn_decl, _) => {
if fn_decl.variadic && !m.abis.is_c() { if fn_decl.variadic && m.abi != abi::C {
ccx.tcx.sess.span_err( ccx.tcx.sess.span_err(
item.span, "variadic function must have C calling convention"); item.span, "variadic function must have C calling convention");
} }
@ -4224,7 +4224,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
}; };
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy { let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
purity: ast::UnsafeFn, purity: ast::UnsafeFn,
abis: AbiSet::Intrinsic(), abi: abi::RustIntrinsic,
sig: FnSig {binder_id: it.id, sig: FnSig {binder_id: it.id,
inputs: inputs, inputs: inputs,
output: output, output: output,

View file

@ -48,7 +48,7 @@ use util::ppaux::Repr;
use std::rc::Rc; use std::rc::Rc;
use collections::HashSet; use collections::HashSet;
use syntax::abi::AbiSet; use syntax::abi;
use syntax::ast::{RegionTyParamBound, TraitTyParamBound}; use syntax::ast::{RegionTyParamBound, TraitTyParamBound};
use syntax::ast; use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
@ -116,8 +116,8 @@ impl<'a> AstConv for CrateCtxt<'a> {
match self.tcx.map.find(id.node) { match self.tcx.map.find(id.node) {
Some(ast_map::NodeItem(item)) => ty_of_item(self, item), Some(ast_map::NodeItem(item)) => ty_of_item(self, item),
Some(ast_map::NodeForeignItem(foreign_item)) => { Some(ast_map::NodeForeignItem(foreign_item)) => {
let abis = self.tcx.map.get_foreign_abis(id.node); let abi = self.tcx.map.get_foreign_abi(id.node);
ty_of_foreign_item(self, foreign_item, abis) ty_of_foreign_item(self, foreign_item, abi)
} }
x => { x => {
self.tcx.sess.bug(format!("unexpected sort of node \ self.tcx.sess.bug(format!("unexpected sort of node \
@ -550,10 +550,10 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
fn ensure_generics_abi(ccx: &CrateCtxt, fn ensure_generics_abi(ccx: &CrateCtxt,
span: Span, span: Span,
abis: AbiSet, abi: abi::Abi,
generics: &ast::Generics) { generics: &ast::Generics) {
if generics.ty_params.len() > 0 && if generics.ty_params.len() > 0 &&
!(abis.is_rust() || abis.is_intrinsic()) { !(abi == abi::Rust || abi == abi::RustIntrinsic) {
ccx.tcx.sess.span_err(span, ccx.tcx.sess.span_err(span,
"foreign functions may not use type parameters"); "foreign functions may not use type parameters");
} }
@ -717,9 +717,9 @@ pub fn convert_foreign(ccx: &CrateCtxt, i: &ast::ForeignItem) {
// map, and I regard each time that I use it as a personal and // map, and I regard each time that I use it as a personal and
// moral failing, but at the moment it seems like the only // moral failing, but at the moment it seems like the only
// convenient way to extract the ABI. - ndm // convenient way to extract the ABI. - ndm
let abis = ccx.tcx.map.get_foreign_abis(i.id); let abi = ccx.tcx.map.get_foreign_abi(i.id);
let tpt = ty_of_foreign_item(ccx, i, abis); let tpt = ty_of_foreign_item(ccx, i, abi);
write_ty_to_tcx(ccx.tcx, i.id, tpt.ty); write_ty_to_tcx(ccx.tcx, i.id, tpt.ty);
ccx.tcx.tcache.borrow_mut().insert(local_def(i.id), tpt); ccx.tcx.tcache.borrow_mut().insert(local_def(i.id), tpt);
@ -891,7 +891,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
pub fn ty_of_foreign_item(ccx: &CrateCtxt, pub fn ty_of_foreign_item(ccx: &CrateCtxt,
it: &ast::ForeignItem, it: &ast::ForeignItem,
abis: AbiSet) -> ty::ty_param_bounds_and_ty abi: abi::Abi) -> ty::ty_param_bounds_and_ty
{ {
match it.node { match it.node {
ast::ForeignItemFn(fn_decl, ref generics) => { ast::ForeignItemFn(fn_decl, ref generics) => {
@ -899,7 +899,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
fn_decl, fn_decl,
local_def(it.id), local_def(it.id),
generics, generics,
abis) abi)
} }
ast::ForeignItemStatic(t, _) => { ast::ForeignItemStatic(t, _) => {
ty::ty_param_bounds_and_ty { ty::ty_param_bounds_and_ty {
@ -1003,7 +1003,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
decl: &ast::FnDecl, decl: &ast::FnDecl,
def_id: ast::DefId, def_id: ast::DefId,
ast_generics: &ast::Generics, ast_generics: &ast::Generics,
abis: AbiSet) abi: abi::Abi)
-> ty::ty_param_bounds_and_ty { -> ty::ty_param_bounds_and_ty {
for i in decl.inputs.iter() { for i in decl.inputs.iter() {
@ -1028,7 +1028,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
let t_fn = ty::mk_bare_fn( let t_fn = ty::mk_bare_fn(
ccx.tcx, ccx.tcx,
ty::BareFnTy { ty::BareFnTy {
abis: abis, abi: abi,
purity: ast::UnsafeFn, purity: ast::UnsafeFn,
sig: ty::FnSig {binder_id: def_id.node, sig: ty::FnSig {binder_id: def_id.node,
inputs: input_tys, inputs: input_tys,

View file

@ -77,6 +77,7 @@ use middle::typeck::infer::to_str::InferStr;
use middle::typeck::infer::resolve::try_resolve_tvar_shallow; use middle::typeck::infer::resolve::try_resolve_tvar_shallow;
use util::common::indenter; use util::common::indenter;
use syntax::abi;
use syntax::ast::MutImmutable; use syntax::ast::MutImmutable;
use syntax::ast; use syntax::ast;
@ -384,7 +385,7 @@ impl<'f> Coerce<'f> {
debug!("coerce_from_bare_fn(a={}, b={})", debug!("coerce_from_bare_fn(a={}, b={})",
a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx)); a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx));
if !fn_ty_a.abis.is_rust() || fn_ty_a.purity != ast::ImpureFn { if fn_ty_a.abi != abi::Rust || fn_ty_a.purity != ast::ImpureFn {
return self.subtype(a, b); return self.subtype(a, b);
} }

View file

@ -67,7 +67,7 @@ use std::result;
use syntax::ast::{Onceness, Purity}; use syntax::ast::{Onceness, Purity};
use syntax::ast; use syntax::ast;
use syntax::owned_slice::OwnedSlice; use syntax::owned_slice::OwnedSlice;
use syntax::abi::AbiSet; use syntax::abi;
pub trait Combine { pub trait Combine {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a>; fn infcx<'a>(&'a self) -> &'a InferCtxt<'a>;
@ -195,10 +195,10 @@ pub trait Combine {
fn bare_fn_tys(&self, a: &ty::BareFnTy, fn bare_fn_tys(&self, a: &ty::BareFnTy,
b: &ty::BareFnTy) -> cres<ty::BareFnTy> { b: &ty::BareFnTy) -> cres<ty::BareFnTy> {
let purity = if_ok!(self.purities(a.purity, b.purity)); let purity = if_ok!(self.purities(a.purity, b.purity));
let abi = if_ok!(self.abis(a.abis, b.abis)); let abi = if_ok!(self.abi(a.abi, b.abi));
let sig = if_ok!(self.fn_sigs(&a.sig, &b.sig)); let sig = if_ok!(self.fn_sigs(&a.sig, &b.sig));
Ok(ty::BareFnTy {purity: purity, Ok(ty::BareFnTy {purity: purity,
abis: abi, abi: abi,
sig: sig}) sig: sig})
} }
@ -248,7 +248,7 @@ pub trait Combine {
fn purities(&self, a: Purity, b: Purity) -> cres<Purity>; fn purities(&self, a: Purity, b: Purity) -> cres<Purity>;
fn abis(&self, a: AbiSet, b: AbiSet) -> cres<AbiSet> { fn abi(&self, a: abi::Abi, b: abi::Abi) -> cres<abi::Abi> {
if a == b { if a == b {
Ok(a) Ok(a)
} else { } else {

View file

@ -358,7 +358,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
} }
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy { let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
purity: ast::ImpureFn, purity: ast::ImpureFn,
abis: abi::AbiSet::Rust(), abi: abi::Rust,
sig: ty::FnSig { sig: ty::FnSig {
binder_id: main_id, binder_id: main_id,
inputs: Vec::new(), inputs: Vec::new(),
@ -404,7 +404,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy { let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
purity: ast::ImpureFn, purity: ast::ImpureFn,
abis: abi::AbiSet::Rust(), abi: abi::Rust,
sig: ty::FnSig { sig: ty::FnSig {
binder_id: start_id, binder_id: start_id,
inputs: vec!( inputs: vec!(

View file

@ -23,7 +23,7 @@ use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_unboxed_vec, ty_infer};
use middle::ty; use middle::ty;
use middle::typeck; use middle::typeck;
use syntax::abi::AbiSet; use syntax::abi;
use syntax::ast_map; use syntax::ast_map;
use syntax::codemap::{Span, Pos}; use syntax::codemap::{Span, Pos};
use syntax::parse::token; use syntax::parse::token;
@ -253,14 +253,14 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
} }
fn bare_fn_to_str(cx: &ctxt, fn bare_fn_to_str(cx: &ctxt,
purity: ast::Purity, purity: ast::Purity,
abis: AbiSet, abi: abi::Abi,
ident: Option<ast::Ident>, ident: Option<ast::Ident>,
sig: &ty::FnSig) sig: &ty::FnSig)
-> ~str { -> ~str {
let mut s = if abis.is_rust() { let mut s = if abi == abi::Rust {
~"" ~""
} else { } else {
format!("extern {} ", abis.to_str()) format!("extern {} ", abi.to_str())
}; };
match purity { match purity {
@ -406,7 +406,7 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
closure_to_str(cx, *f) closure_to_str(cx, *f)
} }
ty_bare_fn(ref f) => { ty_bare_fn(ref f) => {
bare_fn_to_str(cx, f.purity, f.abis, None, &f.sig) bare_fn_to_str(cx, f.purity, f.abi, None, &f.sig)
} }
ty_infer(infer_ty) => infer_ty.to_str(), ty_infer(infer_ty) => infer_ty.to_str(),
ty_err => ~"[type error]", ty_err => ~"[type error]",
@ -813,9 +813,9 @@ impl Repr for ast::Visibility {
impl Repr for ty::BareFnTy { impl Repr for ty::BareFnTy {
fn repr(&self, tcx: &ctxt) -> ~str { fn repr(&self, tcx: &ctxt) -> ~str {
format!("BareFnTy \\{purity: {:?}, abis: {}, sig: {}\\}", format!("BareFnTy \\{purity: {:?}, abi: {}, sig: {}\\}",
self.purity, self.purity,
self.abis.to_str(), self.abi.to_str(),
self.sig.repr(tcx)) self.sig.repr(tcx))
} }
} }
@ -968,13 +968,13 @@ impl UserString for ast::Ident {
} }
} }
impl Repr for AbiSet { impl Repr for abi::Abi {
fn repr(&self, _tcx: &ctxt) -> ~str { fn repr(&self, _tcx: &ctxt) -> ~str {
self.to_str() self.to_str()
} }
} }
impl UserString for AbiSet { impl UserString for abi::Abi {
fn user_string(&self, _tcx: &ctxt) -> ~str { fn user_string(&self, _tcx: &ctxt) -> ~str {
self.to_str() self.to_str()
} }

View file

@ -975,7 +975,7 @@ impl Clean<BareFunctionDecl> for ast::BareFnTy {
type_params: Vec::new(), type_params: Vec::new(),
}, },
decl: self.decl.clean(), decl: self.decl.clean(),
abi: self.abis.to_str(), abi: self.abi.to_str(),
} }
} }
} }

View file

@ -11,7 +11,7 @@
//! Rust AST Visitor. Extracts useful information and massages it into a form //! Rust AST Visitor. Extracts useful information and massages it into a form
//! usable for clean //! usable for clean
use syntax::abi::AbiSet; use syntax::abi;
use syntax::ast; use syntax::ast;
use syntax::ast_util; use syntax::ast_util;
use syntax::ast_map; use syntax::ast_map;
@ -95,7 +95,7 @@ impl<'a> RustdocVisitor<'a> {
} }
pub fn visit_fn(&mut self, item: &ast::Item, fd: &ast::FnDecl, pub fn visit_fn(&mut self, item: &ast::Item, fd: &ast::FnDecl,
purity: &ast::Purity, _abi: &AbiSet, purity: &ast::Purity, _abi: &abi::Abi,
gen: &ast::Generics) -> Function { gen: &ast::Generics) -> Function {
debug!("Visiting fn"); debug!("Visiting fn");
Function { Function {

View file

@ -9,12 +9,11 @@
// except according to those terms. // except according to those terms.
use std::fmt; use std::fmt;
use std::fmt::Show;
#[deriving(Eq)] #[deriving(Eq)]
pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, } pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, }
#[deriving(Eq, TotalEq, Hash)] #[deriving(Eq, TotalEq, Hash, Encodable, Decodable, Clone)]
pub enum Abi { pub enum Abi {
// NB: This ordering MUST match the AbiDatas array below. // NB: This ordering MUST match the AbiDatas array below.
// (This is ensured by the test indices_are_correct().) // (This is ensured by the test indices_are_correct().)
@ -65,11 +64,6 @@ pub enum AbiArchitecture {
Archs(u32) // Multiple architectures (bitset) Archs(u32) // Multiple architectures (bitset)
} }
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
pub struct AbiSet {
bits: u32 // each bit represents one of the abis below
}
static AbiDatas: &'static [AbiData] = &[ static AbiDatas: &'static [AbiData] = &[
// Platform-specific ABIs // Platform-specific ABIs
AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(IntelBits)}, AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(IntelBits)},
@ -136,12 +130,20 @@ impl Abi {
self.data().name self.data().name
} }
pub fn for_target(&self, os: Os, arch: Architecture) -> Abi { pub fn for_target(&self, os: Os, arch: Architecture) -> Option<Abi> {
match (*self, os, arch) { // If this ABI isn't actually for the specified architecture, then we
// short circuit early
match self.data().abi_arch {
Archs(a) if a & arch.bit() == 0 => return None,
Archs(_) | RustArch | AllArch => {}
}
// Transform this ABI as appropriate for the requested os/arch
// combination.
Some(match (*self, os, arch) {
(System, OsWin32, X86) => Stdcall, (System, OsWin32, X86) => Stdcall,
(System, _, _) => C, (System, _, _) => C,
(me, _, _) => me, (me, _, _) => me,
} })
} }
} }
@ -151,138 +153,9 @@ impl Architecture {
} }
} }
impl AbiSet {
pub fn from(abi: Abi) -> AbiSet {
AbiSet { bits: (1 << abi.index()) }
}
#[inline]
pub fn Rust() -> AbiSet {
AbiSet::from(Rust)
}
#[inline]
pub fn C() -> AbiSet {
AbiSet::from(C)
}
#[inline]
pub fn Intrinsic() -> AbiSet {
AbiSet::from(RustIntrinsic)
}
pub fn default() -> AbiSet {
AbiSet::C()
}
pub fn empty() -> AbiSet {
AbiSet { bits: 0 }
}
#[inline]
pub fn is_rust(&self) -> bool {
self.bits == 1 << Rust.index()
}
#[inline]
pub fn is_c(&self) -> bool {
self.bits == 1 << C.index()
}
#[inline]
pub fn is_intrinsic(&self) -> bool {
self.bits == 1 << RustIntrinsic.index()
}
pub fn contains(&self, abi: Abi) -> bool {
(self.bits & (1 << abi.index())) != 0
}
pub fn subset_of(&self, other_abi_set: AbiSet) -> bool {
(self.bits & other_abi_set.bits) == self.bits
}
pub fn add(&mut self, abi: Abi) {
self.bits |= 1 << abi.index();
}
pub fn each(&self, op: |abi: Abi| -> bool) -> bool {
each_abi(|abi| !self.contains(abi) || op(abi))
}
pub fn is_empty(&self) -> bool {
self.bits == 0
}
pub fn for_target(&self, os: Os, arch: Architecture) -> Option<Abi> {
// NB---Single platform ABIs come first
let mut res = None;
self.each(|abi| {
let data = abi.data();
match data.abi_arch {
Archs(a) if (a & arch.bit()) != 0 => { res = Some(abi); false }
Archs(_) => { true }
RustArch | AllArch => { res = Some(abi); false }
}
});
res.map(|r| r.for_target(os, arch))
}
pub fn check_valid(&self) -> Option<(Abi, Abi)> {
let mut abis = Vec::new();
self.each(|abi| { abis.push(abi); true });
for (i, abi) in abis.iter().enumerate() {
let data = abi.data();
for other_abi in abis.slice(0, i).iter() {
let other_data = other_abi.data();
debug!("abis=({:?},{:?}) datas=({:?},{:?})",
abi, data.abi_arch,
other_abi, other_data.abi_arch);
match (&data.abi_arch, &other_data.abi_arch) {
(&AllArch, &AllArch) => {
// Two cross-architecture ABIs
return Some((*abi, *other_abi));
}
(_, &RustArch) |
(&RustArch, _) => {
// Cannot combine Rust or Rust-Intrinsic with
// anything else.
return Some((*abi, *other_abi));
}
(&Archs(is), &Archs(js)) if (is & js) != 0 => {
// Two ABIs for same architecture
return Some((*abi, *other_abi));
}
_ => {}
}
}
}
return None;
}
}
impl fmt::Show for Abi { impl fmt::Show for Abi {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.data().name.fmt(f) write!(f.buf, "\"{}\"", self.name())
}
}
impl fmt::Show for AbiSet {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f.buf, "\""));
let mut first = true;
self.each(|abi| {
if first { first = false; }
else { let _ = write!(f.buf, " "); }
let _ = write!(f.buf, "{}", abi.data().name);
true
});
write!(f.buf, "\"")
} }
} }
@ -304,95 +177,6 @@ fn lookup_baz() {
assert!(abi.is_none()); assert!(abi.is_none());
} }
#[cfg(test)]
fn cannot_combine(n: Abi, m: Abi) {
let mut set = AbiSet::empty();
set.add(n);
set.add(m);
match set.check_valid() {
Some((a, b)) => {
assert!((n == a && m == b) ||
(m == a && n == b));
}
None => {
fail!("invalid match not detected");
}
}
}
#[cfg(test)]
fn can_combine(n: Abi, m: Abi) {
let mut set = AbiSet::empty();
set.add(n);
set.add(m);
match set.check_valid() {
Some((_, _)) => {
fail!("valid match declared invalid");
}
None => {}
}
}
#[test]
fn cannot_combine_cdecl_and_stdcall() {
cannot_combine(Cdecl, Stdcall);
}
#[test]
fn cannot_combine_c_and_rust() {
cannot_combine(C, Rust);
}
#[test]
fn cannot_combine_rust_and_cdecl() {
cannot_combine(Rust, Cdecl);
}
#[test]
fn cannot_combine_rust_intrinsic_and_cdecl() {
cannot_combine(RustIntrinsic, Cdecl);
}
#[test]
fn can_combine_system_and_cdecl() {
can_combine(System, Cdecl);
}
#[test]
fn can_combine_c_and_stdcall() {
can_combine(C, Stdcall);
}
#[test]
fn can_combine_aapcs_and_stdcall() {
can_combine(Aapcs, Stdcall);
}
#[test]
fn abi_to_str_stdcall_aaps() {
let mut set = AbiSet::empty();
set.add(Aapcs);
set.add(Stdcall);
assert!(set.to_str() == ~"\"stdcall aapcs\"");
}
#[test]
fn abi_to_str_c_aaps() {
let mut set = AbiSet::empty();
set.add(Aapcs);
set.add(C);
debug!("set = {}", set.to_str());
assert!(set.to_str() == ~"\"aapcs C\"");
}
#[test]
fn abi_to_str_rust() {
let mut set = AbiSet::empty();
set.add(Rust);
debug!("set = {}", set.to_str());
assert!(set.to_str() == ~"\"Rust\"");
}
#[test] #[test]
fn indices_are_correct() { fn indices_are_correct() {
for (i, abi_data) in AbiDatas.iter().enumerate() { for (i, abi_data) in AbiDatas.iter().enumerate() {
@ -407,30 +191,14 @@ fn indices_are_correct() {
assert_eq!(ArmBits, bits); assert_eq!(ArmBits, bits);
} }
#[cfg(test)]
fn get_arch(abis: &[Abi], os: Os, arch: Architecture) -> Option<Abi> {
let mut set = AbiSet::empty();
for &abi in abis.iter() {
set.add(abi);
}
set.for_target(os, arch)
}
#[test]
fn pick_multiplatform() {
assert_eq!(get_arch([C, Cdecl], OsLinux, X86), Some(Cdecl));
assert_eq!(get_arch([C, Cdecl], OsLinux, X86_64), Some(Cdecl));
assert_eq!(get_arch([C, Cdecl], OsLinux, Arm), Some(C));
}
#[test] #[test]
fn pick_uniplatform() { fn pick_uniplatform() {
assert_eq!(get_arch([Stdcall], OsLinux, X86), Some(Stdcall)); assert_eq!(Stdcall.for_arch(OsLinux, X86), Some(Stdcall));
assert_eq!(get_arch([Stdcall], OsLinux, Arm), None); assert_eq!(Stdcall.for_arch(OsLinux, Arm), None);
assert_eq!(get_arch([System], OsLinux, X86), Some(C)); assert_eq!(System.for_arch(OsLinux, X86), Some(C));
assert_eq!(get_arch([System], OsWin32, X86), Some(Stdcall)); assert_eq!(System.for_arch(OsWin32, X86), Some(Stdcall));
assert_eq!(get_arch([System], OsWin32, X86_64), Some(C)); assert_eq!(System.for_arch(OsWin32, X86_64), Some(C));
assert_eq!(get_arch([System], OsWin32, Arm), Some(C)); assert_eq!(System.for_arch(OsWin32, Arm), Some(C));
assert_eq!(get_arch([Stdcall], OsWin32, X86), Some(Stdcall)); assert_eq!(Stdcall.for_arch(OsWin32, X86), Some(Stdcall));
assert_eq!(get_arch([Stdcall], OsWin32, X86_64), Some(Stdcall)); assert_eq!(Stdcall.for_arch(OsWin32, X86_64), Some(Stdcall));
} }

View file

@ -11,7 +11,7 @@
// The Rust abstract syntax tree. // The Rust abstract syntax tree.
use codemap::{Span, Spanned, DUMMY_SP}; use codemap::{Span, Spanned, DUMMY_SP};
use abi::AbiSet; use abi::Abi;
use ast_util; use ast_util;
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use parse::token::{InternedString, special_idents, str_to_ident}; use parse::token::{InternedString, special_idents, str_to_ident};
@ -807,7 +807,7 @@ pub struct ClosureTy {
#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)] #[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
pub struct BareFnTy { pub struct BareFnTy {
pub purity: Purity, pub purity: Purity,
pub abis: AbiSet, pub abi: Abi,
pub lifetimes: Vec<Lifetime>, pub lifetimes: Vec<Lifetime>,
pub decl: P<FnDecl> pub decl: P<FnDecl>
} }
@ -941,7 +941,7 @@ pub struct Mod {
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
pub struct ForeignMod { pub struct ForeignMod {
pub abis: AbiSet, pub abi: Abi,
pub view_items: Vec<ViewItem>, pub view_items: Vec<ViewItem>,
pub items: Vec<@ForeignItem>, pub items: Vec<@ForeignItem>,
} }
@ -1119,7 +1119,7 @@ pub struct Item {
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)] #[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
pub enum Item_ { pub enum Item_ {
ItemStatic(P<Ty>, Mutability, @Expr), ItemStatic(P<Ty>, Mutability, @Expr),
ItemFn(P<FnDecl>, Purity, AbiSet, Generics, P<Block>), ItemFn(P<FnDecl>, Purity, Abi, Generics, P<Block>),
ItemMod(Mod), ItemMod(Mod),
ItemForeignMod(ForeignMod), ItemForeignMod(ForeignMod),
ItemTy(P<Ty>, Generics), ItemTy(P<Ty>, Generics),

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use abi::AbiSet; use abi;
use ast::*; use ast::*;
use ast_util; use ast_util;
use codemap::Span; use codemap::Span;
@ -224,19 +224,19 @@ impl Map {
} }
} }
pub fn get_foreign_abis(&self, id: NodeId) -> AbiSet { pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi {
let parent = self.get_parent(id); let parent = self.get_parent(id);
let abis = match self.find_entry(parent) { let abi = match self.find_entry(parent) {
Some(EntryItem(_, i)) => match i.node { Some(EntryItem(_, i)) => match i.node {
ItemForeignMod(ref nm) => Some(nm.abis), ItemForeignMod(ref nm) => Some(nm.abi),
_ => None _ => None
}, },
// Wrong but OK, because the only inlined foreign items are intrinsics. // Wrong but OK, because the only inlined foreign items are intrinsics.
Some(RootInlinedParent(_)) => Some(AbiSet::Intrinsic()), Some(RootInlinedParent(_)) => Some(abi::RustIntrinsic),
_ => None _ => None
}; };
match abis { match abi {
Some(abis) => abis, Some(abi) => abi,
None => fail!("expected foreign mod or inlined parent, found {}", None => fail!("expected foreign mod or inlined parent, found {}",
self.node_to_str(parent)) self.node_to_str(parent))
} }

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use abi::AbiSet; use abi;
use ast::{P, Ident}; use ast::{P, Ident};
use ast; use ast;
use ast_util; use ast_util;
@ -826,7 +826,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
Vec::new(), Vec::new(),
ast::ItemFn(self.fn_decl(inputs, output), ast::ItemFn(self.fn_decl(inputs, output),
ast::ImpureFn, ast::ImpureFn,
AbiSet::Rust(), abi::Rust,
generics, generics,
body)) body))
} }

View file

@ -170,7 +170,7 @@ pub trait Folder {
TyBareFn(@BareFnTy { TyBareFn(@BareFnTy {
lifetimes: f.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(), lifetimes: f.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(),
purity: f.purity, purity: f.purity,
abis: f.abis, abi: f.abi,
decl: self.fold_fn_decl(f.decl) decl: self.fold_fn_decl(f.decl)
}) })
} }
@ -198,7 +198,7 @@ pub trait Folder {
fn fold_foreign_mod(&mut self, nm: &ForeignMod) -> ForeignMod { fn fold_foreign_mod(&mut self, nm: &ForeignMod) -> ForeignMod {
ast::ForeignMod { ast::ForeignMod {
abis: nm.abis, abi: nm.abi,
view_items: nm.view_items view_items: nm.view_items
.iter() .iter()
.map(|x| self.fold_view_item(x)) .map(|x| self.fold_view_item(x))

View file

@ -657,7 +657,7 @@ mod test {
variadic: false variadic: false
}), }),
ast::ImpureFn, ast::ImpureFn,
abi::AbiSet::Rust(), abi::Rust,
ast::Generics{ // no idea on either of these: ast::Generics{ // no idea on either of these:
lifetimes: Vec::new(), lifetimes: Vec::new(),
ty_params: OwnedSlice::empty(), ty_params: OwnedSlice::empty(),

View file

@ -11,7 +11,6 @@
#![macro_escape] #![macro_escape]
use abi; use abi;
use abi::AbiSet;
use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil}; use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil};
use ast::{BareFnTy, ClosureTy}; use ast::{BareFnTy, ClosureTy};
use ast::{RegionTyParamBound, TraitTyParamBound}; use ast::{RegionTyParamBound, TraitTyParamBound};
@ -873,17 +872,17 @@ impl<'a> Parser<'a> {
*/ */
let abis = if self.eat_keyword(keywords::Extern) { let abi = if self.eat_keyword(keywords::Extern) {
self.parse_opt_abis().unwrap_or(AbiSet::C()) self.parse_opt_abi().unwrap_or(abi::C)
} else { } else {
AbiSet::Rust() abi::Rust
}; };
let purity = self.parse_unsafety(); let purity = self.parse_unsafety();
self.expect_keyword(keywords::Fn); self.expect_keyword(keywords::Fn);
let (decl, lifetimes) = self.parse_ty_fn_decl(true); let (decl, lifetimes) = self.parse_ty_fn_decl(true);
return TyBareFn(@BareFnTy { return TyBareFn(@BareFnTy {
abis: abis, abi: abi,
purity: purity, purity: purity,
lifetimes: lifetimes, lifetimes: lifetimes,
decl: decl decl: decl
@ -3770,11 +3769,11 @@ impl<'a> Parser<'a> {
} }
// parse an item-position function declaration. // parse an item-position function declaration.
fn parse_item_fn(&mut self, purity: Purity, abis: AbiSet) -> ItemInfo { fn parse_item_fn(&mut self, purity: Purity, abi: abi::Abi) -> ItemInfo {
let (ident, generics) = self.parse_fn_header(); let (ident, generics) = self.parse_fn_header();
let decl = self.parse_fn_decl(false); let decl = self.parse_fn_decl(false);
let (inner_attrs, body) = self.parse_inner_attrs_and_block(); let (inner_attrs, body) = self.parse_inner_attrs_and_block();
(ident, ItemFn(decl, purity, abis, generics, body), Some(inner_attrs)) (ident, ItemFn(decl, purity, abi, generics, body), Some(inner_attrs))
} }
// parse a method in a trait impl, starting with `attrs` attributes. // parse a method in a trait impl, starting with `attrs` attributes.
@ -4237,7 +4236,7 @@ impl<'a> Parser<'a> {
// at this point, this is essentially a wrapper for // at this point, this is essentially a wrapper for
// parse_foreign_items. // parse_foreign_items.
fn parse_foreign_mod_items(&mut self, fn parse_foreign_mod_items(&mut self,
abis: AbiSet, abi: abi::Abi,
first_item_attrs: Vec<Attribute> ) first_item_attrs: Vec<Attribute> )
-> ForeignMod { -> ForeignMod {
let ParsedItemsAndViewItems { let ParsedItemsAndViewItems {
@ -4252,7 +4251,7 @@ impl<'a> Parser<'a> {
} }
assert!(self.token == token::RBRACE); assert!(self.token == token::RBRACE);
ast::ForeignMod { ast::ForeignMod {
abis: abis, abi: abi,
view_items: view_items, view_items: view_items,
items: foreign_items items: foreign_items
} }
@ -4310,17 +4309,17 @@ impl<'a> Parser<'a> {
/// extern {} /// extern {}
fn parse_item_foreign_mod(&mut self, fn parse_item_foreign_mod(&mut self,
lo: BytePos, lo: BytePos,
opt_abis: Option<AbiSet>, opt_abi: Option<abi::Abi>,
visibility: Visibility, visibility: Visibility,
attrs: Vec<Attribute> ) attrs: Vec<Attribute> )
-> ItemOrViewItem { -> ItemOrViewItem {
self.expect(&token::LBRACE); self.expect(&token::LBRACE);
let abis = opt_abis.unwrap_or(AbiSet::C()); let abi = opt_abi.unwrap_or(abi::C);
let (inner, next) = self.parse_inner_attrs_and_next(); let (inner, next) = self.parse_inner_attrs_and_next();
let m = self.parse_foreign_mod_items(abis, next); let m = self.parse_foreign_mod_items(abi, next);
self.expect(&token::RBRACE); self.expect(&token::RBRACE);
let item = self.mk_item(lo, let item = self.mk_item(lo,
@ -4440,45 +4439,29 @@ impl<'a> Parser<'a> {
// Parses a string as an ABI spec on an extern type or module. Consumes // Parses a string as an ABI spec on an extern type or module. Consumes
// the `extern` keyword, if one is found. // the `extern` keyword, if one is found.
fn parse_opt_abis(&mut self) -> Option<AbiSet> { fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
match self.token { match self.token {
token::LIT_STR(s) token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => {
| token::LIT_STR_RAW(s, _) => {
self.bump(); self.bump();
let identifier_string = token::get_ident(s); let identifier_string = token::get_ident(s);
let the_string = identifier_string.get(); let the_string = identifier_string.get();
let mut abis = AbiSet::empty(); match abi::lookup(the_string) {
for word in the_string.words() { Some(abi) => Some(abi),
match abi::lookup(word) { None => {
Some(abi) => { self.span_err(
if abis.contains(abi) { self.span,
self.span_err( format!("illegal ABI: \
self.span, expected one of [{}], \
format!("ABI `{}` appears twice", found `{}`",
word)); abi::all_names().connect(", "),
} else { the_string));
abis.add(abi); None
} }
} }
None => {
self.span_err(
self.span,
format!("illegal ABI: \
expected one of [{}], \
found `{}`",
abi::all_names().connect(", "),
word));
}
}
}
Some(abis)
} }
_ => { _ => None,
None }
}
}
} }
// parse one of the items or view items allowed by the // parse one of the items or view items allowed by the
@ -4531,13 +4514,13 @@ impl<'a> Parser<'a> {
return self.parse_item_extern_crate(lo, visibility, attrs); return self.parse_item_extern_crate(lo, visibility, attrs);
} }
let opt_abis = self.parse_opt_abis(); let opt_abi = self.parse_opt_abi();
if self.eat_keyword(keywords::Fn) { if self.eat_keyword(keywords::Fn) {
// EXTERN FUNCTION ITEM // EXTERN FUNCTION ITEM
let abis = opt_abis.unwrap_or(AbiSet::C()); let abi = opt_abi.unwrap_or(abi::C);
let (ident, item_, extra_attrs) = let (ident, item_, extra_attrs) =
self.parse_item_fn(ExternFn, abis); self.parse_item_fn(ExternFn, abi);
let item = self.mk_item(lo, let item = self.mk_item(lo,
self.last_span.hi, self.last_span.hi,
ident, ident,
@ -4546,7 +4529,7 @@ impl<'a> Parser<'a> {
maybe_append(attrs, extra_attrs)); maybe_append(attrs, extra_attrs));
return IoviItem(item); return IoviItem(item);
} else if self.token == token::LBRACE { } else if self.token == token::LBRACE {
return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs); return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
} }
let token_str = self.this_token_to_str(); let token_str = self.this_token_to_str();
@ -4572,7 +4555,7 @@ impl<'a> Parser<'a> {
// FUNCTION ITEM // FUNCTION ITEM
self.bump(); self.bump();
let (ident, item_, extra_attrs) = let (ident, item_, extra_attrs) =
self.parse_item_fn(ImpureFn, AbiSet::Rust()); self.parse_item_fn(ImpureFn, abi::Rust);
let item = self.mk_item(lo, let item = self.mk_item(lo,
self.last_span.hi, self.last_span.hi,
ident, ident,
@ -4587,7 +4570,7 @@ impl<'a> Parser<'a> {
self.bump(); self.bump();
self.expect_keyword(keywords::Fn); self.expect_keyword(keywords::Fn);
let (ident, item_, extra_attrs) = let (ident, item_, extra_attrs) =
self.parse_item_fn(UnsafeFn, AbiSet::Rust()); self.parse_item_fn(UnsafeFn, abi::Rust);
let item = self.mk_item(lo, let item = self.mk_item(lo,
self.last_span.hi, self.last_span.hi,
ident, ident,

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use abi::AbiSet; use abi;
use ast::{P, RegionTyParamBound, TraitTyParamBound, Required, Provided}; use ast::{P, RegionTyParamBound, TraitTyParamBound, Required, Provided};
use ast; use ast;
use ast_util; use ast_util;
@ -190,7 +190,7 @@ pub fn fun_to_str(decl: &ast::FnDecl, purity: ast::Purity, name: ast::Ident,
opt_explicit_self: Option<ast::ExplicitSelf_>, opt_explicit_self: Option<ast::ExplicitSelf_>,
generics: &ast::Generics) -> ~str { generics: &ast::Generics) -> ~str {
to_str(|s| { to_str(|s| {
try!(s.print_fn(decl, Some(purity), AbiSet::Rust(), try!(s.print_fn(decl, Some(purity), abi::Rust,
name, generics, opt_explicit_self, ast::Inherited)); name, generics, opt_explicit_self, ast::Inherited));
try!(s.end()); // Close the head box try!(s.end()); // Close the head box
s.end() // Close the outer box s.end() // Close the outer box
@ -478,7 +478,7 @@ impl<'a> State<'a> {
lifetimes: f.lifetimes.clone(), lifetimes: f.lifetimes.clone(),
ty_params: OwnedSlice::empty() ty_params: OwnedSlice::empty()
}; };
try!(self.print_ty_fn(Some(f.abis), None, &None, try!(self.print_ty_fn(Some(f.abi), None, &None,
f.purity, ast::Many, f.decl, None, &None, f.purity, ast::Many, f.decl, None, &None,
Some(&generics), None)); Some(&generics), None));
} }
@ -524,7 +524,7 @@ impl<'a> State<'a> {
try!(self.print_outer_attributes(item.attrs.as_slice())); try!(self.print_outer_attributes(item.attrs.as_slice()));
match item.node { match item.node {
ast::ForeignItemFn(decl, ref generics) => { ast::ForeignItemFn(decl, ref generics) => {
try!(self.print_fn(decl, None, AbiSet::Rust(), item.ident, generics, try!(self.print_fn(decl, None, abi::Rust, item.ident, generics,
None, item.vis)); None, item.vis));
try!(self.end()); // end head-ibox try!(self.end()); // end head-ibox
try!(word(&mut self.s, ";")); try!(word(&mut self.s, ";"));
@ -590,7 +590,7 @@ impl<'a> State<'a> {
} }
ast::ItemForeignMod(ref nmod) => { ast::ItemForeignMod(ref nmod) => {
try!(self.head("extern")); try!(self.head("extern"));
try!(self.word_nbsp(nmod.abis.to_str())); try!(self.word_nbsp(nmod.abi.to_str()));
try!(self.bopen()); try!(self.bopen());
try!(self.print_foreign_mod(nmod, item.attrs.as_slice())); try!(self.print_foreign_mod(nmod, item.attrs.as_slice()));
try!(self.bclose(item.span)); try!(self.bclose(item.span));
@ -883,7 +883,7 @@ impl<'a> State<'a> {
try!(self.hardbreak_if_not_bol()); try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(meth.span.lo)); try!(self.maybe_print_comment(meth.span.lo));
try!(self.print_outer_attributes(meth.attrs.as_slice())); try!(self.print_outer_attributes(meth.attrs.as_slice()));
try!(self.print_fn(meth.decl, Some(meth.purity), AbiSet::Rust(), try!(self.print_fn(meth.decl, Some(meth.purity), abi::Rust,
meth.ident, &meth.generics, Some(meth.explicit_self.node), meth.ident, &meth.generics, Some(meth.explicit_self.node),
meth.vis)); meth.vis));
try!(word(&mut self.s, " ")); try!(word(&mut self.s, " "));
@ -1717,14 +1717,14 @@ impl<'a> State<'a> {
pub fn print_fn(&mut self, pub fn print_fn(&mut self,
decl: &ast::FnDecl, decl: &ast::FnDecl,
purity: Option<ast::Purity>, purity: Option<ast::Purity>,
abis: AbiSet, abi: abi::Abi,
name: ast::Ident, name: ast::Ident,
generics: &ast::Generics, generics: &ast::Generics,
opt_explicit_self: Option<ast::ExplicitSelf_>, opt_explicit_self: Option<ast::ExplicitSelf_>,
vis: ast::Visibility) -> IoResult<()> { vis: ast::Visibility) -> IoResult<()> {
try!(self.head("")); try!(self.head(""));
try!(self.print_fn_header_info(opt_explicit_self, purity, abis, try!(self.print_fn_header_info(opt_explicit_self, purity, abi,
ast::Many, None, vis)); ast::Many, None, vis));
try!(self.nbsp()); try!(self.nbsp());
try!(self.print_ident(name)); try!(self.print_ident(name));
try!(self.print_generics(generics)); try!(self.print_generics(generics));
@ -2016,7 +2016,7 @@ impl<'a> State<'a> {
} }
pub fn print_ty_fn(&mut self, pub fn print_ty_fn(&mut self,
opt_abis: Option<AbiSet>, opt_abi: Option<abi::Abi>,
opt_sigil: Option<ast::Sigil>, opt_sigil: Option<ast::Sigil>,
opt_region: &Option<ast::Lifetime>, opt_region: &Option<ast::Lifetime>,
purity: ast::Purity, purity: ast::Purity,
@ -2034,14 +2034,14 @@ impl<'a> State<'a> {
if opt_sigil == Some(ast::OwnedSigil) && onceness == ast::Once { if opt_sigil == Some(ast::OwnedSigil) && onceness == ast::Once {
try!(word(&mut self.s, "proc")); try!(word(&mut self.s, "proc"));
} else if opt_sigil == Some(ast::BorrowedSigil) { } else if opt_sigil == Some(ast::BorrowedSigil) {
try!(self.print_extern_opt_abis(opt_abis)); try!(self.print_extern_opt_abi(opt_abi));
for lifetime in opt_region.iter() { for lifetime in opt_region.iter() {
try!(self.print_lifetime(lifetime)); try!(self.print_lifetime(lifetime));
} }
try!(self.print_purity(purity)); try!(self.print_purity(purity));
try!(self.print_onceness(onceness)); try!(self.print_onceness(onceness));
} else { } else {
try!(self.print_opt_abis_and_extern_if_nondefault(opt_abis)); try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
try!(self.print_opt_sigil(opt_sigil)); try!(self.print_opt_sigil(opt_sigil));
try!(self.print_opt_lifetime(opt_region)); try!(self.print_opt_lifetime(opt_region));
try!(self.print_purity(purity)); try!(self.print_purity(purity));
@ -2303,24 +2303,25 @@ impl<'a> State<'a> {
} }
} }
pub fn print_opt_abis_and_extern_if_nondefault(&mut self, pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
opt_abis: Option<AbiSet>) opt_abi: Option<abi::Abi>)
-> IoResult<()> { -> IoResult<()> {
match opt_abis { match opt_abi {
Some(abis) if !abis.is_rust() => { Some(abi::Rust) => Ok(()),
Some(abi) => {
try!(self.word_nbsp("extern")); try!(self.word_nbsp("extern"));
self.word_nbsp(abis.to_str()) self.word_nbsp(abi.to_str())
} }
Some(_) | None => Ok(()) None => Ok(())
} }
} }
pub fn print_extern_opt_abis(&mut self, pub fn print_extern_opt_abi(&mut self,
opt_abis: Option<AbiSet>) -> IoResult<()> { opt_abi: Option<abi::Abi>) -> IoResult<()> {
match opt_abis { match opt_abi {
Some(abis) => { Some(abi) => {
try!(self.word_nbsp("extern")); try!(self.word_nbsp("extern"));
self.word_nbsp(abis.to_str()) self.word_nbsp(abi.to_str())
} }
None => Ok(()) None => Ok(())
} }
@ -2339,15 +2340,15 @@ impl<'a> State<'a> {
pub fn print_fn_header_info(&mut self, pub fn print_fn_header_info(&mut self,
_opt_explicit_self: Option<ast::ExplicitSelf_>, _opt_explicit_self: Option<ast::ExplicitSelf_>,
opt_purity: Option<ast::Purity>, opt_purity: Option<ast::Purity>,
abis: AbiSet, abi: abi::Abi,
onceness: ast::Onceness, onceness: ast::Onceness,
opt_sigil: Option<ast::Sigil>, opt_sigil: Option<ast::Sigil>,
vis: ast::Visibility) -> IoResult<()> { vis: ast::Visibility) -> IoResult<()> {
try!(word(&mut self.s, visibility_qualified(vis, ""))); try!(word(&mut self.s, visibility_qualified(vis, "")));
if abis != AbiSet::Rust() { if abi != abi::Rust {
try!(self.word_nbsp("extern")); try!(self.word_nbsp("extern"));
try!(self.word_nbsp(abis.to_str())); try!(self.word_nbsp(abi.to_str()));
if opt_purity != Some(ast::ExternFn) { if opt_purity != Some(ast::ExternFn) {
try!(self.print_opt_purity(opt_purity)); try!(self.print_opt_purity(opt_purity));

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use abi::AbiSet; use abi::Abi;
use ast::*; use ast::*;
use ast; use ast;
use codemap::Span; use codemap::Span;
@ -29,7 +29,7 @@ use owned_slice::OwnedSlice;
pub enum FnKind<'a> { pub enum FnKind<'a> {
// fn foo() or extern "Abi" fn foo() // fn foo() or extern "Abi" fn foo()
FkItemFn(Ident, &'a Generics, Purity, AbiSet), FkItemFn(Ident, &'a Generics, Purity, Abi),
// fn foo(&self) // fn foo(&self)
FkMethod(Ident, &'a Generics, &'a Method), FkMethod(Ident, &'a Generics, &'a Method),