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))
}).collect();
ast::ForeignMod {
abis: nm.abis,
abi: nm.abi,
view_items: filtered_view_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) {
match i.node {
ast::ItemForeignMod(ref fm) => {
if fm.abis.is_rust() || fm.abis.is_intrinsic() {
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
return;
}

View File

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

View File

@ -20,7 +20,6 @@ use middle::ty;
use std::str;
use std::uint;
use syntax::abi::AbiSet;
use syntax::abi;
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), '[');
let mut abis = AbiSet::empty();
while peek(st) != ']' {
scan(st, |c| c == ',', |bytes| {
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;
scan(st, |c| c == ']', |bytes| {
let abi_str = str::from_utf8(bytes).unwrap().to_owned();
abi::lookup(abi_str).expect(abi_str)
})
}
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));
ty::BareFnTy {
purity: purity,
abis: abi,
abi: abi,
sig: sig
}
}

View File

@ -23,7 +23,7 @@ use std::fmt;
use middle::ty::param_ty;
use middle::ty;
use syntax::abi::AbiSet;
use syntax::abi::Abi;
use syntax::ast;
use syntax::ast::*;
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, "[");
abis.each(|abi| {
mywrite!(w, "{},", abi.name());
true
});
mywrite!(w, "{}", abi.name());
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) {
enc_purity(w, ft.purity);
enc_abi_set(w, ft.abis);
enc_abi(w, ft.abi);
enc_fn_sig(w, cx, &ft.sig);
}

View File

