From 6965fe4bceea836586bd8e7aa01a92a35b467f78 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 13 Mar 2013 22:25:28 -0400 Subject: Add AbiSet and integrate it into the AST. I believe this patch incorporates all expected syntax changes from extern function reform (#3678). You can now write things like: extern "" fn foo(s: S) -> T { ... } extern "" mod { ... } extern "" fn(S) -> T The ABI for foreign functions is taken from this syntax (rather than from an annotation). We support the full ABI specification I described on the mailing list. The correct ABI is chosen based on the target architecture. Calls by pointer to C functions are not yet supported, and the Rust type of crust fns is still *u8. --- src/libsyntax/print/pprust.rs | 64 +++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 17 deletions(-) (limited to 'src/libsyntax/print/pprust.rs') diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 7ca5fba4c81..0ec7bdba3d1 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -10,6 +10,8 @@ use core::prelude::*; +use abi::AbiSet; +use abi; use ast::{RegionTyParamBound, TraitTyParamBound, required, provided}; use ast; use ast_util; @@ -186,7 +188,8 @@ pub fn fun_to_str(decl: &ast::fn_decl, purity: ast::purity, name: ast::ident, generics: &ast::Generics, intr: @ident_interner) -> ~str { do io::with_str_writer |wr| { let s = rust_printer(wr, intr); - print_fn(s, decl, purity, name, generics, opt_self_ty, ast::inherited); + print_fn(s, decl, Some(purity), AbiSet::Rust(), + name, generics, opt_self_ty, ast::inherited); end(s); // Close the head box end(s); // Close the outer box eof(s.s); @@ -405,7 +408,7 @@ pub fn print_type(s: @ps, &&ty: @ast::Ty) { ast::ty_bare_fn(f) => { let generics = ast::Generics {lifetimes: copy f.lifetimes, ty_params: opt_vec::Empty}; - print_ty_fn(s, Some(f.abi), None, None, + print_ty_fn(s, Some(f.abis), None, None, f.purity, ast::Many, &f.decl, None, Some(&generics), None); } @@ -446,7 +449,7 @@ pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) { print_outer_attributes(s, item.attrs); match item.node { ast::foreign_item_fn(ref decl, purity, ref generics) => { - print_fn(s, decl, purity, item.ident, generics, None, + print_fn(s, decl, Some(purity), AbiSet::Rust(), item.ident, generics, None, ast::inherited); end(s); // end head-ibox word(s.s, ~";"); @@ -485,11 +488,12 @@ pub fn print_item(s: @ps, &&item: @ast::item) { end(s); // end the outer cbox } - ast::item_fn(ref decl, purity, ref typarams, ref body) => { + ast::item_fn(ref decl, purity, abi, ref typarams, ref body) => { print_fn( s, decl, - purity, + Some(purity), + abi, item.ident, typarams, None, @@ -508,8 +512,7 @@ pub fn print_item(s: @ps, &&item: @ast::item) { } ast::item_foreign_mod(ref nmod) => { head(s, visibility_qualified(item.vis, ~"extern")); - print_string(s, *s.intr.get(nmod.abi)); - nbsp(s); + word_nbsp(s, nmod.abis.to_str()); match nmod.sort { ast::named => { word_nbsp(s, ~"mod"); @@ -817,7 +820,7 @@ pub fn print_method(s: @ps, meth: @ast::method) { hardbreak_if_not_bol(s); maybe_print_comment(s, meth.span.lo); print_outer_attributes(s, meth.attrs); - print_fn(s, &meth.decl, meth.purity, + print_fn(s, &meth.decl, Some(meth.purity), AbiSet::Rust(), meth.ident, &meth.generics, Some(meth.self_ty.node), meth.vis); word(s.s, ~" "); @@ -1650,13 +1653,14 @@ pub fn print_self_ty(s: @ps, self_ty: ast::self_ty_) -> bool { pub fn print_fn(s: @ps, decl: &ast::fn_decl, - purity: ast::purity, + purity: Option, + abis: AbiSet, name: ast::ident, generics: &ast::Generics, opt_self_ty: Option, vis: ast::visibility) { head(s, ~""); - print_fn_header_info(s, purity, ast::Many, None, vis); + print_fn_header_info(s, opt_self_ty, purity, abis, ast::Many, None, vis); nbsp(s); print_ident(s, name); print_generics(s, generics); @@ -1905,7 +1909,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { } pub fn print_ty_fn(s: @ps, - opt_abi: Option, + opt_abis: Option, opt_sigil: Option, opt_region: Option<@ast::Lifetime>, purity: ast::purity, @@ -1918,7 +1922,7 @@ pub fn print_ty_fn(s: @ps, // Duplicates the logic in `print_fn_header_info()`. This is because that // function prints the sigil in the wrong place. That should be fixed. - print_opt_abi(s, opt_abi); + print_extern_opt_abis(s, opt_abis); print_opt_sigil(s, opt_sigil); print_opt_lifetime(s, opt_region); print_purity(s, purity); @@ -2146,9 +2150,22 @@ pub fn next_comment(s: @ps) -> Option { } } -pub fn print_opt_abi(s: @ps, opt_abi: Option) { - match opt_abi { - Some(ast::RustAbi) => { word_nbsp(s, ~"extern"); } +pub fn print_opt_purity(s: @ps, opt_purity: Option) { + match opt_purity { + Some(ast::impure_fn) => { } + Some(purity) => { + word_nbsp(s, purity_to_str(purity)); + } + None => {} + } +} + +pub fn print_extern_opt_abis(s: @ps, opt_abis: Option) { + match opt_abis { + Some(abis) => { + word_nbsp(s, ~"extern"); + word_nbsp(s, abis.to_str()); + } None => {} }; } @@ -2163,12 +2180,25 @@ pub fn print_opt_sigil(s: @ps, opt_sigil: Option) { } pub fn print_fn_header_info(s: @ps, - purity: ast::purity, + opt_sty: Option, + opt_purity: Option, + abis: AbiSet, onceness: ast::Onceness, opt_sigil: Option, vis: ast::visibility) { word(s.s, visibility_qualified(vis, ~"")); - print_purity(s, purity); + + if abis != AbiSet::Rust() { + word_nbsp(s, ~"extern"); + word_nbsp(s, abis.to_str()); + + if opt_purity != Some(ast::extern_fn) { + print_opt_purity(s, opt_purity); + } + } else { + print_opt_purity(s, opt_purity); + } + print_onceness(s, onceness); word(s.s, ~"fn"); print_opt_sigil(s, opt_sigil); -- cgit 1.4.1-3-g733a5