Skip to content

Commit 8ef4551

Browse files
committed
rustc: Implement foreign constants.
This is needed for a lot of Apple libraries, as Apple tends to put a lot of globals in dynamic libraries.
1 parent bb5c079 commit 8ef4551

File tree

12 files changed

+139
-71
lines changed

12 files changed

+139
-71
lines changed

src/libsyntax/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ type foreign_item =
830830
#[auto_serialize]
831831
enum foreign_item_ {
832832
foreign_item_fn(fn_decl, purity, ~[ty_param]),
833+
foreign_item_const(@ty)
833834
}
834835

835836
// The data we save and restore about an inlined item or method. This is not

src/libsyntax/fold.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ fn noop_fold_foreign_item(&&ni: @foreign_item, fld: ast_fold)
196196
purity,
197197
fold_ty_params(typms, fld))
198198
}
199+
foreign_item_const(t) => {
200+
foreign_item_const(fld.fold_ty(t))
201+
}
199202
},
200203
id: fld.new_id(ni.id),
201204
span: fld.new_span(ni.span)};

src/libsyntax/parse/parser.rs

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,32 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
3232
expr_move, expr_path, expr_rec, expr_repeat, expr_ret, expr_swap,
3333
expr_struct, expr_tup, expr_unary, expr_unary_move, expr_vec,
3434
expr_vstore, expr_while, extern_fn, field, fn_decl, foreign_item,
35-
foreign_item_fn, foreign_mod, ident, impure_fn, infer, inherited,
36-
init_assign, init_move, initializer, item, item_,
37-
item_class, item_const, item_enum, item_fn, item_foreign_mod,
38-
item_impl, item_mac, item_mod, item_trait, item_ty, lit, lit_,
39-
lit_bool, lit_float, lit_int, lit_int_unsuffixed, lit_nil,
40-
lit_str, lit_uint, local, m_const, m_imm, m_mutbl, mac_, mac_aq,
41-
mac_ellipsis, mac_invoc, mac_invoc_tt, mac_var, matcher,
42-
match_nonterminal, match_seq, match_tok, method, mode, mt, mul,
43-
mutability, named_field, neg, noreturn, not, pat, pat_box,
44-
pat_enum, pat_ident, pat_lit, pat_range, pat_rec, pat_struct,
45-
pat_tup, pat_uniq, pat_wild, path, private, proto, proto_bare,
46-
proto_block, proto_box, proto_uniq, provided, public, pure_fn,
47-
purity, re_anon, re_named, region, rem, required, ret_style,
48-
return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
49-
stmt_semi, struct_def, struct_field, struct_variant_kind,
50-
subtract, sty_box, sty_by_ref, sty_region, sty_static, sty_uniq,
51-
sty_value, token_tree, trait_method, trait_ref, tt_delim, tt_seq,
52-
tt_tok, tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn,
53-
ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_param_bound,
54-
ty_path, ty_ptr, ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq,
55-
ty_vec, ty_fixed_length, tuple_variant_kind, unchecked_blk, uniq,
56-
unnamed_field, unsafe_blk, unsafe_fn, variant, view_item,
57-
view_item_, view_item_export, view_item_import, view_item_use,
58-
view_path, view_path_glob, view_path_list, view_path_simple,
59-
visibility, vstore, vstore_box, vstore_fixed, vstore_slice,
60-
vstore_uniq};
35+
foreign_item_const, foreign_item_fn, foreign_mod, ident,
36+
impure_fn, infer, inherited, init_assign, init_move, initializer,
37+
item, item_, item_class, item_const, item_enum, item_fn,
38+
item_foreign_mod, item_impl, item_mac, item_mod, item_trait,
39+
item_ty, lit, lit_, lit_bool, lit_float, lit_int,
40+
lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const,
41+
m_imm, m_mutbl, mac_, mac_aq, mac_ellipsis, mac_invoc,
42+
mac_invoc_tt, mac_var, matcher, match_nonterminal, match_seq,
43+
match_tok, method, mode, mt, mul, mutability, named_field, neg,
44+
noreturn, not, pat, pat_box, pat_enum, pat_ident, pat_lit,
45+
pat_range, pat_rec, pat_struct, pat_tup, pat_uniq, pat_wild,
46+
path, private, proto, proto_bare, proto_block, proto_box,
47+
proto_uniq, provided, public, pure_fn, purity, re_anon, re_named,
48+
region, rem, required, ret_style, return_val, self_ty, shl, shr,
49+
stmt, stmt_decl, stmt_expr, stmt_semi, struct_def, struct_field,
50+
struct_variant_kind, subtract, sty_box, sty_by_ref, sty_region,
51+
sty_static, sty_uniq, sty_value, token_tree, trait_method,
52+
trait_ref, tt_delim, tt_seq, tt_tok, tt_nonterminal, ty, ty_,
53+
ty_bot, ty_box, ty_field, ty_fn, ty_infer, ty_mac, ty_method,
54+
ty_nil, ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec,
55+
ty_rptr, ty_tup, ty_u32, ty_uniq, ty_vec, ty_fixed_length,
56+
tuple_variant_kind, unchecked_blk, uniq, unnamed_field,
57+
unsafe_blk, unsafe_fn, variant, view_item, view_item_,
58+
view_item_export, view_item_import, view_item_use, view_path,
59+
view_path_glob, view_path_list, view_path_simple, visibility,
60+
vstore, vstore_box, vstore_fixed, vstore_slice, vstore_uniq};
6161