@ -59,6 +59,7 @@ use std::u32;
use std::u64;
use std::u8;
use collections::SmallIntMap;
use syntax::abi;
use syntax::ast_map;
use syntax::ast_util::IdVisitingOperation;
use syntax::attr::{AttrMetaMethods, AttributeMethods};
@ -892,7 +893,7 @@ fn check_item_ctypes(cx: &Context, it: &ast::Item) {
}
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() {
match ni.node {
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);
match ty::get(t).sty {
ty::ty_bare_fn(ref fn_ty) => {
match fn_ty.abis.for_target(ccx.sess().targ_cfg.os,
ccx.sess().targ_cfg.arch) {
match fn_ty.abi.for_target(ccx.sess().targ_cfg.os,
ccx.sess().targ_cfg.arch) {
Some(Rust) | Some(RustIntrinsic) => {
get_extern_rust_fn(ccx,
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)
}
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 llty = type_of_fn_from_ty(ccx, t);
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) {
let _icx = push_ctxt("trans_item");
match item.node {
ast::ItemFn(decl, purity, _abis, ref generics, body) => {
ast::ItemFn(decl, purity, _abi, ref generics, body) => {
if purity == ast::ExternFn {
let llfndecl = get_item_val(ccx, item.id);
foreign::trans_rust_fn_with_foreign_abi(
@ -1721,7 +1721,7 @@ fn register_fn(ccx: &CrateContext,
-> ValueRef {
let f = match ty::get(node_type).sty {
ty::ty_bare_fn(ref f) => {
assert!(f.abis.is_rust() || f.abis.is_intrinsic());
assert!(f.abi == Rust || f.abi == RustIntrinsic);
f
}
_ => 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 {
ast::ForeignItemFn(..) => {
let abis = ccx.tcx.map.get_foreign_abis(id);
foreign::register_foreign_item_fn(ccx, abis, ni)
let abi = ccx.tcx.map.get_foreign_abi(id);
foreign::register_foreign_item_fn(ccx, abi, ni)
}
ast::ForeignItemStatic(..) => {
foreign::register_static(ccx, ni)

View File

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

View File

@ -27,7 +27,7 @@ use middle::ty::FnSig;
use middle::ty;
use std::cmp;
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::codemap::Span;
use syntax::parse::token::{InternedString, special_idents};
@ -73,10 +73,10 @@ struct LlvmSignature {
// Calls to external functions
pub fn llvm_calling_convention(ccx: &CrateContext,
abis: AbiSet) -> Option<CallConv> {
abi: Abi) -> Option<CallConv> {
let os = ccx.sess().targ_cfg.os;
let arch = ccx.sess().targ_cfg.arch;
abis.for_target(os, arch).map(|abi| {
abi.for_target(os, arch).map(|abi| {
match abi {
RustIntrinsic => {
// 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 {
/*!
* Registers a foreign function found in a library.
* Just adds a LLVM global.
*/
debug!("register_foreign_item_fn(abis={}, \
debug!("register_foreign_item_fn(abi={}, \
path={}, \
foreign_item.id={})",
abis.repr(ccx.tcx()),
abi.repr(ccx.tcx()),
ccx.tcx.map.path_to_str(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,
None => {
ccx.sess().span_fatal(foreign_item.span,
format!("ABI `{}` has no suitable calling convention \
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(llretptr));
let (fn_abis, fn_sig) = match ty::get(callee_ty).sty {
ty::ty_bare_fn(ref fn_ty) => (fn_ty.abis, fn_ty.sig.clone()),
let (fn_abi, fn_sig) = match ty::get(callee_ty).sty {
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")
};
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);
}
let cc = match llvm_calling_convention(ccx, fn_abis) {
let cc = match llvm_calling_convention(ccx, fn_abi) {
Some(cc) => cc,
None => {
// FIXME(#8357) We really ought to report a span here
ccx.sess().fatal(
format!("ABI string `{}` has no suitable ABI \
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() {
match foreign_item.node {
ast::ForeignItemFn(..) => {
let abis = foreign_mod.abis;
if !(abis.is_rust() || abis.is_intrinsic()) {
register_foreign_item_fn(ccx, abis, foreign_item);
match foreign_mod.abi {
Rust | RustIntrinsic => {}
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 (cconv, output) = match ty::get(t).sty {
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)
}
_ => 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.
let f = match ty::get(t).sty {
ty::ty_bare_fn(ref f) => {
assert!(!f.abis.is_rust() && !f.abis.is_intrinsic());
assert!(f.abi != Rust && f.abi != RustIntrinsic);
f
}
_ => {

View File

@ -34,6 +34,7 @@ use util::common::indenter;
use util::ppaux::Repr;
use std::c_str::ToCStr;
use syntax::abi::Rust;
use syntax::parse::token;
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");
// Replace the self type (&Self or ~Self) with an opaque pointer.
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)
}
_ => {

View File

@ -23,6 +23,7 @@ use middle::ty;
use middle::typeck;
use util::ppaux::Repr;
use syntax::abi;
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util::local_def;
@ -99,7 +100,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
match map_node {
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.
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 {
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
}
_ => fail!("expected bare rust fn or an intrinsic")

View File

@ -19,6 +19,7 @@ use util::ppaux::Repr;
use middle::trans::type_::Type;
use syntax::abi;
use syntax::ast;
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)
}
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,
false,
f.sig.inputs.as_slice(),

View File

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

View File

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

View File

@ -60,7 +60,7 @@ use middle::typeck::rscope::{RegionScope};
use middle::typeck::lookup_def_tcx;
use util::ppaux::Repr;
use syntax::abi::AbiSet;
use syntax::abi;
use syntax::{ast, ast_util};
use syntax::codemap::Span;
use syntax::owned_slice::OwnedSlice;
@ -519,12 +519,12 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
ty::mk_tup(tcx, flds)
}
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,
"variadic function must have C calling convention");
}
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) => {
if f.sigil == ast::ManagedSigil {
@ -666,20 +666,20 @@ pub fn ty_of_method<AC:AstConv>(
untransformed_self_ty: ty::t,
explicit_self: ast::ExplicitSelf,
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,
explicit_self: explicit_self
}), decl)
}
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 {
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,
purity: ast::Purity, abi: AbiSet,
purity: ast::Purity, abi: abi::Abi,
opt_self_info: Option<SelfInfo>,
decl: &ast::FnDecl) -> ty::BareFnTy {
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 {
purity: purity,
abis: abi,
abi: abi,
sig: ty::FnSig {
binder_id: id,
inputs: self_and_input_tys,

View File

@ -1164,7 +1164,7 @@ impl<'a> LookupContext<'a> {
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
sig: fn_sig,
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));

View File

@ -120,7 +120,7 @@ use std::mem::replace;
use std::result;
use std::slice;
use std::vec::Vec;
use syntax::abi::AbiSet;
use syntax::abi;
use syntax::ast::{Provided, Required};
use syntax::ast;
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);
}
ast::ItemForeignMod(ref m) => {
if m.abis.is_intrinsic() {
if m.abi == abi::RustIntrinsic {
for item in m.items.iter() {
check_intrinsic_type(ccx, *item);
}
@ -612,7 +612,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
match item.node {
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(
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 {
purity: ast::UnsafeFn,
abis: AbiSet::Intrinsic(),
abi: abi::RustIntrinsic,
sig: FnSig {binder_id: it.id,
inputs: inputs,
output: output,

View File

@ -48,7 +48,7 @@ use util::ppaux::Repr;
use std::rc::Rc;
use collections::HashSet;
use syntax::abi::AbiSet;
use syntax::abi;
use syntax::ast::{RegionTyParamBound, TraitTyParamBound};
use syntax::ast;
use syntax::ast_map;
@ -116,8 +116,8 @@ impl<'a> AstConv for CrateCtxt<'a> {
match self.tcx.map.find(id.node) {
Some(ast_map::NodeItem(item)) => ty_of_item(self, item),
Some(ast_map::NodeForeignItem(foreign_item)) => {
let abis = self.tcx.map.get_foreign_abis(id.node);
ty_of_foreign_item(self, foreign_item, abis)
let abi = self.tcx.map.get_foreign_abi(id.node);
ty_of_foreign_item(self, foreign_item, abi)
}
x => {
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,
span: Span,
abis: AbiSet,
abi: abi::Abi,
generics: &ast::Generics) {
if generics.ty_params.len() > 0 &&
!(abis.is_rust() || abis.is_intrinsic()) {
!(abi == abi::Rust || abi == abi::RustIntrinsic) {
ccx.tcx.sess.span_err(span,
"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
// moral failing, but at the moment it seems like the only
// 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);
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,
it: &ast::ForeignItem,
abis: AbiSet) -> ty::ty_param_bounds_and_ty
abi: abi::Abi) -> ty::ty_param_bounds_and_ty
{
match it.node {
ast::ForeignItemFn(fn_decl, ref generics) => {
@ -899,7 +899,7 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
fn_decl,
local_def(it.id),
generics,
abis)
abi)
}
ast::ForeignItemStatic(t, _) => {
ty::ty_param_bounds_and_ty {
@ -1003,7 +1003,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
decl: &ast::FnDecl,
def_id: ast::DefId,
ast_generics: &ast::Generics,
abis: AbiSet)
abi: abi::Abi)
-> ty::ty_param_bounds_and_ty {
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(
ccx.tcx,
ty::BareFnTy {
abis: abis,
abi: abi,
purity: ast::UnsafeFn,
sig: ty::FnSig {binder_id: def_id.node,
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 util::common::indenter;
use syntax::abi;
use syntax::ast::MutImmutable;
use syntax::ast;
@ -384,7 +385,7 @@ impl<'f> Coerce<'f> {
debug!("coerce_from_bare_fn(a={}, b={})",
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);
}

View File

@ -67,7 +67,7 @@ use std::result;
use syntax::ast::{Onceness, Purity};
use syntax::ast;
use syntax::owned_slice::OwnedSlice;
use syntax::abi::AbiSet;
use syntax::abi;
pub trait Combine {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a>;
@ -195,10 +195,10 @@ pub trait Combine {
fn bare_fn_tys(&self, a: &ty::BareFnTy,
b: &ty::BareFnTy) -> cres<ty::BareFnTy> {
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));
Ok(ty::BareFnTy {purity: purity,
abis: abi,
abi: abi,
sig: sig})
}
@ -248,7 +248,7 @@ pub trait Combine {
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 {
Ok(a)
} else {

View File

@ -358,7 +358,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
}
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
purity: ast::ImpureFn,
abis: abi::AbiSet::Rust(),
abi: abi::Rust,
sig: ty::FnSig {
binder_id: main_id,
inputs: Vec::new(),
@ -404,7 +404,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
purity: ast::ImpureFn,
abis: abi::AbiSet::Rust(),
abi: abi::Rust,
sig: ty::FnSig {
binder_id: start_id,
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::typeck;
use syntax::abi::AbiSet;
use syntax::abi;
use syntax::ast_map;
use syntax::codemap::{Span, Pos};
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,
purity: ast::Purity,
abis: AbiSet,
abi: abi::Abi,
ident: Option<ast::Ident>,
sig: &ty::FnSig)
-> ~str {
let mut s = if abis.is_rust() {
let mut s = if abi == abi::Rust {
~""
} else {
format!("extern {} ", abis.to_str())
format!("extern {} ", abi.to_str())
};
match purity {
@ -406,7 +406,7 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
closure_to_str(cx, *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_err => ~"[type error]",
@ -813,9 +813,9 @@ impl Repr for ast::Visibility {
impl Repr for ty::BareFnTy {
fn repr(&self, tcx: &ctxt) -> ~str {
format!("BareFnTy \\{purity: {:?}, abis: {}, sig: {}\\}",
format!("BareFnTy \\{purity: {:?}, abi: {}, sig: {}\\}",
self.purity,
self.abis.to_str(),
self.abi.to_str(),
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 {
self.to_str()
}
}
impl UserString for AbiSet {
impl UserString for abi::Abi {
fn user_string(&self, _tcx: &ctxt) -> ~str {
self.to_str()
}

View File

@ -975,7 +975,7 @@ impl Clean<BareFunctionDecl> for ast::BareFnTy {
type_params: Vec::new(),
},
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
//! usable for clean
use syntax::abi::AbiSet;
use syntax::abi;
use syntax::ast;
use syntax::ast_util;
use syntax::ast_map;
@ -95,7 +95,7 @@ impl<'a> RustdocVisitor<'a> {
}
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 {
debug!("Visiting fn");
Function {

View File

@ -9,12 +9,11 @@
// except according to those terms.
use std::fmt;
use std::fmt::Show;
#[deriving(Eq)]
pub enum Os { OsWin32, OsMacos, OsLinux, OsAndroid, OsFreebsd, }
#[deriving(Eq, TotalEq, Hash)]
#[deriving(Eq, TotalEq, Hash, Encodable, Decodable, Clone)]
pub enum Abi {
// NB: This ordering MUST match the AbiDatas array below.
// (This is ensured by the test indices_are_correct().)
@ -65,11 +64,6 @@ pub enum AbiArchitecture {
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] = &[
// Platform-specific ABIs
AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(IntelBits)},
@ -136,12 +130,20 @@ impl Abi {
self.data().name
}
pub fn for_target(&self, os: Os, arch: Architecture) -> Abi {
match (*self, os, arch) {
pub fn for_target(&self, os: Os, arch: Architecture) -> Option<Abi> {
// 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, _, _) => C,
(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 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.data().name.fmt(f)
}
}
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, "\"")
write!(f.buf, "\"{}\"", self.name())
}
}
@ -304,95 +177,6 @@ fn lookup_baz() {
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]
fn indices_are_correct() {
for (i, abi_data) in AbiDatas.iter().enumerate() {
@ -407,30 +191,14 @@ fn indices_are_correct() {
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]
fn pick_uniplatform() {
assert_eq!(get_arch([Stdcall], OsLinux, X86), Some(Stdcall));
assert_eq!(get_arch([Stdcall], OsLinux, Arm), None);
assert_eq!(get_arch([System], OsLinux, X86), Some(C));
assert_eq!(get_arch([System], OsWin32, X86), Some(Stdcall));
assert_eq!(get_arch([System], OsWin32, X86_64), Some(C));
assert_eq!(get_arch([System], OsWin32, Arm), Some(C));
assert_eq!(get_arch([Stdcall], OsWin32, X86), Some(Stdcall));
assert_eq!(get_arch([Stdcall], OsWin32, X86_64), Some(Stdcall));
assert_eq!(Stdcall.for_arch(OsLinux, X86), Some(Stdcall));
assert_eq!(Stdcall.for_arch(OsLinux, Arm), None);
assert_eq!(System.for_arch(OsLinux, X86), Some(C));
assert_eq!(System.for_arch(OsWin32, X86), Some(Stdcall));
assert_eq!(System.for_arch(OsWin32, X86_64), Some(C));
assert_eq!(System.for_arch(OsWin32, Arm), Some(C));
assert_eq!(Stdcall.for_arch(OsWin32, X86), Some(Stdcall));
assert_eq!(Stdcall.for_arch(OsWin32, X86_64), Some(Stdcall));
}

View File

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

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use abi::AbiSet;
use abi;
use ast::*;
use ast_util;
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 abis = match self.find_entry(parent) {
let abi = match self.find_entry(parent) {
Some(EntryItem(_, i)) => match i.node {
ItemForeignMod(ref nm) => Some(nm.abis),
ItemForeignMod(ref nm) => Some(nm.abi),
_ => None
},
// Wrong but OK, because the only inlined foreign items are intrinsics.
Some(RootInlinedParent(_)) => Some(AbiSet::Intrinsic()),
Some(RootInlinedParent(_)) => Some(abi::RustIntrinsic),
_ => None
};
match abis {
Some(abis) => abis,
match abi {
Some(abi) => abi,
None => fail!("expected foreign mod or inlined parent, found {}",
self.node_to_str(parent))
}

View File

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

View File

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

View File

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

View File

@ -11,7 +11,6 @@
#![macro_escape]
use abi;
use abi::AbiSet;
use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil};
use ast::{BareFnTy, ClosureTy};
use ast::{RegionTyParamBound, TraitTyParamBound};
@ -873,17 +872,17 @@ impl<'a> Parser<'a> {
*/
let abis = if self.eat_keyword(keywords::Extern) {
self.parse_opt_abis().unwrap_or(AbiSet::C())
let abi = if self.eat_keyword(keywords::Extern) {
self.parse_opt_abi().unwrap_or(abi::C)
} else {
AbiSet::Rust()
abi::Rust
};
let purity = self.parse_unsafety();
self.expect_keyword(keywords::Fn);
let (decl, lifetimes) = self.parse_ty_fn_decl(true);
return TyBareFn(@BareFnTy {
abis: abis,
abi: abi,
purity: purity,
lifetimes: lifetimes,
decl: decl
@ -3770,11 +3769,11 @@ impl<'a> Parser<'a> {
}
// 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 decl = self.parse_fn_decl(false);
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.
@ -4237,7 +4236,7 @@ impl<'a> Parser<'a> {
// at this point, this is essentially a wrapper for
// parse_foreign_items.
fn parse_foreign_mod_items(&mut self,
abis: AbiSet,
abi: abi::Abi,
first_item_attrs: Vec<Attribute> )
-> ForeignMod {
let ParsedItemsAndViewItems {
@ -4252,7 +4251,7 @@ impl<'a> Parser<'a> {
}
assert!(self.token == token::RBRACE);
ast::ForeignMod {
abis: abis,
abi: abi,
view_items: view_items,
items: foreign_items
}
@ -4310,17 +4309,17 @@ impl<'a> Parser<'a> {
/// extern {}
fn parse_item_foreign_mod(&mut self,
lo: BytePos,
opt_abis: Option<AbiSet>,
opt_abi: Option<abi::Abi>,
visibility: Visibility,
attrs: Vec<Attribute> )
-> ItemOrViewItem {
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 m = self.parse_foreign_mod_items(abis, next);
let m = self.parse_foreign_mod_items(abi, next);
self.expect(&token::RBRACE);
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
// 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 {
token::LIT_STR(s)
| token::LIT_STR_RAW(s, _) => {
token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => {
self.bump();
let identifier_string = token::get_ident(s);
let the_string = identifier_string.get();
let mut abis = AbiSet::empty();
for word in the_string.words() {
match abi::lookup(word) {
Some(abi) => {
if abis.contains(abi) {
self.span_err(
self.span,
format!("ABI `{}` appears twice",
word));
} else {
abis.add(abi);
}
}
None => {
self.span_err(
self.span,
format!("illegal ABI: \
expected one of [{}], \
found `{}`",
abi::all_names().connect(", "),
word));
}
}
}
Some(abis)
match abi::lookup(the_string) {
Some(abi) => Some(abi),
None => {
self.span_err(
self.span,
format!("illegal ABI: \
expected one of [{}], \
found `{}`",
abi::all_names().connect(", "),
the_string));
None
}
}
}
_ => {
None
}
}
_ => None,
}
}
// 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);
}
let opt_abis = self.parse_opt_abis();
let opt_abi = self.parse_opt_abi();
if self.eat_keyword(keywords::Fn) {
// EXTERN FUNCTION ITEM
let abis = opt_abis.unwrap_or(AbiSet::C());
let abi = opt_abi.unwrap_or(abi::C);
let (ident, item_, extra_attrs) =
self.parse_item_fn(ExternFn, abis);
self.parse_item_fn(ExternFn, abi);
let item = self.mk_item(lo,
self.last_span.hi,
ident,
@ -4546,7 +4529,7 @@ impl<'a> Parser<'a> {
maybe_append(attrs, extra_attrs));
return IoviItem(item);
} 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();
@ -4572,7 +4555,7 @@ impl<'a> Parser<'a> {
// FUNCTION ITEM
self.bump();
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,
self.last_span.hi,
ident,
@ -4587,7 +4570,7 @@ impl<'a> Parser<'a> {
self.bump();
self.expect_keyword(keywords::Fn);
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,
self.last_span.hi,
ident,

View File

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

View File

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