rustc: Encode reexports in the metadata and don't have each_path search tag_paths
This commit is contained in:
parent
7bae3449ce
commit
578b7266f2
@ -176,6 +176,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
|
||||
|
||||
let { def_map: def_map,
|
||||
exp_map: exp_map,
|
||||
exp_map2: exp_map2,
|
||||
impl_map: impl_map,
|
||||
trait_map: trait_map } =
|
||||
time(time_passes, ~"resolution", ||
|
||||
@ -238,7 +239,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
|
||||
|
||||
let (llmod, link_meta) = time(time_passes, ~"translation", ||
|
||||
trans::base::trans_crate(sess, crate, ty_cx, outputs.obj_filename,
|
||||
exp_map, maps));
|
||||
exp_map, exp_map2, maps));
|
||||
|
||||
time(time_passes, ~"LLVM passes", ||
|
||||
link::write::run_passes(sess, llmod, outputs.obj_filename));
|
||||
|
@ -5,6 +5,8 @@
|
||||
mod middle {
|
||||
import ty = middle_::ty;
|
||||
export ty;
|
||||
import resolve3 = middle_::resolve3;
|
||||
export resolve3;
|
||||
}
|
||||
|
||||
mod front {
|
||||
|
@ -100,6 +100,12 @@ impl items contain tag_item_impl_method elements, and classes
|
||||
const tag_item_trait_method_self_ty: uint = 0x4b;
|
||||
const tag_item_trait_method_self_ty_region: uint = 0x4c;
|
||||
|
||||
// Reexports are found within module tags. Each reexport contains def_ids
|
||||
// and names.
|
||||
const tag_items_data_item_reexport: uint = 0x4d;
|
||||
const tag_items_data_item_reexport_def_id: uint = 0x4e;
|
||||
const tag_items_data_item_reexport_name: uint = 0x4f;
|
||||
|
||||
// used to encode crate_ctxt side tables
|
||||
enum astencode_tag { // Reserves 0x50 -- 0x6f
|
||||
tag_ast = 0x50,
|
||||
@ -115,15 +121,15 @@ enum astencode_tag { // Reserves 0x50 -- 0x6f
|
||||
tag_table_node_type = 0x57,
|
||||
tag_table_node_type_subst = 0x58,
|
||||
tag_table_freevars = 0x59,
|
||||
tag_table_tcache,
|
||||
tag_table_param_bounds,
|
||||
tag_table_inferred_modes,
|
||||
tag_table_mutbl,
|
||||
tag_table_last_use,
|
||||
tag_table_spill,
|
||||
tag_table_method_map,
|
||||
tag_table_vtable_map,
|
||||
tag_table_borrowings
|
||||
tag_table_tcache = 0x5a,
|
||||
tag_table_param_bounds = 0x5b,
|
||||
tag_table_inferred_modes = 0x5c,
|
||||
tag_table_mutbl = 0x5d,
|
||||
tag_table_last_use = 0x5e,
|
||||
tag_table_spill = 0x5f,
|
||||
tag_table_method_map = 0x60,
|
||||
tag_table_vtable_map = 0x61,
|
||||
tag_table_borrowings = 0x62
|
||||
}
|
||||
|
||||
// djb's cdb hashes.
|
||||
|
@ -127,6 +127,14 @@ fn item_def_id(d: ebml::doc, cdata: cmd) -> ast::def_id {
|
||||
|d| parse_def_id(d)));
|
||||
}
|
||||
|
||||
fn each_reexport(d: ebml::doc, f: fn(ebml::doc) -> bool) {
|
||||
for ebml::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| {
|
||||
if !f(reexport_doc) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn field_mutability(d: ebml::doc) -> ast::class_mutability {
|
||||
// Use maybe_get_doc in case it's a method
|
||||
option::map_default(
|
||||
@ -426,22 +434,67 @@ fn each_path(cdata: cmd, f: fn(path_entry) -> bool) {
|
||||
// First, go through all the explicit items.
|
||||
for ebml::tagged_docs(items_data, tag_items_data_item) |item_doc| {
|
||||
if !broken {
|
||||
let name = ast_map::path_to_str_with_sep(item_path(item_doc),
|
||||
let path = ast_map::path_to_str_with_sep(item_path(item_doc),
|
||||
~"::");
|
||||
if name != ~"" {
|
||||
if path != ~"" {
|
||||
// Extract the def ID.
|
||||
let def_id = item_def_id(item_doc, cdata);
|
||||
|
||||
// Construct the def for this item.
|
||||
debug!{"(each_path) yielding explicit item: %s", name};
|
||||
debug!{"(each_path) yielding explicit item: %s", path};
|
||||
let def_like = item_to_def_like(item_doc, def_id, cdata.cnum);
|
||||
|
||||
// Hand the information off to the iteratee.
|
||||
let this_path_entry = path_entry(name, def_like);
|
||||
let this_path_entry = path_entry(path, def_like);
|
||||
if !f(this_path_entry) {
|
||||
broken = true; // XXX: This is awful.
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a module, find the reexports.
|
||||
for each_reexport(item_doc) |reexport_doc| {
|
||||
if !broken {
|
||||
let def_id_doc =
|
||||
ebml::get_doc(reexport_doc,
|
||||
tag_items_data_item_reexport_def_id);
|
||||
let def_id =
|
||||
ebml::with_doc_data(def_id_doc, |d| parse_def_id(d));
|
||||
let def_id = translate_def_id(cdata, def_id);
|
||||
|
||||
let reexport_name_doc =
|
||||
ebml::get_doc(reexport_doc,
|
||||
tag_items_data_item_reexport_name);
|
||||
let reexport_name = ebml::doc_as_str(reexport_name_doc);
|
||||
|
||||
let reexport_path;
|
||||
if path == ~"" {
|
||||
reexport_path = reexport_name;
|
||||
} else {
|
||||
reexport_path = path + ~"::" + reexport_name;
|
||||
}
|
||||
|
||||
// Get the item.
|
||||
match maybe_find_item(def_id.node, items) {
|
||||
none => {}
|
||||
some(item_doc) => {
|
||||
// Construct the def for this item.
|
||||
let def_like = item_to_def_like(item_doc,
|
||||
def_id,
|
||||
cdata.cnum);
|
||||
|
||||
// Hand the information off to the iteratee.
|
||||
debug!("(each_path) yielding reexported \
|
||||
item: %s", reexport_path);
|
||||
|
||||
let this_path_entry =
|
||||
path_entry(reexport_path, def_like);
|
||||
if (!f(this_path_entry)) {
|
||||
broken = true; // XXX: This is awful.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,54 +502,6 @@ fn each_path(cdata: cmd, f: fn(path_entry) -> bool) {
|
||||
if broken {
|
||||
return;
|
||||
}
|
||||
|
||||
// Next, go through all the paths. We will find items that we didn't know
|
||||
// about before (reexports in particular).
|
||||
//
|
||||
// XXX: This is broken; the paths are actually hierarchical.
|
||||
|
||||
let outer_paths = ebml::get_doc(root, tag_paths);
|
||||
let inner_paths = ebml::get_doc(outer_paths, tag_paths);
|
||||
|
||||
fn g(cdata: cmd, items: ebml::doc, path_doc: ebml::doc, &broken: bool,
|
||||
f: fn(path_entry) -> bool) {
|
||||
|
||||
if !broken {
|
||||
let path = item_name(path_doc);
|
||||
|
||||
// Extract the def ID.
|
||||
let def_id = item_def_id(path_doc, cdata);
|
||||
|
||||
// Get the item.
|
||||
match maybe_find_item(def_id.node, items) {
|
||||
none => {
|
||||
debug!{"(each_path) ignoring implicit item: %s",
|
||||
*path};
|
||||
}
|
||||
some(item_doc) => {
|
||||
// Construct the def for this item.
|
||||
let def_like = item_to_def_like(item_doc, def_id,
|
||||
cdata.cnum);
|
||||
|
||||
// Hand the information off to the iteratee.
|
||||
debug!{"(each_path) yielding implicit item: %s",
|
||||
*path};
|
||||
let this_path_entry = path_entry(*path, def_like);
|
||||
if (!f(this_path_entry)) {
|
||||
broken = true; // XXX: This is awful.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ebml::tagged_docs(inner_paths, tag_paths_data_item) |path_doc| {
|
||||
g(cdata, items, path_doc, broken, f);
|
||||
}
|
||||
|
||||
for ebml::tagged_docs(inner_paths, tag_paths_foreign_path) |path_doc| {
|
||||
g(cdata, items, path_doc, broken, f);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_item_path(cdata: cmd, id: ast::node_id) -> ast_map::path {
|
||||
|
@ -13,6 +13,7 @@
|
||||
import common::*;
|
||||
import middle::ty;
|
||||
import middle::ty::node_id_to_type;
|
||||
import middle::resolve3;
|
||||
import syntax::ast_map;
|
||||
import syntax::attr;
|
||||
import std::serialization::serializer;
|
||||
@ -44,6 +45,7 @@
|
||||
tcx: ty::ctxt,
|
||||
reachable: hashmap<ast::node_id, ()>,
|
||||
reexports: ~[(~str, def_id)],
|
||||
reexports2: middle::resolve3::ExportMap2,
|
||||
impl_map: fn@(ast::node_id) -> ~[(ident, def_id)],
|
||||
item_symbols: hashmap<ast::node_id, ~str>,
|
||||
discrim_symbols: hashmap<ast::node_id, ~str>,
|
||||
@ -57,6 +59,7 @@ enum encode_ctxt = {
|
||||
tcx: ty::ctxt,
|
||||
reachable: hashmap<ast::node_id, ()>,
|
||||
reexports: ~[(~str, def_id)],
|
||||
reexports2: middle::resolve3::ExportMap2,
|
||||
impl_map: fn@(ast::node_id) -> ~[(ident, def_id)],
|
||||
item_symbols: hashmap<ast::node_id, ~str>,
|
||||
discrim_symbols: hashmap<ast::node_id, ~str>,
|
||||
@ -278,7 +281,7 @@ fn encode_trait_ref(ebml_w: ebml::writer, ecx: @encode_ctxt, t: @trait_ref) {
|
||||
}
|
||||
|
||||
fn encode_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, crate: @crate)
|
||||
-> ~[entry<~str>] {
|
||||
-> ~[entry<~str>] {
|
||||
let mut index: ~[entry<~str>] = ~[];
|
||||
let mut path: ~[ident] = ~[];
|
||||
ebml_w.start_tag(tag_paths);
|
||||
@ -478,6 +481,31 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
|
||||
} // for
|
||||
|
||||
encode_path(ebml_w, path, ast_map::path_mod(name));
|
||||
|
||||
// Encode the reexports of this module.
|
||||
debug!("(encoding info for module) encoding reexports for %d", id);
|
||||
match ecx.reexports2.find(id) {
|
||||
some(exports) => {
|
||||
debug!("(encoding info for module) found reexports for %d", id);
|
||||
for exports.each |exp| {
|
||||
debug!("(encoding info for module) reexport '%s' for %d",
|
||||
exp.name, id);
|
||||
ebml_w.start_tag(tag_items_data_item_reexport);
|
||||
ebml_w.start_tag(tag_items_data_item_reexport_def_id);
|
||||
ebml_w.wr_str(def_to_str(exp.def_id));
|
||||
ebml_w.end_tag();
|
||||
ebml_w.start_tag(tag_items_data_item_reexport_name);
|
||||
ebml_w.wr_str(exp.name);
|
||||
ebml_w.end_tag();
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
}
|
||||
none => {
|
||||
debug!("(encoding info for module) found no reexports for %d",
|
||||
id);
|
||||
}
|
||||
}
|
||||
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
@ -1228,6 +1256,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
|
||||
tcx: parms.tcx,
|
||||
reachable: parms.reachable,
|
||||
reexports: parms.reexports,
|
||||
reexports2: parms.reexports2,
|
||||
impl_map: parms.impl_map,
|
||||
item_symbols: parms.item_symbols,
|
||||
discrim_symbols: parms.discrim_symbols,
|
||||
|
@ -96,6 +96,16 @@ struct binding_info {
|
||||
type Export = { reexp: bool, id: def_id };
|
||||
type ExportMap = hashmap<node_id, ~[Export]>;
|
||||
|
||||
// This is the replacement export map. It maps a module to all of the exports
|
||||
// within.
|
||||
type ExportMap2 = hashmap<node_id, ~[Export2]>;
|
||||
|
||||
struct Export2 {
|
||||
name: ~str; // The name of the target.
|
||||
def_id: def_id; // The definition of the target.
|
||||
reexport: bool; // Whether this is a reexport.
|
||||
}
|
||||
|
||||
enum PatternBindingMode {
|
||||
RefutableMode,
|
||||
IrrefutableMode
|
||||
@ -701,6 +711,7 @@ struct Resolver {
|
||||
let def_map: DefMap;
|
||||
let impl_map: ImplMap;
|
||||
let export_map: ExportMap;
|
||||
let export_map2: ExportMap2;
|
||||
let trait_map: TraitMap;
|
||||
|
||||
new(session: session, lang_items: LanguageItems, crate: @crate) {
|
||||
@ -741,6 +752,7 @@ struct Resolver {
|
||||
self.def_map = int_hash();
|
||||
self.impl_map = int_hash();
|
||||
self.export_map = int_hash();
|
||||
self.export_map2 = int_hash();
|
||||
self.trait_map = @int_hash();
|
||||
}
|
||||
|
||||
@ -2734,6 +2746,7 @@ fn record_exports_for_module_subtree(module_: @Module) {
|
||||
}
|
||||
|
||||
fn record_exports_for_module(module_: @Module) {
|
||||
let mut exports2 = ~[];
|
||||
for module_.exported_names.each |name, node_id| {
|
||||
let mut exports = ~[];
|
||||
for self.namespaces.each |namespace| {
|
||||
@ -2752,22 +2765,49 @@ fn record_exports_for_module(module_: @Module) {
|
||||
// Nothing to do.
|
||||
}
|
||||
ChildNameDefinition(target_def) => {
|
||||
debug!("(computing exports) found child export '%s' \
|
||||
for %?",
|
||||
*self.atom_table.atom_to_str(name),
|
||||
module_.def_id);
|
||||
vec::push(exports, {
|
||||
reexp: false,
|
||||
id: def_id_of_def(target_def)
|
||||
});
|
||||
vec::push(exports2, Export2 {
|
||||
reexport: false,
|
||||
name: copy *self.atom_table.atom_to_str(name),
|
||||
def_id: def_id_of_def(target_def)
|
||||
});
|
||||
}
|
||||
ImportNameDefinition(target_def) => {
|
||||
debug!("(computing exports) found reexport '%s' for \
|
||||
%?",
|
||||
*self.atom_table.atom_to_str(name),
|
||||
module_.def_id);
|
||||
vec::push(exports, {
|
||||
reexp: true,
|
||||
id: def_id_of_def(target_def)
|
||||
});
|
||||
vec::push(exports2, Export2 {
|
||||
reexport: true,
|
||||
name: copy *self.atom_table.atom_to_str(name),
|
||||
def_id: def_id_of_def(target_def)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.export_map.insert(node_id, exports);
|
||||
}
|
||||
|
||||
match copy module_.def_id {
|
||||
some(def_id) => {
|
||||
self.export_map2.insert(def_id.node, move exports2);
|
||||
debug!("(computing exports) writing exports for %d (some)",
|
||||
def_id.node);
|
||||
}
|
||||
none => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation scope creation
|
||||
@ -4846,6 +4886,7 @@ fn dump_impl_scopes(impl_scopes: ImplScopes) {
|
||||
fn resolve_crate(session: session, lang_items: LanguageItems, crate: @crate)
|
||||
-> { def_map: DefMap,
|
||||
exp_map: ExportMap,
|
||||
exp_map2: ExportMap2,
|
||||
impl_map: ImplMap,
|
||||
trait_map: TraitMap } {
|
||||
|
||||
@ -4854,6 +4895,7 @@ fn resolve_crate(session: session, lang_items: LanguageItems, crate: @crate)
|
||||
return {
|
||||
def_map: resolver.def_map,
|
||||
exp_map: resolver.export_map,
|
||||
exp_map2: resolver.export_map2,
|
||||
impl_map: resolver.impl_map,
|
||||
trait_map: resolver.trait_map
|
||||
};
|
||||
|
@ -5648,6 +5648,7 @@ fn crate_ctxt_to_encode_parms(cx: @crate_ctxt)
|
||||
tcx: cx.tcx,
|
||||
reachable: cx.reachable,
|
||||
reexports: reexports(cx),
|
||||
reexports2: cx.exp_map2,
|
||||
impl_map: |a| impl_map(cx, a),
|
||||
item_symbols: cx.item_symbols,
|
||||
discrim_symbols: cx.discrim_symbols,
|
||||
@ -5662,9 +5663,10 @@ fn reexports(cx: @crate_ctxt) -> ~[(~str, ast::def_id)] {
|
||||
for defs.each |def| {
|
||||
if !def.reexp { again; }
|
||||
let path = match check cx.tcx.items.get(exp_id) {
|
||||
ast_map::node_export(_, path) => {
|
||||
ast_map::path_to_str(*path)
|
||||
}
|
||||
ast_map::node_export(_, path) => {
|
||||
|
||||
ast_map::path_to_str(*path)
|
||||
}
|
||||
};
|
||||
vec::push(reexports, (path, def.id));
|
||||
}
|
||||
@ -5711,10 +5713,15 @@ fn write_abi_version(ccx: @crate_ctxt) {
|
||||
false);
|
||||
}
|
||||
|
||||
fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
|
||||
output: ~str, emap: resolve3::ExportMap,
|
||||
fn trans_crate(sess: session::session,
|
||||
crate: @ast::crate,
|
||||
tcx: ty::ctxt,
|
||||
output: ~str,
|
||||
emap: resolve3::ExportMap,
|
||||
emap2: resolve3::ExportMap2,
|
||||
maps: astencode::maps)
|
||||
-> (ModuleRef, link_meta) {
|
||||
-> (ModuleRef, link_meta) {
|
||||
|
||||
let symbol_hasher = @hash::default_state();
|
||||
let link_meta =
|
||||
link::build_link_meta(sess, *crate, output, symbol_hasher);
|
||||
@ -5773,6 +5780,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
|
||||
intrinsics: intrinsics,
|
||||
item_vals: int_hash::<ValueRef>(),
|
||||
exp_map: emap,
|
||||
exp_map2: emap2,
|
||||
reachable: reachable,
|
||||
item_symbols: int_hash::<~str>(),
|
||||
mut main_fn: none::<ValueRef>,
|
||||
|
@ -88,6 +88,7 @@ struct BuilderRef_res {
|
||||
intrinsics: hashmap<~str, ValueRef>,
|
||||
item_vals: hashmap<ast::node_id, ValueRef>,
|
||||
exp_map: resolve3::ExportMap,
|
||||
exp_map2: resolve3::ExportMap2,
|
||||
reachable: reachable::map,
|
||||
item_symbols: hashmap<ast::node_id, ~str>,
|
||||
mut main_fn: option<ValueRef>,
|
||||
|
Loading…
Reference in New Issue
Block a user