6262
export file_type;
6363
export parser;
@@ -2843,6 +2843,21 @@ struct parser {
28432843
span: mk_sp(lo, hi)};
28442844
}
28452845

2846+
fn parse_item_foreign_const(+attrs: ~[attribute]) -> @foreign_item {
2847+
let lo = self.span.lo;
2848+
self.expect_keyword(~"const");
2849+
let ident = self.parse_ident();
2850+
self.expect(token::COLON);
2851+
let ty = self.parse_ty(false);
2852+
let hi = self.span.hi;
2853+
self.expect(token::SEMI);
2854+
return @{ident: ident,
2855+
attrs: attrs,
2856+
node: foreign_item_const(move ty),
2857+
id: self.get_id(),
2858+
span: mk_sp(lo, hi)};
2859+
}
2860+
28462861
fn parse_fn_purity() -> purity {
28472862
if self.eat_keyword(~"fn") { impure_fn }
28482863
else if self.eat_keyword(~"pure") {
@@ -2855,9 +2870,12 @@ struct parser {
28552870
else { self.unexpected(); }
28562871
}
28572872

2858-
fn parse_foreign_item(+attrs: ~[attribute]) ->
2859-
@foreign_item {
2860-
self.parse_item_foreign_fn(attrs)
2873+
fn parse_foreign_item(+attrs: ~[attribute]) -> @foreign_item {
2874+
if self.is_keyword(~"const") {
2875+
self.parse_item_foreign_const(move attrs)
2876+
} else {
2877+
self.parse_item_foreign_fn(move attrs)
2878+
}
28612879
}
28622880

28632881
fn parse_foreign_mod_items(+first_item_attrs: ~[attribute]) ->

src/libsyntax/print/pprust.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,14 @@ fn print_foreign_item(s: ps, item: @ast::foreign_item) {
421421
word(s.s, ~";");
422422
end(s); // end the outer fn box
423423
}
424+
ast::foreign_item_const(t) => {
425+
head(s, ~"const");
426+
print_ident(s, item.ident);
427+
word_space(s, ~":");
428+
print_type(s, t);
429+
word(s.s, ~";");
430+
end(s); // end the head-ibox
431+
}
424432
}
425433
}
426434

src/libsyntax/visit.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ fn visit_foreign_item<E>(ni: @foreign_item, e: E, v: vt<E>) {
254254
v.visit_ty_params(tps, e, v);
255255
visit_fn_decl(fd, e, v);
256256
}
257+
foreign_item_const(t) => {
258+
v.visit_ty(t, e, v);
259+
}
257260
}
258261
}
259262

src/rustc/metadata/encoder.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,14 @@ fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
803803
}
804804
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
805805
}
806+
foreign_item_const(t) => {
807+
encode_def_id(ebml_w, local_def(nitem.id));
808+
encode_family(ebml_w, 'c');
809+
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
810+
encode_symbol(ecx, ebml_w, nitem.id);
811+
encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident));
812+
ebml_w.end_tag();
813+
}
806814
}
807815
ebml_w.end_tag();
808816
}

src/rustc/middle/lint.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
420420
ast::foreign_item_fn(decl, _, tps) => {
421421
check_foreign_fn(cx, it.id, decl);
422422
}
423+
ast::foreign_item_const(*) => {} // XXX: Not implemented.
423424
}
424425
}
425426
}

