librustc: Parse extern "C" { ... }. r=brson

This commit is contained in:
Patrick Walton 2012-11-27 17:25:55 -08:00
parent d2d6d955f4
commit 61cfec3c52
7 changed files with 54 additions and 8 deletions

View File

@ -75,6 +75,7 @@ fn fold_foreign_mod(cx: ctxt, nm: ast::foreign_mod,
|a| filter_view_item(cx, *a));
return {
sort: nm.sort,
abi: nm.abi,
view_items: vec::map(filtered_view_items, |x| fld.fold_view_item(*x)),
items: filtered_items
};

View File

@ -1861,6 +1861,7 @@ impl foreign_abi : cmp::Eq {
#[auto_deserialize]
type foreign_mod =
{sort: foreign_mod_sort,
abi: ident,
view_items: ~[@view_item],
items: ~[@foreign_item]};

View File

@ -546,8 +546,9 @@ fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod {
fn noop_fold_foreign_mod(nm: foreign_mod, fld: ast_fold) -> foreign_mod {
return {sort: nm.sort,
view_items: vec::map(nm.view_items, |x| fld.fold_view_item(*x)),
items: vec::map(nm.items, |x| fld.fold_foreign_item(*x))}
abi: nm.abi,
view_items: vec::map(nm.view_items, |x| fld.fold_view_item(*x)),
items: vec::map(nm.items, |x| fld.fold_foreign_item(*x))}
}
fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {

View File

@ -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);

View File

@ -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 {

View File

@ -485,6 +485,7 @@ fn print_item(s: ps, &&item: @ast::item) {
}
ast::item_foreign_mod(nmod) => {
head(s, visibility_qualified(item.vis, ~"extern"));
print_string(s, *s.intr.get(nmod.abi));
match nmod.sort {
ast::named => {
word_nbsp(s, ~"mod");

View File

@ -0,0 +1,6 @@
extern "C" {
fn pow(x: f64, y: f64) -> f64;
}
fn main() {}