提交 57e0908a 编写于 作者: A Alex Crichton

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
上级 1a1c47b9
......@@ -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
}
......
......@@ -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;
}
......
......@@ -33,7 +33,7 @@
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);
});
}
......
......@@ -20,7 +20,6 @@
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
}
}
......
......@@ -23,7 +23,7 @@
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);
}
......
......@@ -59,6 +59,7 @@
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_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
}
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),
......
......@@ -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 @@ fn visit_item(&mut self, i: &ast::Item, _:()) {
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)
......
......@@ -50,7 +50,7 @@
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.
......
......@@ -27,7 +27,7 @@
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 @@ fn build_rust_fn(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
}
_ => {
......
......@@ -34,6 +34,7 @@
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)
}
_ => {
......
......@@ -23,6 +23,7 @@
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")
......
......@@ -19,6 +19,7 @@
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(),
......
......@@ -51,7 +51,7 @@
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);
......
......@@ -48,7 +48,7 @@ fn fold_bare_fn_ty(&mut self,
fty: &ty::BareFnTy)
-> ty::BareFnTy {
ty::BareFnTy { sig: self.fold_sig(&fty.sig),
abis: fty.abis,
abi: fty.abi,
purity: fty.purity }
}
......
......@@ -60,7 +60,7 @@
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 @@ fn mk_pointer<AC:AstConv,
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,
......
......@@ -1164,7 +1164,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
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));
......
......@@ -120,7 +120,7 @@
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 @@ fn param(ccx: &CrateCtxt, n: uint) -> ty::t {
};
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,
......
......@@ -48,7 +48,7 @@
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 @@ fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty {
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,
......
......@@ -77,6 +77,7 @@ fn foo<A>(a: A, b: A) { ... }
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 @@ fn coerce_from_bare_fn(&self, a: ty::t, fn_ty_a: &ty::BareFnTy, b: ty::t)
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);
}
......
......@@ -67,7 +67,7 @@
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 @@ fn relate_region_params<C:Combine>(this: &C,
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 @@ fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
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 {
......
......@@ -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!(
......
......@@ -23,7 +23,7 @@
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 @@ fn fn_input_to_str(cx: &ctxt, input: ty::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 @@ fn push_sig_to_str(cx: &ctxt,
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 @@ fn repr(&self, _tcx: &ctxt) -> ~str {
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 @@ fn user_string(&self, _tcx: &ctxt) -> ~str {
}
}
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()
}
......
......@@ -975,7 +975,7 @@ fn clean(&self) -> BareFunctionDecl {
type_params: Vec::new(),
},
decl: self.decl.clean(),
abi: self.abis.to_str(),
abi: self.abi.to_str(),
}
}
}
......
......@@ -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 @@ pub fn visit_enum_def(&mut self, it: &ast::Item, def: &ast::EnumDef,
}
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 {
......
......@@ -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 @@ pub fn name(&self) -> &'static str {
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 @@ fn bit(&self) -> u32 {
}
}
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));
}
......@@ -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),
......
......@@ -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 @@ pub fn get_parent_did(&self, id: NodeId) -> DefId {
}
}
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))
}
......
......@@ -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 @@ fn item_fn_poly(&self,
Vec::new(),
ast::ItemFn(self.fn_decl(inputs, output),
ast::ImpureFn,
AbiSet::Rust(),
abi::Rust,
generics,
body))
}
......
......@@ -170,7 +170,7 @@ fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
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 @@ fn fold_mod(&mut self, m: &Mod) -> Mod {
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))
......
......@@ -657,7 +657,7 @@ fn parser_done(p: Parser){
variadic: false
}),
ast::ImpureFn,
abi::AbiSet::Rust(),
abi::Rust,
ast::Generics{ // no idea on either of these:
lifetimes: Vec::new(),
ty_params: OwnedSlice::empty(),
......
......@@ -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 @@ pub fn parse_ty_bare_fn(&mut self) -> Ty_ {
*/
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 @@ fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
}
// 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 @@ fn parse_fn_purity(&mut self) -> Purity {
// 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 @@ fn parse_foreign_mod_items(&mut self,
}
assert!(self.token == token::RBRACE);
ast::ForeignMod {
abis: abis,
abi: abi,
view_items: view_items,
items: foreign_items
}
......@@ -4310,17 +4309,17 @@ fn parse_item_extern_crate(&mut self,
/// 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 @@ fn fn_expr_lookahead(tok: &token::Token) -> bool {
// 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 @@ fn parse_item_or_view_item(&mut self,
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 @@ fn parse_item_or_view_item(&mut self,
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 @@ fn parse_item_or_view_item(&mut self,
// 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 @@ fn parse_item_or_view_item(&mut self,
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,
......
......@@ -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 @@ pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
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 @@ pub fn print_foreign_item(&mut self,
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 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
}
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 @@ pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
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 @@ fn print_explicit_self(&mut self,
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 @@ pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> {
}
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 @@ pub fn print_ty_fn(&mut self,
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 @@ pub fn print_opt_purity(&mut self,
}
}
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 @@ pub fn print_opt_sigil(&mut self,
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));
......
......@@ -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 @@
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),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册