src/rustc/middle/resolve3.rs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,23 @@ import syntax::ast::{enum_variant_kind, expr, expr_again, expr_assign_op};
2525
import syntax::ast::{expr_binary, expr_break, expr_cast, expr_field, expr_fn};
2626
import syntax::ast::{expr_fn_block, expr_index, expr_loop};
2727
import syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl};
28-
import syntax::ast::{foreign_item, foreign_item_fn, ge, gt, ident, trait_ref};
29-
import syntax::ast::{impure_fn, inherited, item, item_class, item_const};
30-
import syntax::ast::{item_enum, item_fn, item_mac, item_foreign_mod};
31-
import syntax::ast::{item_impl, item_mod, item_trait, item_ty, le, local};
32-
import syntax::ast::{local_crate, lt, method, mul, ne, neg, node_id, pat};
33-
import syntax::ast::{pat_enum, pat_ident, path, prim_ty, pat_box, pat_uniq};
28+
import syntax::ast::{foreign_item, foreign_item_const, foreign_item_fn, ge};
29+
import syntax::ast::{gt, ident, impure_fn, inherited, item, item_class};
30+
import syntax::ast::{item_const, item_enum, item_fn, item_foreign_mod};
31+
import syntax::ast::{item_impl, item_mac, item_mod, item_trait, item_ty, le};
32+
import syntax::ast::{local, local_crate, lt, method, mul, ne, neg, node_id};
33+
import syntax::ast::{pat, pat_enum, pat_ident, path, prim_ty, pat_box};
3434
import syntax::ast::{pat_lit, pat_range, pat_rec, pat_struct, pat_tup};
35-
import syntax::ast::{pat_wild, private, provided, public, required, rem};
36-
import syntax::ast::{self_ty_};
37-
import syntax::ast::{shl, stmt_decl, struct_field, struct_variant_kind};
38-
import syntax::ast::{sty_static, subtract, tuple_variant_kind, ty};
39-
import syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i};
40-
import syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, ty_param};
41-
import syntax::ast::{ty_path, ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8};
42-
import syntax::ast::{ty_uint, variant, view_item, view_item_export};
43-
import syntax::ast::{view_item_import, view_item_use, view_path_glob};
44-
import syntax::ast::{view_path_list, view_path_simple, visibility};
35+
import syntax::ast::{pat_uniq, pat_wild, private, provided, public, required};
36+
import syntax::ast::{rem, self_ty_, shl, stmt_decl, struct_field};
37+
import syntax::ast::{struct_variant_kind, sty_static, subtract, trait_ref};
38+
import syntax::ast::{tuple_variant_kind, ty, ty_bool, ty_char, ty_f, ty_f32};
39+
import syntax::ast::{ty_f64, ty_float, ty_i, ty_i16, ty_i32, ty_i64, ty_i8};
40+
import syntax::ast::{ty_int, ty_param, ty_path, ty_str, ty_u, ty_u16, ty_u32};
41+
import syntax::ast::{ty_u64, ty_u8, ty_uint, variant, view_item};
42+
import syntax::ast::{view_item_export, view_item_import, view_item_use};
43+
import syntax::ast::{view_path_glob, view_path_list, view_path_simple};
44+
import syntax::ast::{visibility};
4545
import syntax::ast_util::{def_id_of_def, dummy_sp, local_def, new_def_hash};
4646
import syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
4747
import syntax::attr::{attr_metas, contains_name};
@@ -1213,26 +1213,27 @@ struct Resolver {
12131213
vt<ReducedGraphParent>) {
12141214

12151215
let name = foreign_item.ident;
1216+
let (name_bindings, new_parent) =
1217+
self.add_child(name, parent, ~[ValueNS], foreign_item.span);
12161218

12171219
match foreign_item.node {
12181220
foreign_item_fn(fn_decl, purity, type_parameters) => {
1219-
let (name_bindings, new_parent) = self.add_child(name, parent,
1220-
~[ValueNS], foreign_item.span);
1221-
12221221
let def = def_fn(local_def(foreign_item.id), purity);
12231222
(*name_bindings).define_value(Public, def, foreign_item.span);
12241223

12251224
do self.with_type_parameter_rib
1226-
(HasTypeParameters(&type_parameters,
1227-
foreign_item.id,
1228-
0u,
1229-
NormalRibKind)) || {
1230-
1225+
(HasTypeParameters(&type_parameters, foreign_item.id,
1226+
0u, NormalRibKind)) {
12311227
visit_foreign_item(foreign_item, new_parent, visitor);
12321228
}
12331229
}
1234-
}
1230+
foreign_item_const(item_type) => {
1231+
let def = def_const(local_def(foreign_item.id));
1232+
(*name_bindings).define_value(Public, def, foreign_item.span);
12351233

1234+
visit_foreign_item(foreign_item, new_parent, visitor);
1235+
}
1236+
}
12361237
}
12371238

