aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2011-04-01 13:02:44 -0700
committerPatrick Walton <[email protected]>2011-04-01 13:02:44 -0700
commit6dc452335a410e139220c4ecadbbda9dd15fe8e2 (patch)
tree96d3fe1107c175f3792eb960cf3d9b9cc87731b7 /src
parentrustc: Have tag_variants() return a new variant_info structure instead of an ... (diff)
downloadrust-6dc452335a410e139220c4ecadbbda9dd15fe8e2.tar.xz
rust-6dc452335a410e139220c4ecadbbda9dd15fe8e2.zip
rustc: Get tag variants from the crate metadata
Diffstat (limited to 'src')
-rw-r--r--src/comp/front/creader.rs55
-rw-r--r--src/comp/middle/metadata.rs33
-rw-r--r--src/comp/middle/trans.rs5
-rw-r--r--src/comp/rustc.rc1
4 files changed, 78 insertions, 16 deletions
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs
index 22c38c31..151411c6 100644
--- a/src/comp/front/creader.rs
+++ b/src/comp/front/creader.rs
@@ -8,6 +8,7 @@ import lib.llvm.mk_object_file;
import lib.llvm.mk_section_iter;
import middle.fold;
import middle.metadata;
+import middle.trans;
import middle.ty;
import back.x86;
import util.common;
@@ -324,7 +325,8 @@ impure fn move_to_item(&ebml.reader ebml_r, int item_id) {
auto eqer = bind eq_item(_, item_id);
auto hash = metadata.hash_def_num(item_id);
ebml.move_to_sibling_with_id(ebml_r, metadata.tag_items);
- lookup_hash_entry(ebml_r, eqer, hash);
+ auto found = lookup_hash_entry(ebml_r, eqer, hash);
+ check (found);
}
// Looks up an item in the given metadata and returns an EBML reader pointing
@@ -409,17 +411,17 @@ impure fn get_item_type(&ebml.reader ebml_r, int this_cnum) -> @ty.t {
ret get_item_generic[@ty.t](ebml_r, metadata.tag_items_data_item_type, f);
}
-impure fn get_item_ty_params(&ebml.reader ebml_r, int this_cnum)
+impure fn collect_def_ids(&ebml.reader ebml_r, int this_cnum, uint tag_id)
-> vec[ast.def_id] {
- let vec[ast.def_id] tps = vec();
+ let vec[ast.def_id] def_ids = vec();
while (ebml.bytes_left(ebml_r) > 0u) {
auto ebml_tag = ebml.peek(ebml_r);
- if (ebml_tag.id == metadata.tag_items_data_item_ty_param) {
+ if (ebml_tag.id == tag_id) {
ebml.move_to_first_child(ebml_r);
auto data = ebml.read_data(ebml_r);
auto external_def_id = parse_def_id(data);
- tps += vec(tup(this_cnum, external_def_id._1));
+ def_ids += vec(tup(this_cnum, external_def_id._1));
ebml.move_to_parent(ebml_r);
}
@@ -430,7 +432,19 @@ impure fn get_item_ty_params(&ebml.reader ebml_r, int this_cnum)
ebml.move_to_parent(ebml_r);
ebml.move_to_first_child(ebml_r);
- ret tps;
+ ret def_ids;
+}
+
+impure fn get_item_ty_params(&ebml.reader ebml_r, int this_cnum)
+ -> vec[ast.def_id] {
+ ret collect_def_ids(ebml_r, this_cnum,
+ metadata.tag_items_data_item_ty_param);
+}
+
+impure fn collect_tag_variant_ids(&ebml.reader ebml_r, int this_cnum)
+ -> vec[ast.def_id] {
+ ret collect_def_ids(ebml_r, this_cnum,
+ metadata.tag_items_data_item_variant);
}
@@ -590,6 +604,35 @@ fn get_symbol(session.session sess, ast.def_id def) -> str {
ret get_item_symbol(ebml_r);
}
+fn get_tag_variants(session.session sess, ast.def_id def)
+ -> vec[trans.variant_info] {
+ auto external_crate_id = def._0;
+ auto data = sess.get_external_crate(external_crate_id);
+ auto ebml_r = lookup_item(def._1, data);
+
+ let vec[trans.variant_info] infos = vec();
+ auto variant_ids = collect_tag_variant_ids(ebml_r, external_crate_id);
+ for (ast.def_id did in variant_ids) {
+ ebml.reset_reader(ebml_r, 0u);
+ move_to_item(ebml_r, did._1);
+ auto ctor_ty = get_item_type(ebml_r, external_crate_id);
+ let vec[@ty.t] arg_tys = vec();
+ alt (ctor_ty.struct) {
+ case (ty.ty_fn(_, ?args, _)) {
+ for (ty.arg a in args) {
+ arg_tys += vec(a.ty);
+ }
+ }
+ case (_) {
+ // Nullary tag variant.
+ }
+ }
+ infos += vec(rec(args=arg_tys, ctor_ty=ctor_ty, id=did));
+ }
+
+ ret infos;
+}
+
// Local Variables:
// mode: rust
// fill-column: 78;
diff --git a/src/comp/middle/metadata.rs b/src/comp/middle/metadata.rs
index c42ed6db..587db223 100644
--- a/src/comp/middle/metadata.rs
+++ b/src/comp/middle/metadata.rs
@@ -176,8 +176,12 @@ fn encode_def_id(&ebml.writer ebml_w, &ast.def_id id) {
ebml.end_tag(ebml_w);
}
-fn encode_tag_variant_paths(&ebml.writer ebml_w, vec[ast.variant] variants) {
+fn encode_tag_variant_paths(&ebml.writer ebml_w,
+ vec[ast.variant] variants,
+ vec[str] path,
+ &mutable vec[tup(str, uint)] index) {
for (ast.variant variant in variants) {
+ add_to_index(ebml_w, path, index, variant.node.name);
ebml.start_tag(ebml_w, tag_paths_data_item);
encode_name(ebml_w, variant.node.name);
encode_def_id(ebml_w, variant.node.id);
@@ -266,9 +270,10 @@ fn encode_module_item_paths(&ebml.writer ebml_w,
add_to_index(ebml_w, path, index, id);
ebml.start_tag(ebml_w, tag_paths_data_item);
encode_name(ebml_w, id);
- encode_tag_variant_paths(ebml_w, variants);
encode_def_id(ebml_w, did);
ebml.end_tag(ebml_w);
+
+ encode_tag_variant_paths(ebml_w, variants, path, index);
}
case (ast.item_obj(?id, _, ?tps, ?odid, ?ann)) {
add_to_index(ebml_w, path, index, id);
@@ -314,6 +319,12 @@ fn encode_type_params(&ebml.writer ebml_w, vec[ast.ty_param] tps) {
}
}
+fn encode_variant_id(&ebml.writer ebml_w, ast.def_id vid) {
+ ebml.start_tag(ebml_w, tag_items_data_item_variant);
+ ebml_w.writer.write(_str.bytes(def_to_str(vid)));
+ ebml.end_tag(ebml_w);
+}
+
fn encode_type(&ebml.writer ebml_w, @ty.t typ) {
ebml.start_tag(ebml_w, tag_items_data_item_type);
auto f = def_to_str;
@@ -348,23 +359,24 @@ fn encode_obj_type_id(&ebml.writer ebml_w, &ast.def_id id) {
fn encode_tag_variant_info(@trans.crate_ctxt cx, &ebml.writer ebml_w,
- ast.def_id did, vec[ast.variant] variants) {
+ ast.def_id did, vec[ast.variant] variants,
+ &mutable vec[tup(int, uint)] index) {
for (ast.variant variant in variants) {
+ index += vec(tup(variant.node.id._1, ebml_w.writer.tell()));
+
ebml.start_tag(ebml_w, tag_items_data_item);
encode_def_id(ebml_w, variant.node.id);
encode_kind(ebml_w, 'v' as u8);
encode_tag_id(ebml_w, did);
encode_type(ebml_w, trans.node_ann_type(cx, variant.node.ann));
- if (_vec.len[ast.variant_arg](variant.node.args) > 0u) {
- encode_symbol(cx, ebml_w, variant.node.id);
- }
+ encode_symbol(cx, ebml_w, variant.node.id);
encode_discriminant(cx, ebml_w, variant.node.id);
ebml.end_tag(ebml_w);
}
}
fn encode_info_for_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
- @ast.item item) {
+ @ast.item item, &mutable vec[tup(int, uint)] index) {
alt (item.node) {
case (ast.item_const(_, _, _, ?did, ?ann)) {
ebml.start_tag(ebml_w, tag_items_data_item);
@@ -409,9 +421,12 @@ fn encode_info_for_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
encode_kind(ebml_w, 't' as u8);
encode_type_params(ebml_w, tps);
encode_type(ebml_w, trans.node_ann_type(cx, ann));
+ for (ast.variant v in variants) {
+ encode_variant_id(ebml_w, v.node.id);
+ }
ebml.end_tag(ebml_w);
- encode_tag_variant_info(cx, ebml_w, did, variants);
+ encode_tag_variant_info(cx, ebml_w, did, variants, index);
}
case (ast.item_obj(?id, _, ?tps, ?odid, ?ann)) {
ebml.start_tag(ebml_w, tag_items_data_item);
@@ -458,7 +473,7 @@ fn encode_info_for_items(@trans.crate_ctxt cx, &ebml.writer ebml_w)
ebml.start_tag(ebml_w, tag_items_data);
for each (@tup(ast.def_id, @ast.item) kvp in cx.items.items()) {
index += vec(tup(kvp._0._1, ebml_w.writer.tell()));
- encode_info_for_item(cx, ebml_w, kvp._1);
+ encode_info_for_item(cx, ebml_w, kvp._1, index);
}
for each (@tup(ast.def_id, @ast.native_item) kvp in
cx.native_items.items()) {
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 263ac940..7859393e 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -1911,7 +1911,10 @@ type variant_info = rec(vec[@ty.t] args, @ty.t ctor_ty, ast.def_id id);
// Returns information about the variants in a tag.
fn tag_variants(@crate_ctxt cx, ast.def_id id) -> vec[variant_info] {
- // FIXME: This doesn't work for external variants.
+ if (cx.sess.get_targ_crate_num() != id._0) {
+ ret creader.get_tag_variants(cx.sess, id);
+ }
+
check (cx.items.contains_key(id));
alt (cx.items.get(id).node) {
case (ast.item_tag(_, ?variants, _, _, _)) {
diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc
index afa84711..98fae38b 100644
--- a/src/comp/rustc.rc
+++ b/src/comp/rustc.rc
@@ -47,6 +47,7 @@ auth front.creader.load_crate = unsafe;
auth front.creader.lookup_def = impure;
auth front.creader.get_type = impure;
auth front.creader.get_symbol = impure;
+auth front.creader.get_tag_variants = impure;
auth front.creader.impure_no_op = impure;
auth middle.metadata = unsafe;
auth middle.metadata.encode_index = impure;