summary refs log tree commit diff
path: root/src/libsyntax/print/pprust.rs
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-03-13 22:25:28 -0400
committerBrian Anderson <banderson@mozilla.com>2013-03-29 18:36:20 -0700
commit6965fe4bceea836586bd8e7aa01a92a35b467f78 (patch)
treed95089f050cd67db2a5171a799763faa09f5b0a8 /src/libsyntax/print/pprust.rs
parentf864934f548be9f03d2c0512de8d7e908469e2ae (diff)
downloadrust-6965fe4bceea836586bd8e7aa01a92a35b467f78.tar.gz
rust-6965fe4bceea836586bd8e7aa01a92a35b467f78.zip
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.
Diffstat (limited to 'src/libsyntax/print/pprust.rs')
-rw-r--r--src/libsyntax/print/pprust.rs64
1 files changed, 47 insertions, 17 deletions
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<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);