12381239
fn build_reduced_graph_for_block(block: blk,
@@ -2953,6 +2954,10 @@ struct Resolver {
29532954
visitor);
29542955
}
29552956
}
2957+
foreign_item_const(item_type) => {
2958+
visit_foreign_item(foreign_item, (),
2959+
visitor);
2960+
}
29562961
}
29572962
}
29582963
}

src/rustc/middle/trans/base.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5414,9 +5414,22 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
54145414
}
54155415
ast_map::node_foreign_item(ni, _, pth) => {
54165416
exprt = true;
5417-
register_fn(ccx, ni.span,
5418-
vec::append(*pth, ~[path_name(ni.ident)]),
5419-
ni.id)
5417+
match ni.node {
5418+
ast::foreign_item_fn(*) => {
5419+
register_fn(ccx, ni.span,
5420+
vec::append(*pth, ~[path_name(ni.ident)]),
5421+
ni.id)
5422+
}
5423+
ast::foreign_item_const(*) => {
5424+
let typ = ty::node_id_to_type(ccx.tcx, ni.id);
5425+
let ident = ccx.sess.parse_sess.interner.get(ni.ident);
5426+
let g = do str::as_c_str(*ident) |buf| {
5427+
llvm::LLVMAddGlobal(ccx.llmod, type_of(ccx, typ), buf)
5428+
};
5429+
ccx.item_symbols.insert(ni.id, copy *ident);
5430+
g
5431+
}
5432+
}
54205433
}
54215434
ast_map::node_ctor(nm, _, ctor, _, pt) => {
54225435
let my_path = vec::append(*pt, ~[path_name(nm)]);

src/rustc/middle/trans/foreign.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
789789
}
790790
}
791791
}
792+
ast::foreign_item_const(*) => {}
792793
}
793794
}
794795
}

src/rustc/middle/typeck/collect.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -537,12 +537,8 @@ fn convert_foreign(ccx: @crate_ctxt, i: @ast::foreign_item) {
537537
// type of the foreign item. We simply write it into the node type
538538
// table.
539539
let tpt = ty_of_foreign_item(ccx, i);
540-
match i.node {
541-
ast::foreign_item_fn(*) => {
542-
write_ty_to_tcx(ccx.tcx, i.id, tpt.ty);
543-
ccx.tcx.tcache.insert(local_def(i.id), tpt);
544-
}
545-
}
540+
write_ty_to_tcx(ccx.tcx, i.id, tpt.ty);
541+
ccx.tcx.tcache.insert(local_def(i.id), tpt);
546542
}
547543

548544
fn ty_of_method(ccx: @crate_ctxt,
@@ -695,6 +691,14 @@ fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
695691
return ty_of_foreign_fn_decl(ccx, fn_decl, purity, params,
696692
local_def(it.id));
697693
}
694+
ast::foreign_item_const(t) => {
695+
let rb = in_binding_rscope(empty_rscope);
696+
return {
697+
bounds: @~[],
698+
region_param: none,
699+
ty: ast_ty_to_ty(ccx, rb, t)
700+
};
701+
}
698702
}
699703
}
700704

src/rustdoc/extract.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,19 @@ fn nmoddoc_from_mod(
130130
itemdoc: doc::itemdoc,
131131
module_: ast::foreign_mod
132132
) -> doc::nmoddoc {
133+
let mut fns = ~[];
134+
for module_.items.each |item| {
135+
let itemdoc = mk_itemdoc(item.id, to_str(item.ident));
136+
match item.node {
137+
ast::foreign_item_fn(*) => {
138+
vec::push(fns, fndoc_from_fn(itemdoc));
139+
}
140+
ast::foreign_item_const(*) => {} // XXX: Not implemented.
141+
}
142+
}
133143
{
134144
item: itemdoc,
135-
fns: do vec::map(module_.items) |item| {
136-
let itemdoc = mk_itemdoc(item.id, to_str(item.ident));
137-
match item.node {
138-
ast::foreign_item_fn(*) => {
139-
fndoc_from_fn(itemdoc)
140-
}
141-
}
142-
},
145+
fns: fns,
143146
index: none
144147
}
145148
}

0 commit comments

Comments
 (0)