Use version and hash in crate_map name

Related issue #2137
This commit is contained in:
Haitao Li 2012-04-06 18:45:49 +08:00
parent 13686b6778
commit 2f42b14b4f
5 changed files with 57 additions and 6 deletions

View file

@ -3,7 +3,7 @@
import std::map;
import std::map::hashmap;
import syntax::ast;
import syntax::{ast, attr};
import util::common::*;
export cstore::{};
@ -12,6 +12,8 @@ export crate_metadata;
export mk_cstore;
export get_crate_data;
export set_crate_data;
export get_crate_hash;
export get_crate_vers;
export have_crate_data;
export iter_crate_data;
export add_used_crate_file;
@ -79,6 +81,18 @@ fn get_crate_data(cstore: cstore, cnum: ast::crate_num) -> crate_metadata {
ret p(cstore).metas.get(cnum);
}
fn get_crate_hash(cstore: cstore, cnum: ast::crate_num) -> str {
let cdata = get_crate_data(cstore, cnum);
ret decoder::get_crate_hash(cdata.data);
}
fn get_crate_vers(cstore: cstore, cnum: ast::crate_num) -> str {
let cdata = get_crate_data(cstore, cnum);
let attrs = decoder::get_crate_attributes(cdata.data);
ret option::get(attr::meta_item_value_from_list(
attr::find_linkage_metas(attrs), "vers"));
}
fn set_crate_data(cstore: cstore, cnum: ast::crate_num,
data: crate_metadata) {
p(cstore).metas.insert(cnum, data);

View file

@ -4748,14 +4748,16 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
}
fn decl_crate_map(sess: session::session, mapname: str,
fn decl_crate_map(sess: session::session, mapmeta: link::link_meta,
llmod: ModuleRef) -> ValueRef {
let targ_cfg = sess.targ_cfg;
let int_type = T_int(targ_cfg);
let mut n_subcrates = 1;
let cstore = sess.cstore;
while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; }
let mapname = if sess.building_library { mapname } else { "toplevel" };
let mapname = if sess.building_library {
mapmeta.name + "_" + mapmeta.vers + "_" + mapmeta.extras_hash
} else { "toplevel" };
let sym_name = "_rust_crate_map_" + mapname;
let arrtype = T_array(int_type, n_subcrates as uint);
let maptype = T_struct([int_type, arrtype]);
@ -4766,13 +4768,15 @@ fn decl_crate_map(sess: session::session, mapname: str,
ret map;
}
// FIXME use hashed metadata instead of crate names once we have that
fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
let mut subcrates: [ValueRef] = [];
let mut i = 1;
let cstore = ccx.sess.cstore;
while cstore::have_crate_data(cstore, i) {
let nm = "_rust_crate_map_" + cstore::get_crate_data(cstore, i).name;
let cdata = cstore::get_crate_data(cstore, i);
let nm = "_rust_crate_map_" + cdata.name +
"_" + cstore::get_crate_vers(cstore, i) +
"_" + cstore::get_crate_hash(cstore, i);
let cr = str::as_c_str(nm, {|buf|
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
});
@ -4857,7 +4861,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
lib::llvm::associate_type(tn, "taskptr", taskptr_type);
let tydesc_type = T_tydesc(targ_cfg);
lib::llvm::associate_type(tn, "tydesc", tydesc_type);
let crate_map = decl_crate_map(sess, link_meta.name, llmod);
let crate_map = decl_crate_map(sess, link_meta, llmod);
let dbg_cx = if sess.opts.debuginfo {
option::some(debuginfo::mk_ctxt(llmod_id))
} else {

View file

@ -0,0 +1,6 @@
#[link(name = "crateresolve3",
vers = "0.1")];
#[crate_type = "lib"];
fn f() -> int { 10 }

View file

@ -0,0 +1,6 @@
#[link(name = "crateresolve3",
vers = "0.2")];
#[crate_type = "lib"];
fn g() -> int { 20 }

View file

@ -0,0 +1,21 @@
// xfail-fast
// aux-build:crateresolve3-1.rs
// aux-build:crateresolve3-2.rs
// verify able to link with crates with same name but different versions
// as long as no name collision on invoked functions.
mod a {
use crateresolve3(vers = "0.1");
fn f() { assert crateresolve3::f() == 10; }
}
mod b {
use crateresolve3(vers = "0.2");
fn f() { assert crateresolve3::g() == 20; }
}
fn main() {
a::f();
b::f();
}