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 "<abi>" fn foo(s: S) -> T { ... } extern "<abi>" mod { ... } extern "<abi>" 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.
This commit is contained in:
parent
f864934f54
commit
6965fe4bce
72 changed files with 879 additions and 352 deletions
|
@ -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<ast::purity>,
|
||||
abis: AbiSet,
|
||||
name: ast::ident,
|
||||
generics: &ast::Generics,
|
||||
opt_self_ty: Option<ast::self_ty_>,
|
||||
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<ast::Abi>,
|
||||
opt_abis: Option<AbiSet>,
|
||||
opt_sigil: Option<ast::Sigil>,
|
||||
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<comments::cmnt> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn print_opt_abi(s: @ps, opt_abi: Option<ast::Abi>) {
|
||||
match opt_abi {
|
||||
Some(ast::RustAbi) => { word_nbsp(s, ~"extern"); }
|
||||
pub fn print_opt_purity(s: @ps, opt_purity: Option<ast::purity>) {
|
||||
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<AbiSet>) {
|
||||
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<ast::Sigil>) {
|
|||
}
|
||||
|
||||
pub fn print_fn_header_info(s: @ps,
|
||||
purity: ast::purity,
|
||||
opt_sty: Option<ast::self_ty_>,
|
||||
opt_purity: Option<ast::purity>,
|
||||
abis: AbiSet,
|
||||
onceness: ast::Onceness,
|
||||
opt_sigil: Option<ast::Sigil>,
|
||||
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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue