summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-11-27 17:25:55 -0800
committerPatrick Walton <pcwalton@mimiga.net>2012-11-28 11:28:16 -0800
commit61cfec3c52d3ac316b627c4b20c9c6e81e7521f2 (patch)
treecb814d1c1039b02d6baa62727eb91ce0911aa57d /src/libsyntax/parse
parentd2d6d955f45682399bce2a270e1ffaf2908fe0b0 (diff)
downloadrust-61cfec3c52d3ac316b627c4b20c9c6e81e7521f2.tar.gz
rust-61cfec3c52d3ac316b627c4b20c9c6e81e7521f2.zip
librustc: Parse `extern "C" { ... }`. r=brson
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs44
-rw-r--r--src/libsyntax/parse/token.rs4
2 files changed, 42 insertions, 6 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f340a52a4e7..e4d77e7da09 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3043,8 +3043,9 @@ impl Parser {
     }
 
     fn parse_foreign_mod_items(sort: ast::foreign_mod_sort,
-                               +first_item_attrs: ~[attribute]) ->
-        foreign_mod {
+                               +abi: ast::ident,
+                               +first_item_attrs: ~[attribute])
+                            -> foreign_mod {
         // Shouldn't be any view items since we've already parsed an item attr
         let {attrs_remaining, view_items, items: _, foreign_items} =
             self.parse_items_and_view_items(first_item_attrs,
@@ -3058,8 +3059,12 @@ impl Parser {
             initial_attrs = ~[];
             items.push(self.parse_foreign_item(attrs));
         }
-        return {sort: sort, view_items: view_items,
-            items: items};
+        return {
+            sort: sort,
+            abi: move abi,
+            view_items: view_items,
+            items: items
+        };
     }
 
     fn parse_item_foreign_mod(lo: BytePos,
@@ -3068,6 +3073,18 @@ impl Parser {
                               items_allowed: bool)
                            -> item_or_view_item {
 
+        // Parse the ABI.
+        let abi_opt;
+        match self.token {
+            token::LIT_STR(copy found_abi) => {
+                self.bump();
+                abi_opt = Some(found_abi);
+            }
+            _ => {
+                abi_opt = None;
+            }
+        }
+
         let mut must_be_named_mod = false;
         if self.is_keyword(~"mod") {
             must_be_named_mod = true;
@@ -3096,9 +3113,18 @@ impl Parser {
 
         // extern mod { ... }
         if items_allowed && self.eat(token::LBRACE) {
+            let abi;
+            match move abi_opt {
+                Some(move found_abi) => abi = move found_abi,
+                None => abi = special_idents::c_abi,
+            }
+
             let extra_attrs = self.parse_inner_attrs_and_next();
-            let m = self.parse_foreign_mod_items(sort, extra_attrs.next);
+            let m = self.parse_foreign_mod_items(sort,
+                                                 move abi,
+                                                 extra_attrs.next);
             self.expect(token::RBRACE);
+
             return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
                                           item_foreign_mod(m), visibility,
                                           maybe_append(attrs,
@@ -3106,6 +3132,14 @@ impl Parser {
                                                             inner))));
         }
 
+        match abi_opt {
+            None => {}  // OK.
+            Some(_) => {
+                self.span_err(copy self.span, ~"an ABI may not be specified \
+                                                here");
+            }
+        }
+
         // extern mod foo;
         let metadata = self.parse_optional_meta();
         self.expect(token::SEMI);
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 2e59d2fa45f..7b15f00d761 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -322,6 +322,7 @@ mod special_idents {
     const intrinsic : ident = ident { repr: 32u };
     const clownshoes_foreign_mod: ident = ident { repr: 33 };
     const unnamed_field: ident = ident { repr: 34 };
+    const c_abi: ident = ident { repr: 35 };
 }
 
 struct ident_interner {
@@ -368,7 +369,8 @@ fn mk_ident_interner() -> @ident_interner {
                     @~"str", @~"TyVisitor", @~"arg", @~"descrim",
                     @~"__rust_abi", @~"__rust_stack_shim", @~"TyDesc",
                     @~"dtor", @~"main", @~"<opaque>", @~"blk", @~"static",
-                    @~"intrinsic", @~"__foreign_mod__"
+                    @~"intrinsic", @~"__foreign_mod__", @~"__field__",
+                    @~"C"
                 ];
 
                 let rv = @ident_interner {