rustc: Remove CrateId and all related support
This commit removes all support in the compiler for the #[crate_id] attribute and all of its derivative infrastructure. A list of the functionality removed is: * The #[crate_id] attribute no longer exists * There is no longer the concept of a version of a crate * Version numbers are no longer appended to symbol names * The --crate-id command line option has been removed To migrate forward, rename #[crate_id] to #[crate_name] and only the name of the crate itself should be mentioned. The version/path of the old crate id should be removed. For a transitionary state, the #[crate_id] attribute is still accepted if the #[crate_name] is not present, but it is warned about if it is the only identifier present. RFC: 0035-remove-crate-id [breaking-change]
This commit is contained in:
parent
aaff4e05e1
commit
50ee1ec1b4
24 changed files with 230 additions and 269 deletions
|
@ -19,7 +19,7 @@ use lib::llvm::llvm;
|
||||||
use lib::llvm::ModuleRef;
|
use lib::llvm::ModuleRef;
|
||||||
use lib;
|
use lib;
|
||||||
use metadata::common::LinkMeta;
|
use metadata::common::LinkMeta;
|
||||||
use metadata::{encoder, cstore, filesearch, csearch, loader};
|
use metadata::{encoder, cstore, filesearch, csearch, loader, creader};
|
||||||
use middle::trans::context::CrateContext;
|
use middle::trans::context::CrateContext;
|
||||||
use middle::trans::common::gensym_name;
|
use middle::trans::common::gensym_name;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
|
@ -40,9 +40,8 @@ use syntax::abi;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast_map::{PathElem, PathElems, PathName};
|
use syntax::ast_map::{PathElem, PathElems, PathName};
|
||||||
use syntax::ast_map;
|
use syntax::ast_map;
|
||||||
use syntax::attr;
|
|
||||||
use syntax::attr::AttrMetaMethods;
|
use syntax::attr::AttrMetaMethods;
|
||||||
use syntax::crateid::CrateId;
|
use syntax::codemap::Span;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
|
#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
|
||||||
|
@ -547,18 +546,49 @@ pub mod write {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
|
// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
|
||||||
pub fn find_crate_id(attrs: &[ast::Attribute], out_filestem: &str) -> CrateId {
|
pub fn find_crate_name(sess: Option<&Session>,
|
||||||
match attr::find_crateid(attrs) {
|
attrs: &[ast::Attribute],
|
||||||
None => from_str(out_filestem).unwrap_or_else(|| {
|
out_filestem: &str) -> String {
|
||||||
let mut s = out_filestem.chars().filter(|c| c.is_XID_continue());
|
use syntax::crateid::CrateId;
|
||||||
from_str(s.collect::<String>().as_slice())
|
|
||||||
.or(from_str("rust-out")).unwrap()
|
let validate = |s: String, span: Option<Span>| {
|
||||||
}),
|
creader::validate_crate_name(sess, s.as_slice(), span);
|
||||||
Some(s) => s,
|
s
|
||||||
|
};
|
||||||
|
|
||||||
|
let crate_name = attrs.iter().find(|at| at.check_name("crate_name"))
|
||||||
|
.and_then(|at| at.value_str().map(|s| (at, s)));
|
||||||
|
match crate_name {
|
||||||
|
Some((attr, s)) => return validate(s.get().to_string(), Some(attr.span)),
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
|
let crate_id = attrs.iter().find(|at| at.check_name("crate_id"))
|
||||||
|
.and_then(|at| at.value_str().map(|s| (at, s)))
|
||||||
|
.and_then(|(at, s)| {
|
||||||
|
from_str::<CrateId>(s.get()).map(|id| (at, id))
|
||||||
|
});
|
||||||
|
match crate_id {
|
||||||
|
Some((attr, id)) => {
|
||||||
|
match sess {
|
||||||
|
Some(sess) => {
|
||||||
|
sess.span_warn(attr.span, "the #[crate_id] attribute is \
|
||||||
|
deprecated for the \
|
||||||
|
#[crate_name] attribute");
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
return validate(id.name, Some(attr.span))
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
return validate(from_str(out_filestem).unwrap_or_else(|| {
|
||||||
|
let mut s = out_filestem.chars().filter(|c| c.is_XID_continue());
|
||||||
|
from_str(s.collect::<String>().as_slice())
|
||||||
|
.or(from_str("rust-out")).unwrap()
|
||||||
|
}), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn crate_id_hash(crate_id: &CrateId) -> String {
|
pub fn crate_name_hash(sess: &Session, crate_name: &str) -> String {
|
||||||
// This calculates CMH as defined above. Note that we don't use the path of
|
// This calculates CMH as defined above. Note that we don't use the path of
|
||||||
// the crate id in the hash because lookups are only done by (name/vers),
|
// the crate id in the hash because lookups are only done by (name/vers),
|
||||||
// not by path.
|
// not by path.
|
||||||
|
@ -567,10 +597,9 @@ pub fn crate_id_hash(crate_id: &CrateId) -> String {
|
||||||
truncated_hash_result(&mut s).as_slice().slice_to(8).to_string()
|
truncated_hash_result(&mut s).as_slice().slice_to(8).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
|
pub fn build_link_meta(krate: &ast::Crate, name: String) -> LinkMeta {
|
||||||
pub fn build_link_meta(krate: &ast::Crate, out_filestem: &str) -> LinkMeta {
|
|
||||||
let r = LinkMeta {
|
let r = LinkMeta {
|
||||||
crateid: find_crate_id(krate.attrs.as_slice(), out_filestem),
|
crate_name: name,
|
||||||
crate_hash: Svh::calculate(krate),
|
crate_hash: Svh::calculate(krate),
|
||||||
};
|
};
|
||||||
info!("{}", r);
|
info!("{}", r);
|
||||||
|
@ -594,7 +623,7 @@ fn symbol_hash(tcx: &ty::ctxt,
|
||||||
// to be independent of one another in the crate.
|
// to be independent of one another in the crate.
|
||||||
|
|
||||||
symbol_hasher.reset();
|
symbol_hasher.reset();
|
||||||
symbol_hasher.input_str(link_meta.crateid.name.as_slice());
|
symbol_hasher.input_str(link_meta.crate_name.as_slice());
|
||||||
symbol_hasher.input_str("-");
|
symbol_hasher.input_str("-");
|
||||||
symbol_hasher.input_str(link_meta.crate_hash.as_str());
|
symbol_hasher.input_str(link_meta.crate_hash.as_str());
|
||||||
symbol_hasher.input_str("-");
|
symbol_hasher.input_str("-");
|
||||||
|
@ -666,8 +695,7 @@ pub fn sanitize(s: &str) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mangle<PI: Iterator<PathElem>>(mut path: PI,
|
pub fn mangle<PI: Iterator<PathElem>>(mut path: PI,
|
||||||
hash: Option<&str>,
|
hash: Option<&str>) -> String {
|
||||||
vers: Option<&str>) -> String {
|
|
||||||
// Follow C++ namespace-mangling style, see
|
// Follow C++ namespace-mangling style, see
|
||||||
// http://en.wikipedia.org/wiki/Name_mangling for more info.
|
// http://en.wikipedia.org/wiki/Name_mangling for more info.
|
||||||
//
|
//
|
||||||
|
@ -698,25 +726,13 @@ pub fn mangle<PI: Iterator<PathElem>>(mut path: PI,
|
||||||
Some(s) => push(&mut n, s),
|
Some(s) => push(&mut n, s),
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
match vers {
|
|
||||||
Some(s) => push(&mut n, s),
|
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
n.push_char('E'); // End name-sequence.
|
n.push_char('E'); // End name-sequence.
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exported_name(path: PathElems, hash: &str, vers: &str) -> String {
|
pub fn exported_name(path: PathElems, hash: &str) -> String {
|
||||||
// The version will get mangled to have a leading '_', but it makes more
|
mangle(path, Some(hash))
|
||||||
// sense to lead with a 'v' b/c this is a version...
|
|
||||||
let vers = if vers.len() > 0 && !char::is_XID_start(vers.char_at(0)) {
|
|
||||||
format!("v{}", vers)
|
|
||||||
} else {
|
|
||||||
vers.to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
mangle(path, Some(hash), Some(vers.as_slice()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
|
pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
|
||||||
|
@ -741,9 +757,7 @@ pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
|
||||||
hash.push_char(EXTRA_CHARS.as_bytes()[extra2] as char);
|
hash.push_char(EXTRA_CHARS.as_bytes()[extra2] as char);
|
||||||
hash.push_char(EXTRA_CHARS.as_bytes()[extra3] as char);
|
hash.push_char(EXTRA_CHARS.as_bytes()[extra3] as char);
|
||||||
|
|
||||||
exported_name(path,
|
exported_name(path, hash.as_slice())
|
||||||
hash.as_slice(),
|
|
||||||
ccx.link_meta.crateid.version_or_default())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
|
pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
|
||||||
|
@ -753,15 +767,11 @@ pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
|
||||||
let path = [PathName(token::intern(s.as_slice())),
|
let path = [PathName(token::intern(s.as_slice())),
|
||||||
gensym_name(name)];
|
gensym_name(name)];
|
||||||
let hash = get_symbol_hash(ccx, t);
|
let hash = get_symbol_hash(ccx, t);
|
||||||
mangle(ast_map::Values(path.iter()), Some(hash.as_slice()), None)
|
mangle(ast_map::Values(path.iter()), Some(hash.as_slice()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
|
pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
|
||||||
mangle(path.chain(Some(gensym_name(flav)).move_iter()), None, None)
|
mangle(path.chain(Some(gensym_name(flav)).move_iter()), None)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn output_lib_filename(id: &CrateId) -> String {
|
|
||||||
format!("{}-{}-{}", id.name, crate_id_hash(id), id.version_or_default())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cc_prog(sess: &Session) -> String {
|
pub fn get_cc_prog(sess: &Session) -> String {
|
||||||
|
@ -803,14 +813,15 @@ fn remove(sess: &Session, path: &Path) {
|
||||||
pub fn link_binary(sess: &Session,
|
pub fn link_binary(sess: &Session,
|
||||||
trans: &CrateTranslation,
|
trans: &CrateTranslation,
|
||||||
outputs: &OutputFilenames,
|
outputs: &OutputFilenames,
|
||||||
id: &CrateId) -> Vec<Path> {
|
crate_name: &str) -> Vec<Path> {
|
||||||
let mut out_filenames = Vec::new();
|
let mut out_filenames = Vec::new();
|
||||||
for &crate_type in sess.crate_types.borrow().iter() {
|
for &crate_type in sess.crate_types.borrow().iter() {
|
||||||
if invalid_output_for_target(sess, crate_type) {
|
if invalid_output_for_target(sess, crate_type) {
|
||||||
sess.bug(format!("invalid output type `{}` for target os `{}`",
|
sess.bug(format!("invalid output type `{}` for target os `{}`",
|
||||||
crate_type, sess.targ_cfg.os).as_slice());
|
crate_type, sess.targ_cfg.os).as_slice());
|
||||||
}
|
}
|
||||||
let out_file = link_binary_output(sess, trans, crate_type, outputs, id);
|
let out_file = link_binary_output(sess, trans, crate_type, outputs,
|
||||||
|
crate_name);
|
||||||
out_filenames.push(out_file);
|
out_filenames.push(out_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,9 +870,11 @@ fn is_writeable(p: &Path) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filename_for_input(sess: &Session, crate_type: config::CrateType,
|
pub fn filename_for_input(sess: &Session,
|
||||||
id: &CrateId, out_filename: &Path) -> Path {
|
crate_type: config::CrateType,
|
||||||
let libname = output_lib_filename(id);
|
name: &str,
|
||||||
|
out_filename: &Path) -> Path {
|
||||||
|
let libname = format!("{}-{}", name, crate_name_hash(sess, name));
|
||||||
match crate_type {
|
match crate_type {
|
||||||
config::CrateTypeRlib => {
|
config::CrateTypeRlib => {
|
||||||
out_filename.with_filename(format!("lib{}.rlib", libname))
|
out_filename.with_filename(format!("lib{}.rlib", libname))
|
||||||
|
@ -891,13 +904,13 @@ fn link_binary_output(sess: &Session,
|
||||||
trans: &CrateTranslation,
|
trans: &CrateTranslation,
|
||||||
crate_type: config::CrateType,
|
crate_type: config::CrateType,
|
||||||
outputs: &OutputFilenames,
|
outputs: &OutputFilenames,
|
||||||
id: &CrateId) -> Path {
|
crate_name: &str) -> Path {
|
||||||
let obj_filename = outputs.temp_path(OutputTypeObject);
|
let obj_filename = outputs.temp_path(OutputTypeObject);
|
||||||
let out_filename = match outputs.single_output_file {
|
let out_filename = match outputs.single_output_file {
|
||||||
Some(ref file) => file.clone(),
|
Some(ref file) => file.clone(),
|
||||||
None => {
|
None => {
|
||||||
let out_filename = outputs.path(OutputTypeExe);
|
let out_filename = outputs.path(OutputTypeExe);
|
||||||
filename_for_input(sess, crate_type, id, &out_filename)
|
filename_for_input(sess, crate_type, crate_name, &out_filename)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -91,8 +91,8 @@ pub struct Options {
|
||||||
pub debugging_opts: u64,
|
pub debugging_opts: u64,
|
||||||
/// Whether to write dependency files. It's (enabled, optional filename).
|
/// Whether to write dependency files. It's (enabled, optional filename).
|
||||||
pub write_dependency_info: (bool, Option<Path>),
|
pub write_dependency_info: (bool, Option<Path>),
|
||||||
/// Crate id-related things to maybe print. It's (crate_id, crate_name, crate_file_name).
|
/// Crate id-related things to maybe print. It's (crate_name, crate_file_name).
|
||||||
pub print_metas: (bool, bool, bool),
|
pub print_metas: (bool, bool),
|
||||||
pub cg: CodegenOptions,
|
pub cg: CodegenOptions,
|
||||||
pub color: ColorConfig,
|
pub color: ColorConfig,
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ pub fn basic_options() -> Options {
|
||||||
no_analysis: false,
|
no_analysis: false,
|
||||||
debugging_opts: 0,
|
debugging_opts: 0,
|
||||||
write_dependency_info: (false, None),
|
write_dependency_info: (false, None),
|
||||||
print_metas: (false, false, false),
|
print_metas: (false, false),
|
||||||
cg: basic_codegen_options(),
|
cg: basic_codegen_options(),
|
||||||
color: Auto,
|
color: Auto,
|
||||||
}
|
}
|
||||||
|
@ -505,7 +505,6 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
|
||||||
"[bin|lib|rlib|dylib|staticlib]"),
|
"[bin|lib|rlib|dylib|staticlib]"),
|
||||||
optmulti("", "emit", "Comma separated list of types of output for the compiler to emit",
|
optmulti("", "emit", "Comma separated list of types of output for the compiler to emit",
|
||||||
"[asm|bc|ir|obj|link]"),
|
"[asm|bc|ir|obj|link]"),
|
||||||
optflag("", "crate-id", "Output the crate id and exit"),
|
|
||||||
optflag("", "crate-name", "Output the crate name and exit"),
|
optflag("", "crate-name", "Output the crate name and exit"),
|
||||||
optflag("", "crate-file-name", "Output the file(s) that would be written if compilation \
|
optflag("", "crate-file-name", "Output the file(s) that would be written if compilation \
|
||||||
continued and exit"),
|
continued and exit"),
|
||||||
|
@ -709,8 +708,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||||
matches.opt_str("dep-info")
|
matches.opt_str("dep-info")
|
||||||
.map(|p| Path::new(p)));
|
.map(|p| Path::new(p)));
|
||||||
|
|
||||||
let print_metas = (matches.opt_present("crate-id"),
|
let print_metas = (matches.opt_present("crate-name"),
|
||||||
matches.opt_present("crate-name"),
|
|
||||||
matches.opt_present("crate-file-name"));
|
matches.opt_present("crate-file-name"));
|
||||||
let cg = build_codegen_options(matches);
|
let cg = build_codegen_options(matches);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ use std::io::MemReader;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::attr::{AttrMetaMethods};
|
use syntax::attr::{AttrMetaMethods};
|
||||||
use syntax::crateid::CrateId;
|
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::print::{pp, pprust};
|
use syntax::print::{pp, pprust};
|
||||||
|
@ -69,7 +68,7 @@ pub fn compile_input(sess: Session,
|
||||||
// large chunks of memory alive and we want to free them as soon as
|
// large chunks of memory alive and we want to free them as soon as
|
||||||
// possible to keep the peak memory usage low
|
// possible to keep the peak memory usage low
|
||||||
let (outputs, trans, sess) = {
|
let (outputs, trans, sess) = {
|
||||||
let (outputs, expanded_crate, ast_map) = {
|
let (outputs, expanded_crate, ast_map, id) = {
|
||||||
let krate = phase_1_parse_input(&sess, cfg, input);
|
let krate = phase_1_parse_input(&sess, cfg, input);
|
||||||
if stop_after_phase_1(&sess) { return; }
|
if stop_after_phase_1(&sess) { return; }
|
||||||
let outputs = build_output_filenames(input,
|
let outputs = build_output_filenames(input,
|
||||||
|
@ -77,25 +76,25 @@ pub fn compile_input(sess: Session,
|
||||||
output,
|
output,
|
||||||
krate.attrs.as_slice(),
|
krate.attrs.as_slice(),
|
||||||
&sess);
|
&sess);
|
||||||
let id = link::find_crate_id(krate.attrs.as_slice(),
|
let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
|
||||||
outputs.out_filestem.as_slice());
|
outputs.out_filestem.as_slice());
|
||||||
let (expanded_crate, ast_map)
|
let (expanded_crate, ast_map)
|
||||||
= match phase_2_configure_and_expand(&sess, krate, &id) {
|
= match phase_2_configure_and_expand(&sess, krate, id.as_slice()) {
|
||||||
None => return,
|
None => return,
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
};
|
};
|
||||||
|
|
||||||
(outputs, expanded_crate, ast_map)
|
(outputs, expanded_crate, ast_map, id)
|
||||||
};
|
};
|
||||||
write_out_deps(&sess, input, &outputs, &expanded_crate);
|
write_out_deps(&sess, input, &outputs, id.as_slice());
|
||||||
|
|
||||||
if stop_after_phase_2(&sess) { return; }
|
if stop_after_phase_2(&sess) { return; }
|
||||||
|
|
||||||
let analysis = phase_3_run_analysis_passes(sess, &expanded_crate, ast_map);
|
let analysis = phase_3_run_analysis_passes(sess, &expanded_crate,
|
||||||
|
ast_map, id);
|
||||||
phase_save_analysis(&analysis.ty_cx.sess, &expanded_crate, &analysis, outdir);
|
phase_save_analysis(&analysis.ty_cx.sess, &expanded_crate, &analysis, outdir);
|
||||||
if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
|
if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
|
||||||
let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate,
|
let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate, analysis);
|
||||||
analysis, &outputs);
|
|
||||||
|
|
||||||
// Discard interned strings as they are no longer required.
|
// Discard interned strings as they are no longer required.
|
||||||
token::get_ident_interner().clear();
|
token::get_ident_interner().clear();
|
||||||
|
@ -181,11 +180,12 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
|
||||||
/// Returns `None` if we're aborting after handling -W help.
|
/// Returns `None` if we're aborting after handling -W help.
|
||||||
pub fn phase_2_configure_and_expand(sess: &Session,
|
pub fn phase_2_configure_and_expand(sess: &Session,
|
||||||
mut krate: ast::Crate,
|
mut krate: ast::Crate,
|
||||||
crate_id: &CrateId)
|
crate_name: &str)
|
||||||
-> Option<(ast::Crate, syntax::ast_map::Map)> {
|
-> Option<(ast::Crate, syntax::ast_map::Map)> {
|
||||||
let time_passes = sess.time_passes();
|
let time_passes = sess.time_passes();
|
||||||
|
|
||||||
*sess.crate_types.borrow_mut() = collect_crate_types(sess, krate.attrs.as_slice());
|
*sess.crate_types.borrow_mut() =
|
||||||
|
collect_crate_types(sess, krate.attrs.as_slice());
|
||||||
|
|
||||||
time(time_passes, "gated feature checking", (), |_|
|
time(time_passes, "gated feature checking", (), |_|
|
||||||
front::feature_gate::check_crate(sess, &krate));
|
front::feature_gate::check_crate(sess, &krate));
|
||||||
|
@ -247,7 +247,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||||
}
|
}
|
||||||
let cfg = syntax::ext::expand::ExpansionConfig {
|
let cfg = syntax::ext::expand::ExpansionConfig {
|
||||||
deriving_hash_type_parameter: sess.features.default_type_params.get(),
|
deriving_hash_type_parameter: sess.features.default_type_params.get(),
|
||||||
crate_id: crate_id.clone(),
|
crate_name: crate_name.to_string(),
|
||||||
};
|
};
|
||||||
syntax::ext::expand::expand_crate(&sess.parse_sess,
|
syntax::ext::expand::expand_crate(&sess.parse_sess,
|
||||||
cfg,
|
cfg,
|
||||||
|
@ -286,6 +286,7 @@ pub struct CrateAnalysis {
|
||||||
pub public_items: middle::privacy::PublicItems,
|
pub public_items: middle::privacy::PublicItems,
|
||||||
pub ty_cx: ty::ctxt,
|
pub ty_cx: ty::ctxt,
|
||||||
pub reachable: NodeSet,
|
pub reachable: NodeSet,
|
||||||
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the resolution, typechecking, region checking and other
|
/// Run the resolution, typechecking, region checking and other
|
||||||
|
@ -293,7 +294,8 @@ pub struct CrateAnalysis {
|
||||||
/// structures carrying the results of the analysis.
|
/// structures carrying the results of the analysis.
|
||||||
pub fn phase_3_run_analysis_passes(sess: Session,
|
pub fn phase_3_run_analysis_passes(sess: Session,
|
||||||
krate: &ast::Crate,
|
krate: &ast::Crate,
|
||||||
ast_map: syntax::ast_map::Map) -> CrateAnalysis {
|
ast_map: syntax::ast_map::Map,
|
||||||
|
name: String) -> CrateAnalysis {
|
||||||
|
|
||||||
let time_passes = sess.time_passes();
|
let time_passes = sess.time_passes();
|
||||||
|
|
||||||
|
@ -398,6 +400,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
||||||
exported_items: exported_items,
|
exported_items: exported_items,
|
||||||
public_items: public_items,
|
public_items: public_items,
|
||||||
reachable: reachable_map,
|
reachable: reachable_map,
|
||||||
|
name: name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,8 +429,7 @@ pub struct CrateTranslation {
|
||||||
/// Run the translation phase to LLVM, after which the AST and analysis can
|
/// Run the translation phase to LLVM, after which the AST and analysis can
|
||||||
/// be discarded.
|
/// be discarded.
|
||||||
pub fn phase_4_translate_to_llvm(krate: ast::Crate,
|
pub fn phase_4_translate_to_llvm(krate: ast::Crate,
|
||||||
analysis: CrateAnalysis,
|
analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
|
||||||
outputs: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
|
|
||||||
let time_passes = analysis.ty_cx.sess.time_passes();
|
let time_passes = analysis.ty_cx.sess.time_passes();
|
||||||
|
|
||||||
time(time_passes, "resolving dependency formats", (), |_|
|
time(time_passes, "resolving dependency formats", (), |_|
|
||||||
|
@ -435,7 +437,7 @@ pub fn phase_4_translate_to_llvm(krate: ast::Crate,
|
||||||
|
|
||||||
// Option dance to work around the lack of stack once closures.
|
// Option dance to work around the lack of stack once closures.
|
||||||
time(time_passes, "translation", (krate, analysis), |(krate, analysis)|
|
time(time_passes, "translation", (krate, analysis), |(krate, analysis)|
|
||||||
trans::base::trans_crate(krate, analysis, outputs))
|
trans::base::trans_crate(krate, analysis))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run LLVM itself, producing a bitcode file, assembly file or object file
|
/// Run LLVM itself, producing a bitcode file, assembly file or object file
|
||||||
|
@ -473,7 +475,7 @@ pub fn phase_6_link_output(sess: &Session,
|
||||||
link::link_binary(sess,
|
link::link_binary(sess,
|
||||||
trans,
|
trans,
|
||||||
outputs,
|
outputs,
|
||||||
&trans.link.crateid));
|
trans.link.crate_name.as_slice()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop_after_phase_3(sess: &Session) -> bool {
|
pub fn stop_after_phase_3(sess: &Session) -> bool {
|
||||||
|
@ -514,9 +516,7 @@ pub fn stop_after_phase_5(sess: &Session) -> bool {
|
||||||
fn write_out_deps(sess: &Session,
|
fn write_out_deps(sess: &Session,
|
||||||
input: &Input,
|
input: &Input,
|
||||||
outputs: &OutputFilenames,
|
outputs: &OutputFilenames,
|
||||||
krate: &ast::Crate) {
|
id: &str) {
|
||||||
let id = link::find_crate_id(krate.attrs.as_slice(),
|
|
||||||
outputs.out_filestem.as_slice());
|
|
||||||
|
|
||||||
let mut out_filenames = Vec::new();
|
let mut out_filenames = Vec::new();
|
||||||
for output_type in sess.opts.output_types.iter() {
|
for output_type in sess.opts.output_types.iter() {
|
||||||
|
@ -524,7 +524,8 @@ fn write_out_deps(sess: &Session,
|
||||||
match *output_type {
|
match *output_type {
|
||||||
link::OutputTypeExe => {
|
link::OutputTypeExe => {
|
||||||
for output in sess.crate_types.borrow().iter() {
|
for output in sess.crate_types.borrow().iter() {
|
||||||
let p = link::filename_for_input(sess, *output, &id, &file);
|
let p = link::filename_for_input(sess, *output,
|
||||||
|
id, &file);
|
||||||
out_filenames.push(p);
|
out_filenames.push(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -649,13 +650,14 @@ pub fn pretty_print_input(sess: Session,
|
||||||
ppm: PpMode,
|
ppm: PpMode,
|
||||||
ofile: Option<Path>) {
|
ofile: Option<Path>) {
|
||||||
let krate = phase_1_parse_input(&sess, cfg, input);
|
let krate = phase_1_parse_input(&sess, cfg, input);
|
||||||
let id = link::find_crate_id(krate.attrs.as_slice(),
|
let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
|
||||||
input.filestem().as_slice());
|
input.filestem().as_slice());
|
||||||
|
|
||||||
let (krate, ast_map, is_expanded) = match ppm {
|
let (krate, ast_map, is_expanded) = match ppm {
|
||||||
PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
|
PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
|
||||||
let (krate, ast_map)
|
let (krate, ast_map)
|
||||||
= match phase_2_configure_and_expand(&sess, krate, &id) {
|
= match phase_2_configure_and_expand(&sess, krate,
|
||||||
|
id.as_slice()) {
|
||||||
None => return,
|
None => return,
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
};
|
};
|
||||||
|
@ -695,7 +697,7 @@ pub fn pretty_print_input(sess: Session,
|
||||||
}
|
}
|
||||||
PpmTyped => {
|
PpmTyped => {
|
||||||
let ast_map = ast_map.expect("--pretty=typed missing ast_map");
|
let ast_map = ast_map.expect("--pretty=typed missing ast_map");
|
||||||
let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map, id);
|
||||||
let annotation = TypedAnnotation {
|
let annotation = TypedAnnotation {
|
||||||
analysis: analysis
|
analysis: analysis
|
||||||
};
|
};
|
||||||
|
@ -728,7 +730,8 @@ pub fn pretty_print_input(sess: Session,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
let analysis = phase_3_run_analysis_passes(sess, &krate,
|
||||||
|
ast_map, id);
|
||||||
print_flowgraph(analysis, block, out)
|
print_flowgraph(analysis, block, out)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -895,11 +898,10 @@ pub fn build_output_filenames(input: &Input,
|
||||||
|
|
||||||
let mut stem = input.filestem();
|
let mut stem = input.filestem();
|
||||||
|
|
||||||
// If a crateid is present, we use it as the link name
|
// If a crate name is present, we use it as the link name
|
||||||
let crateid = attr::find_crateid(attrs);
|
match attr::find_crate_name(attrs) {
|
||||||
match crateid {
|
|
||||||
None => {}
|
None => {}
|
||||||
Some(crateid) => stem = crateid.name.to_string(),
|
Some(name) => stem = name.get().to_string(),
|
||||||
}
|
}
|
||||||
OutputFilenames {
|
OutputFilenames {
|
||||||
out_directory: dirpath,
|
out_directory: dirpath,
|
||||||
|
|
|
@ -294,28 +294,25 @@ fn print_crate_info(sess: &Session,
|
||||||
odir: &Option<Path>,
|
odir: &Option<Path>,
|
||||||
ofile: &Option<Path>)
|
ofile: &Option<Path>)
|
||||||
-> bool {
|
-> bool {
|
||||||
let (crate_id, crate_name, crate_file_name) = sess.opts.print_metas;
|
let (crate_name, crate_file_name) = sess.opts.print_metas;
|
||||||
// these nasty nested conditions are to avoid doing extra work
|
// these nasty nested conditions are to avoid doing extra work
|
||||||
if crate_id || crate_name || crate_file_name {
|
if crate_name || crate_file_name {
|
||||||
let attrs = parse_crate_attrs(sess, input);
|
let attrs = parse_crate_attrs(sess, input);
|
||||||
let t_outputs = driver::build_output_filenames(input,
|
let t_outputs = driver::build_output_filenames(input,
|
||||||
odir,
|
odir,
|
||||||
ofile,
|
ofile,
|
||||||
attrs.as_slice(),
|
attrs.as_slice(),
|
||||||
sess);
|
sess);
|
||||||
let id = link::find_crate_id(attrs.as_slice(),
|
let id = link::find_crate_name(Some(sess), attrs.as_slice(),
|
||||||
t_outputs.out_filestem.as_slice());
|
t_outputs.out_filestem.as_slice());
|
||||||
|
|
||||||
if crate_id {
|
|
||||||
println!("{}", id.to_str());
|
|
||||||
}
|
|
||||||
if crate_name {
|
if crate_name {
|
||||||
println!("{}", id.name);
|
println!("{}", id);
|
||||||
}
|
}
|
||||||
if crate_file_name {
|
if crate_file_name {
|
||||||
let crate_types = driver::collect_crate_types(sess, attrs.as_slice());
|
let crate_types = driver::collect_crate_types(sess, attrs.as_slice());
|
||||||
for &style in crate_types.iter() {
|
for &style in crate_types.iter() {
|
||||||
let fname = link::filename_for_input(sess, style, &id,
|
let fname = link::filename_for_input(sess, style, id.as_slice(),
|
||||||
&t_outputs.with_extension(""));
|
&t_outputs.with_extension(""));
|
||||||
println!("{}", fname.filename_display());
|
println!("{}", fname.filename_display());
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,6 @@ use syntax::util::small_vector::SmallVector;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::gc::{Gc, GC};
|
use std::gc::{Gc, GC};
|
||||||
|
|
||||||
pub static VERSION: &'static str = "0.11.0";
|
|
||||||
|
|
||||||
pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
|
pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
|
||||||
-> ast::Crate {
|
-> ast::Crate {
|
||||||
if use_std(&krate) {
|
if use_std(&krate) {
|
||||||
|
@ -60,24 +58,12 @@ struct StandardLibraryInjector<'a> {
|
||||||
sess: &'a Session,
|
sess: &'a Session,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
|
|
||||||
match option_env!("CFG_DISABLE_INJECT_STD_VERSION") {
|
|
||||||
Some("1") => None,
|
|
||||||
_ => {
|
|
||||||
Some((token::intern_and_get_ident(format!("{}#{}",
|
|
||||||
krate,
|
|
||||||
VERSION).as_slice()),
|
|
||||||
ast::CookedStr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> fold::Folder for StandardLibraryInjector<'a> {
|
impl<'a> fold::Folder for StandardLibraryInjector<'a> {
|
||||||
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
|
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
|
||||||
let mut vis = vec!(ast::ViewItem {
|
let mut vis = vec!(ast::ViewItem {
|
||||||
node: ast::ViewItemExternCrate(token::str_to_ident("std"),
|
node: ast::ViewItemExternCrate(token::str_to_ident("std"),
|
||||||
with_version("std"),
|
None,
|
||||||
ast::DUMMY_NODE_ID),
|
ast::DUMMY_NODE_ID),
|
||||||
attrs: vec!(
|
attrs: vec!(
|
||||||
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
|
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
|
||||||
InternedString::new("phase"),
|
InternedString::new("phase"),
|
||||||
|
@ -95,8 +81,8 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
|
||||||
if use_start(&krate) && any_exe {
|
if use_start(&krate) && any_exe {
|
||||||
vis.push(ast::ViewItem {
|
vis.push(ast::ViewItem {
|
||||||
node: ast::ViewItemExternCrate(token::str_to_ident("native"),
|
node: ast::ViewItemExternCrate(token::str_to_ident("native"),
|
||||||
with_version("native"),
|
None,
|
||||||
ast::DUMMY_NODE_ID),
|
ast::DUMMY_NODE_ID),
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
vis: ast::Inherited,
|
vis: ast::Inherited,
|
||||||
span: DUMMY_SP
|
span: DUMMY_SP
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
use driver::session::Session;
|
use driver::session::Session;
|
||||||
use front::config;
|
use front::config;
|
||||||
use front::std_inject::with_version;
|
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::gc::{Gc, GC};
|
use std::gc::{Gc, GC};
|
||||||
|
@ -154,7 +153,7 @@ fn generate_test_harness(sess: &Session, krate: ast::Crate)
|
||||||
ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
|
ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
|
||||||
ExpansionConfig {
|
ExpansionConfig {
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_name: "test".to_string(),
|
||||||
}),
|
}),
|
||||||
path: RefCell::new(Vec::new()),
|
path: RefCell::new(Vec::new()),
|
||||||
testfns: RefCell::new(Vec::new()),
|
testfns: RefCell::new(Vec::new()),
|
||||||
|
@ -298,9 +297,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
|
||||||
ast::DUMMY_NODE_ID))),
|
ast::DUMMY_NODE_ID))),
|
||||||
ast::Public)
|
ast::Public)
|
||||||
} else {
|
} else {
|
||||||
(ast::ViewItemExternCrate(id_test,
|
(ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
|
||||||
with_version("test"),
|
|
||||||
ast::DUMMY_NODE_ID),
|
|
||||||
ast::Inherited)
|
ast::Inherited)
|
||||||
};
|
};
|
||||||
ast::ViewItem {
|
ast::ViewItem {
|
||||||
|
@ -395,8 +392,8 @@ fn mk_tests(cx: &TestCtxt) -> Gc<ast::Item> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_test_crate(krate: &ast::Crate) -> bool {
|
fn is_test_crate(krate: &ast::Crate) -> bool {
|
||||||
match attr::find_crateid(krate.attrs.as_slice()) {
|
match attr::find_crate_name(krate.attrs.as_slice()) {
|
||||||
Some(ref s) if "test" == s.name.as_slice() => true,
|
Some(ref s) if "test" == s.get().as_slice() => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use syntax::crateid::CrateId;
|
|
||||||
use back::svh::Svh;
|
use back::svh::Svh;
|
||||||
|
|
||||||
// EBML enum definitions and utils shared by the encoder and decoder
|
// EBML enum definitions and utils shared by the encoder and decoder
|
||||||
|
@ -71,9 +70,9 @@ pub static tag_crate_deps: uint = 0x18;
|
||||||
pub static tag_crate_dep: uint = 0x19;
|
pub static tag_crate_dep: uint = 0x19;
|
||||||
|
|
||||||
pub static tag_crate_hash: uint = 0x1a;
|
pub static tag_crate_hash: uint = 0x1a;
|
||||||
pub static tag_crate_crateid: uint = 0x1b;
|
pub static tag_crate_crate_name: uint = 0x1b;
|
||||||
|
|
||||||
pub static tag_crate_dep_crateid: uint = 0x1d;
|
pub static tag_crate_dep_crate_name: uint = 0x1d;
|
||||||
pub static tag_crate_dep_hash: uint = 0x1e;
|
pub static tag_crate_dep_hash: uint = 0x1e;
|
||||||
|
|
||||||
pub static tag_mod_impl: uint = 0x1f;
|
pub static tag_mod_impl: uint = 0x1f;
|
||||||
|
@ -215,7 +214,7 @@ pub static tag_items_data_item_stability: uint = 0x92;
|
||||||
|
|
||||||
#[deriving(Clone, Show)]
|
#[deriving(Clone, Show)]
|
||||||
pub struct LinkMeta {
|
pub struct LinkMeta {
|
||||||
pub crateid: CrateId,
|
pub crate_name: String,
|
||||||
pub crate_hash: Svh,
|
pub crate_hash: Svh,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
//! Validates all used crates and extern libraries and loads their metadata
|
//! Validates all used crates and extern libraries and loads their metadata
|
||||||
|
|
||||||
use back::link;
|
|
||||||
use back::svh::Svh;
|
use back::svh::Svh;
|
||||||
use driver::session::Session;
|
use driver::session::Session;
|
||||||
use driver::{driver, config};
|
use driver::{driver, config};
|
||||||
|
@ -33,7 +32,6 @@ use syntax::codemap::{Span};
|
||||||
use syntax::diagnostic::SpanHandler;
|
use syntax::diagnostic::SpanHandler;
|
||||||
use syntax::parse::token::InternedString;
|
use syntax::parse::token::InternedString;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::crateid::CrateId;
|
|
||||||
use syntax::visit;
|
use syntax::visit;
|
||||||
|
|
||||||
struct Env<'a> {
|
struct Env<'a> {
|
||||||
|
@ -69,7 +67,7 @@ impl<'a> visit::Visitor<()> for Env<'a> {
|
||||||
fn dump_crates(cstore: &CStore) {
|
fn dump_crates(cstore: &CStore) {
|
||||||
debug!("resolved crates:");
|
debug!("resolved crates:");
|
||||||
cstore.iter_crate_data_origins(|_, data, opt_source| {
|
cstore.iter_crate_data_origins(|_, data, opt_source| {
|
||||||
debug!("crate_id: {}", data.crate_id());
|
debug!(" name: {}", data.name());
|
||||||
debug!(" cnum: {}", data.cnum);
|
debug!(" cnum: {}", data.cnum);
|
||||||
debug!(" hash: {}", data.hash());
|
debug!(" hash: {}", data.hash());
|
||||||
opt_source.map(|cs| {
|
opt_source.map(|cs| {
|
||||||
|
@ -83,20 +81,17 @@ fn dump_crates(cstore: &CStore) {
|
||||||
fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
|
fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
cstore.iter_crate_data(|cnum, data| {
|
cstore.iter_crate_data(|cnum, data| {
|
||||||
let crateid = data.crate_id();
|
map.find_or_insert_with(data.name(), |_| Vec::new()).push(cnum);
|
||||||
let key = (crateid.name.clone(), crateid.path.clone());
|
|
||||||
map.find_or_insert_with(key, |_| Vec::new()).push(cnum);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
for ((name, _), dupes) in map.move_iter() {
|
for (name, dupes) in map.move_iter() {
|
||||||
if dupes.len() == 1 { continue }
|
if dupes.len() == 1 { continue }
|
||||||
diag.handler().warn(
|
diag.handler().warn(
|
||||||
format!("using multiple versions of crate `{}`",
|
format!("using multiple versions of crate `{}`", name).as_slice());
|
||||||
name).as_slice());
|
|
||||||
for dupe in dupes.move_iter() {
|
for dupe in dupes.move_iter() {
|
||||||
let data = cstore.get_crate_data(dupe);
|
let data = cstore.get_crate_data(dupe);
|
||||||
diag.span_note(data.span, "used here");
|
diag.span_note(data.span, "used here");
|
||||||
loader::note_crateid_attr(diag, &data.crate_id());
|
loader::note_crate_name(diag, data.name().as_slice());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +124,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
|
||||||
let (cnum, _, _) = resolve_crate(e,
|
let (cnum, _, _) = resolve_crate(e,
|
||||||
&None,
|
&None,
|
||||||
info.ident.as_slice(),
|
info.ident.as_slice(),
|
||||||
&info.crate_id,
|
info.name.as_slice(),
|
||||||
None,
|
None,
|
||||||
i.span);
|
i.span);
|
||||||
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
||||||
|
@ -140,7 +135,7 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
|
||||||
|
|
||||||
struct CrateInfo {
|
struct CrateInfo {
|
||||||
ident: String,
|
ident: String,
|
||||||
crate_id: CrateId,
|
name: String,
|
||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
should_link: bool,
|
should_link: bool,
|
||||||
}
|
}
|
||||||
|
@ -151,22 +146,18 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
|
||||||
let ident = token::get_ident(ident);
|
let ident = token::get_ident(ident);
|
||||||
debug!("resolving extern crate stmt. ident: {:?} path_opt: {:?}",
|
debug!("resolving extern crate stmt. ident: {:?} path_opt: {:?}",
|
||||||
ident, path_opt);
|
ident, path_opt);
|
||||||
let crate_id = match *path_opt {
|
let name = match *path_opt {
|
||||||
Some((ref path_str, _)) => {
|
Some((ref path_str, _)) => {
|
||||||
let crateid: Option<CrateId> = from_str(path_str.get());
|
let name = path_str.get().to_str();
|
||||||
match crateid {
|
validate_crate_name(Some(e.sess), name.as_slice(),
|
||||||
None => {
|
Some(i.span));
|
||||||
e.sess.span_err(i.span, "malformed crate id");
|
name
|
||||||
return None
|
|
||||||
}
|
|
||||||
Some(id) => id
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => from_str(ident.get().to_str().as_slice()).unwrap()
|
None => ident.get().to_str(),
|
||||||
};
|
};
|
||||||
Some(CrateInfo {
|
Some(CrateInfo {
|
||||||
ident: ident.get().to_string(),
|
ident: ident.get().to_string(),
|
||||||
crate_id: crate_id,
|
name: name,
|
||||||
id: id,
|
id: id,
|
||||||
should_link: should_link(i),
|
should_link: should_link(i),
|
||||||
})
|
})
|
||||||
|
@ -175,6 +166,28 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
|
||||||
|
let err = |s: &str| {
|
||||||
|
match (sp, sess) {
|
||||||
|
(_, None) => fail!("{}", s),
|
||||||
|
(Some(sp), Some(sess)) => sess.span_err(sp, s),
|
||||||
|
(None, Some(sess)) => sess.err(s),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if s.len() == 0 {
|
||||||
|
err("crate name must not be empty");
|
||||||
|
}
|
||||||
|
for c in s.chars() {
|
||||||
|
if c.is_alphanumeric() { continue }
|
||||||
|
if c == '_' || c == '-' { continue }
|
||||||
|
err(format!("invalid character in crate name: `{}`", c).as_slice());
|
||||||
|
}
|
||||||
|
match sess {
|
||||||
|
Some(sess) => sess.abort_if_errors(),
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_item(e: &Env, i: &ast::Item) {
|
fn visit_item(e: &Env, i: &ast::Item) {
|
||||||
match i.node {
|
match i.node {
|
||||||
ast::ItemForeignMod(ref fm) => {
|
ast::ItemForeignMod(ref fm) => {
|
||||||
|
@ -263,12 +276,11 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn existing_match(e: &Env, crate_id: &CrateId,
|
fn existing_match(e: &Env, name: &str,
|
||||||
hash: Option<&Svh>) -> Option<ast::CrateNum> {
|
hash: Option<&Svh>) -> Option<ast::CrateNum> {
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
e.sess.cstore.iter_crate_data(|cnum, data| {
|
e.sess.cstore.iter_crate_data(|cnum, data| {
|
||||||
let other_id = data.crate_id();
|
if data.name().as_slice() == name {
|
||||||
if crate_id.matches(&other_id) {
|
|
||||||
let other_hash = data.hash();
|
let other_hash = data.hash();
|
||||||
match hash {
|
match hash {
|
||||||
Some(hash) if *hash != other_hash => {}
|
Some(hash) if *hash != other_hash => {}
|
||||||
|
@ -282,7 +294,7 @@ fn existing_match(e: &Env, crate_id: &CrateId,
|
||||||
fn register_crate<'a>(e: &mut Env,
|
fn register_crate<'a>(e: &mut Env,
|
||||||
root: &Option<CratePaths>,
|
root: &Option<CratePaths>,
|
||||||
ident: &str,
|
ident: &str,
|
||||||
crate_id: &CrateId,
|
name: &str,
|
||||||
span: Span,
|
span: Span,
|
||||||
lib: loader::Library)
|
lib: loader::Library)
|
||||||
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
|
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
|
||||||
|
@ -309,7 +321,7 @@ fn register_crate<'a>(e: &mut Env,
|
||||||
let loader::Library{ dylib, rlib, metadata } = lib;
|
let loader::Library{ dylib, rlib, metadata } = lib;
|
||||||
|
|
||||||
let cmeta = Rc::new( cstore::crate_metadata {
|
let cmeta = Rc::new( cstore::crate_metadata {
|
||||||
name: crate_id.name.to_string(),
|
name: name.to_string(),
|
||||||
data: metadata,
|
data: metadata,
|
||||||
cnum_map: cnum_map,
|
cnum_map: cnum_map,
|
||||||
cnum: cnum,
|
cnum: cnum,
|
||||||
|
@ -330,20 +342,18 @@ fn register_crate<'a>(e: &mut Env,
|
||||||
fn resolve_crate<'a>(e: &mut Env,
|
fn resolve_crate<'a>(e: &mut Env,
|
||||||
root: &Option<CratePaths>,
|
root: &Option<CratePaths>,
|
||||||
ident: &str,
|
ident: &str,
|
||||||
crate_id: &CrateId,
|
name: &str,
|
||||||
hash: Option<&Svh>,
|
hash: Option<&Svh>,
|
||||||
span: Span)
|
span: Span)
|
||||||
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
|
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
|
||||||
cstore::CrateSource) {
|
cstore::CrateSource) {
|
||||||
match existing_match(e, crate_id, hash) {
|
match existing_match(e, name, hash) {
|
||||||
None => {
|
None => {
|
||||||
let id_hash = link::crate_id_hash(crate_id);
|
|
||||||
let mut load_ctxt = loader::Context {
|
let mut load_ctxt = loader::Context {
|
||||||
sess: e.sess,
|
sess: e.sess,
|
||||||
span: span,
|
span: span,
|
||||||
ident: ident,
|
ident: ident,
|
||||||
crate_id: crate_id,
|
crate_name: name,
|
||||||
id_hash: id_hash.as_slice(),
|
|
||||||
hash: hash.map(|a| &*a),
|
hash: hash.map(|a| &*a),
|
||||||
filesearch: e.sess.target_filesearch(),
|
filesearch: e.sess.target_filesearch(),
|
||||||
os: e.sess.targ_cfg.os,
|
os: e.sess.targ_cfg.os,
|
||||||
|
@ -353,7 +363,7 @@ fn resolve_crate<'a>(e: &mut Env,
|
||||||
rejected_via_triple: vec!(),
|
rejected_via_triple: vec!(),
|
||||||
};
|
};
|
||||||
let library = load_ctxt.load_library_crate();
|
let library = load_ctxt.load_library_crate();
|
||||||
register_crate(e, root, ident, crate_id, span, library)
|
register_crate(e, root, ident, name, span, library)
|
||||||
}
|
}
|
||||||
Some(cnum) => (cnum,
|
Some(cnum) => (cnum,
|
||||||
e.sess.cstore.get_crate_data(cnum),
|
e.sess.cstore.get_crate_data(cnum),
|
||||||
|
@ -370,10 +380,10 @@ fn resolve_crate_deps(e: &mut Env,
|
||||||
// The map from crate numbers in the crate we're resolving to local crate
|
// The map from crate numbers in the crate we're resolving to local crate
|
||||||
// numbers
|
// numbers
|
||||||
decoder::get_crate_deps(cdata).iter().map(|dep| {
|
decoder::get_crate_deps(cdata).iter().map(|dep| {
|
||||||
debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
|
debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
|
||||||
let (local_cnum, _, _) = resolve_crate(e, root,
|
let (local_cnum, _, _) = resolve_crate(e, root,
|
||||||
dep.crate_id.name.as_slice(),
|
dep.name.as_slice(),
|
||||||
&dep.crate_id,
|
dep.name.as_slice(),
|
||||||
Some(&dep.hash),
|
Some(&dep.hash),
|
||||||
span);
|
span);
|
||||||
(dep.cnum, local_cnum)
|
(dep.cnum, local_cnum)
|
||||||
|
@ -399,14 +409,12 @@ impl<'a> PluginMetadataReader<'a> {
|
||||||
let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
|
let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
|
||||||
let is_cross = target_triple != driver::host_triple();
|
let is_cross = target_triple != driver::host_triple();
|
||||||
let mut should_link = info.should_link && !is_cross;
|
let mut should_link = info.should_link && !is_cross;
|
||||||
let id_hash = link::crate_id_hash(&info.crate_id);
|
|
||||||
let os = config::get_os(driver::host_triple()).unwrap();
|
let os = config::get_os(driver::host_triple()).unwrap();
|
||||||
let mut load_ctxt = loader::Context {
|
let mut load_ctxt = loader::Context {
|
||||||
sess: self.env.sess,
|
sess: self.env.sess,
|
||||||
span: krate.span,
|
span: krate.span,
|
||||||
ident: info.ident.as_slice(),
|
ident: info.ident.as_slice(),
|
||||||
crate_id: &info.crate_id,
|
crate_name: info.name.as_slice(),
|
||||||
id_hash: id_hash.as_slice(),
|
|
||||||
hash: None,
|
hash: None,
|
||||||
filesearch: self.env.sess.host_filesearch(),
|
filesearch: self.env.sess.host_filesearch(),
|
||||||
triple: driver::host_triple(),
|
triple: driver::host_triple(),
|
||||||
|
@ -448,10 +456,11 @@ impl<'a> PluginMetadataReader<'a> {
|
||||||
macros: macros,
|
macros: macros,
|
||||||
registrar_symbol: registrar,
|
registrar_symbol: registrar,
|
||||||
};
|
};
|
||||||
if should_link && existing_match(&self.env, &info.crate_id, None).is_none() {
|
if should_link && existing_match(&self.env, info.name.as_slice(),
|
||||||
|
None).is_none() {
|
||||||
// register crate now to avoid double-reading metadata
|
// register crate now to avoid double-reading metadata
|
||||||
register_crate(&mut self.env, &None, info.ident.as_slice(),
|
register_crate(&mut self.env, &None, info.ident.as_slice(),
|
||||||
&info.crate_id, krate.span, library);
|
info.name.as_slice(), krate.span, library);
|
||||||
}
|
}
|
||||||
pc
|
pc
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ use std::c_vec::CVec;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::crateid::CrateId;
|
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::parse::token::IdentInterner;
|
use syntax::parse::token::IdentInterner;
|
||||||
|
|
||||||
|
@ -220,7 +219,7 @@ impl CStore {
|
||||||
|
|
||||||
impl crate_metadata {
|
impl crate_metadata {
|
||||||
pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
|
pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
|
||||||
pub fn crate_id(&self) -> CrateId { decoder::get_crate_id(self.data()) }
|
pub fn name(&self) -> String { decoder::get_crate_name(self.data()) }
|
||||||
pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
|
pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ use syntax::parse::token;
|
||||||
use syntax::print::pprust;
|
use syntax::print::pprust;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap;
|
use syntax::codemap;
|
||||||
use syntax::crateid::CrateId;
|
|
||||||
|
|
||||||
pub type Cmd<'a> = &'a crate_metadata;
|
pub type Cmd<'a> = &'a crate_metadata;
|
||||||
|
|
||||||
|
@ -1101,7 +1100,7 @@ pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct CrateDep {
|
pub struct CrateDep {
|
||||||
pub cnum: ast::CrateNum,
|
pub cnum: ast::CrateNum,
|
||||||
pub crate_id: CrateId,
|
pub name: String,
|
||||||
pub hash: Svh,
|
pub hash: Svh,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1115,13 +1114,11 @@ pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
|
||||||
d.as_str_slice().to_string()
|
d.as_str_slice().to_string()
|
||||||
}
|
}
|
||||||
reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
|
reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
|
||||||
let crate_id =
|
let name = docstr(depdoc, tag_crate_dep_crate_name);
|
||||||
from_str(docstr(depdoc,
|
|
||||||
tag_crate_dep_crateid).as_slice()).unwrap();
|
|
||||||
let hash = Svh::new(docstr(depdoc, tag_crate_dep_hash).as_slice());
|
let hash = Svh::new(docstr(depdoc, tag_crate_dep_hash).as_slice());
|
||||||
deps.push(CrateDep {
|
deps.push(CrateDep {
|
||||||
cnum: crate_num,
|
cnum: crate_num,
|
||||||
crate_id: crate_id,
|
name: name,
|
||||||
hash: hash,
|
hash: hash,
|
||||||
});
|
});
|
||||||
crate_num += 1;
|
crate_num += 1;
|
||||||
|
@ -1133,7 +1130,7 @@ pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
|
||||||
fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
||||||
try!(write!(out, "=External Dependencies=\n"));
|
try!(write!(out, "=External Dependencies=\n"));
|
||||||
for dep in get_crate_deps(data).iter() {
|
for dep in get_crate_deps(data).iter() {
|
||||||
try!(write!(out, "{} {}-{}\n", dep.cnum, dep.crate_id, dep.hash));
|
try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
|
||||||
}
|
}
|
||||||
try!(write!(out, "\n"));
|
try!(write!(out, "\n"));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1152,23 +1149,21 @@ pub fn get_crate_hash(data: &[u8]) -> Svh {
|
||||||
Svh::new(hashdoc.as_str_slice())
|
Svh::new(hashdoc.as_str_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_get_crate_id(data: &[u8]) -> Option<CrateId> {
|
pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
|
||||||
let cratedoc = ebml::Doc::new(data);
|
let cratedoc = ebml::Doc::new(data);
|
||||||
reader::maybe_get_doc(cratedoc, tag_crate_crateid).map(|doc| {
|
reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
|
||||||
from_str(doc.as_str_slice()).unwrap()
|
doc.as_str_slice().to_string()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_crate_triple(data: &[u8]) -> String {
|
pub fn get_crate_triple(data: &[u8]) -> Option<String> {
|
||||||
let cratedoc = ebml::Doc::new(data);
|
let cratedoc = ebml::Doc::new(data);
|
||||||
let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
|
let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
|
||||||
triple_doc.expect("No triple in crate").as_str().to_string()
|
triple_doc.map(|s| s.as_str().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_crate_id(data: &[u8]) -> CrateId {
|
pub fn get_crate_name(data: &[u8]) -> String {
|
||||||
let cratedoc = ebml::Doc::new(data);
|
maybe_get_crate_name(data).expect("no crate name in crate")
|
||||||
let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);
|
|
||||||
from_str(hashdoc.as_str_slice()).unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
||||||
|
|
|
@ -44,11 +44,9 @@ use syntax::ast_map::{PathElem, PathElems};
|
||||||
use syntax::ast_map;
|
use syntax::ast_map;
|
||||||
use syntax::ast_util::*;
|
use syntax::ast_util::*;
|
||||||
use syntax::ast_util;
|
use syntax::ast_util;
|
||||||
use syntax::attr::AttrMetaMethods;
|
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::crateid::CrateId;
|
use syntax::attr::AttrMetaMethods;
|
||||||
use syntax::diagnostic::SpanHandler;
|
use syntax::diagnostic::SpanHandler;
|
||||||
use syntax::parse::token::InternedString;
|
|
||||||
use syntax::parse::token::special_idents;
|
use syntax::parse::token::special_idents;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
use syntax::visit::Visitor;
|
use syntax::visit::Visitor;
|
||||||
|
@ -1494,35 +1492,6 @@ fn encode_attributes(ebml_w: &mut Encoder, attrs: &[Attribute]) {
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
// So there's a special crate attribute called 'crate_id' which defines the
|
|
||||||
// metadata that Rust cares about for linking crates. If the user didn't
|
|
||||||
// provide it we will throw it in anyway with a default value.
|
|
||||||
fn synthesize_crate_attrs(ecx: &EncodeContext,
|
|
||||||
krate: &Crate) -> Vec<Attribute> {
|
|
||||||
|
|
||||||
fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
|
|
||||||
assert!(!ecx.link_meta.crateid.name.is_empty());
|
|
||||||
|
|
||||||
attr::mk_attr_inner(attr::mk_attr_id(),
|
|
||||||
attr::mk_name_value_item_str(
|
|
||||||
InternedString::new("crate_id"),
|
|
||||||
token::intern_and_get_ident(ecx.link_meta
|
|
||||||
.crateid
|
|
||||||
.to_str()
|
|
||||||
.as_slice())))
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut attrs = Vec::new();
|
|
||||||
for attr in krate.attrs.iter() {
|
|
||||||
if !attr.check_name("crate_id") {
|
|
||||||
attrs.push(*attr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
attrs.push(synthesize_crateid_attr(ecx));
|
|
||||||
|
|
||||||
attrs
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encode_crate_deps(ebml_w: &mut Encoder, cstore: &cstore::CStore) {
|
fn encode_crate_deps(ebml_w: &mut Encoder, cstore: &cstore::CStore) {
|
||||||
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
|
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
|
||||||
// Pull the cnums and name,vers,hash out of cstore
|
// Pull the cnums and name,vers,hash out of cstore
|
||||||
|
@ -1530,8 +1499,8 @@ fn encode_crate_deps(ebml_w: &mut Encoder, cstore: &cstore::CStore) {
|
||||||
cstore.iter_crate_data(|key, val| {
|
cstore.iter_crate_data(|key, val| {
|
||||||
let dep = decoder::CrateDep {
|
let dep = decoder::CrateDep {
|
||||||
cnum: key,
|
cnum: key,
|
||||||
crate_id: decoder::get_crate_id(val.data()),
|
name: decoder::get_crate_name(val.data()),
|
||||||
hash: decoder::get_crate_hash(val.data())
|
hash: decoder::get_crate_hash(val.data()),
|
||||||
};
|
};
|
||||||
deps.push(dep);
|
deps.push(dep);
|
||||||
});
|
});
|
||||||
|
@ -1766,8 +1735,8 @@ fn encode_reachable_extern_fns(ecx: &EncodeContext, ebml_w: &mut Encoder) {
|
||||||
fn encode_crate_dep(ebml_w: &mut Encoder,
|
fn encode_crate_dep(ebml_w: &mut Encoder,
|
||||||
dep: decoder::CrateDep) {
|
dep: decoder::CrateDep) {
|
||||||
ebml_w.start_tag(tag_crate_dep);
|
ebml_w.start_tag(tag_crate_dep);
|
||||||
ebml_w.start_tag(tag_crate_dep_crateid);
|
ebml_w.start_tag(tag_crate_dep_crate_name);
|
||||||
ebml_w.writer.write(dep.crate_id.to_str().as_bytes());
|
ebml_w.writer.write(dep.name.as_bytes());
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
ebml_w.start_tag(tag_crate_dep_hash);
|
ebml_w.start_tag(tag_crate_dep_hash);
|
||||||
ebml_w.writer.write(dep.hash.as_str().as_bytes());
|
ebml_w.writer.write(dep.hash.as_str().as_bytes());
|
||||||
|
@ -1781,9 +1750,9 @@ fn encode_hash(ebml_w: &mut Encoder, hash: &Svh) {
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_crate_id(ebml_w: &mut Encoder, crate_id: &CrateId) {
|
fn encode_crate_name(ebml_w: &mut Encoder, crate_name: &str) {
|
||||||
ebml_w.start_tag(tag_crate_crateid);
|
ebml_w.start_tag(tag_crate_crate_name);
|
||||||
ebml_w.writer.write(crate_id.to_str().as_bytes());
|
ebml_w.writer.write(crate_name.as_bytes());
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1880,7 +1849,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
||||||
|
|
||||||
let mut ebml_w = writer::Encoder::new(wr);
|
let mut ebml_w = writer::Encoder::new(wr);
|
||||||
|
|
||||||
encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid);
|
encode_crate_name(&mut ebml_w, ecx.link_meta.crate_name.as_slice());
|
||||||
encode_crate_triple(&mut ebml_w,
|
encode_crate_triple(&mut ebml_w,
|
||||||
tcx.sess
|
tcx.sess
|
||||||
.targ_cfg
|
.targ_cfg
|
||||||
|
@ -1891,8 +1860,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
||||||
encode_dylib_dependency_formats(&mut ebml_w, &ecx);
|
encode_dylib_dependency_formats(&mut ebml_w, &ecx);
|
||||||
|
|
||||||
let mut i = ebml_w.writer.tell().unwrap();
|
let mut i = ebml_w.writer.tell().unwrap();
|
||||||
let crate_attrs = synthesize_crate_attrs(&ecx, krate);
|
encode_attributes(&mut ebml_w, krate.attrs.as_slice());
|
||||||
encode_attributes(&mut ebml_w, crate_attrs.as_slice());
|
|
||||||
stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;
|
stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;
|
||||||
|
|
||||||
i = ebml_w.writer.tell().unwrap();
|
i = ebml_w.writer.tell().unwrap();
|
||||||
|
|
|
@ -1373,15 +1373,15 @@ pub fn process_crate(sess: &Session,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (cratename, crateid) = match attr::find_crateid(krate.attrs.as_slice()) {
|
let cratename = match attr::find_crate_name(krate.attrs.as_slice()) {
|
||||||
Some(crateid) => (crateid.name.clone(), crateid.to_str()),
|
Some(name) => name.get().to_string(),
|
||||||
None => {
|
None => {
|
||||||
info!("Could not find crate name, using 'unknown_crate'");
|
info!("Could not find crate name, using 'unknown_crate'");
|
||||||
(String::from_str("unknown_crate"),"unknown_crate".to_owned())
|
String::from_str("unknown_crate")
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Dumping crate {} ({})", cratename, crateid);
|
info!("Dumping crate {}", cratename);
|
||||||
|
|
||||||
// find a path to dump our data to
|
// find a path to dump our data to
|
||||||
let mut root_path = match os::getenv("DXR_RUST_TEMP_FOLDER") {
|
let mut root_path = match os::getenv("DXR_RUST_TEMP_FOLDER") {
|
||||||
|
|
|
@ -30,7 +30,6 @@ use back::{link, abi};
|
||||||
use driver::config;
|
use driver::config;
|
||||||
use driver::config::{NoDebugInfo, FullDebugInfo};
|
use driver::config::{NoDebugInfo, FullDebugInfo};
|
||||||
use driver::session::Session;
|
use driver::session::Session;
|
||||||
use driver::driver::OutputFilenames;
|
|
||||||
use driver::driver::{CrateAnalysis, CrateTranslation};
|
use driver::driver::{CrateAnalysis, CrateTranslation};
|
||||||
use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
|
use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
|
||||||
use lib::llvm::{llvm, Vector};
|
use lib::llvm::{llvm, Vector};
|
||||||
|
@ -2270,8 +2269,9 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
|
||||||
}.as_slice());
|
}.as_slice());
|
||||||
let llmeta = C_bytes(cx, compressed.as_slice());
|
let llmeta = C_bytes(cx, compressed.as_slice());
|
||||||
let llconst = C_struct(cx, [llmeta], false);
|
let llconst = C_struct(cx, [llmeta], false);
|
||||||
let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,
|
let name = format!("rust_metadata_{}_{}",
|
||||||
cx.link_meta.crateid.version_or_default(), cx.link_meta.crate_hash);
|
cx.link_meta.crate_name,
|
||||||
|
cx.link_meta.crate_hash);
|
||||||
let llglobal = name.with_c_str(|buf| {
|
let llglobal = name.with_c_str(|buf| {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMAddGlobal(cx.metadata_llmod, val_ty(llconst).to_ref(), buf)
|
llvm::LLVMAddGlobal(cx.metadata_llmod, val_ty(llconst).to_ref(), buf)
|
||||||
|
@ -2288,9 +2288,8 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trans_crate(krate: ast::Crate,
|
pub fn trans_crate(krate: ast::Crate,
|
||||||
analysis: CrateAnalysis,
|
analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
|
||||||
output: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
|
let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
|
||||||
let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, .. } = analysis;
|
|
||||||
|
|
||||||
// Before we touch LLVM, make sure that multithreading is enabled.
|
// Before we touch LLVM, make sure that multithreading is enabled.
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -2310,8 +2309,7 @@ pub fn trans_crate(krate: ast::Crate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let link_meta = link::build_link_meta(&krate,
|
let link_meta = link::build_link_meta(&krate, name);
|
||||||
output.out_filestem.as_slice());
|
|
||||||
|
|
||||||
// Append ".rs" to crate name as LLVM module identifier.
|
// Append ".rs" to crate name as LLVM module identifier.
|
||||||
//
|
//
|
||||||
|
@ -2321,7 +2319,7 @@ pub fn trans_crate(krate: ast::Crate,
|
||||||
// crashes if the module identifier is same as other symbols
|
// crashes if the module identifier is same as other symbols
|
||||||
// such as a function name in the module.
|
// such as a function name in the module.
|
||||||
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
|
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
|
||||||
let mut llmod_id = link_meta.crateid.name.clone();
|
let mut llmod_id = link_meta.crate_name.clone();
|
||||||
llmod_id.push_str(".rs");
|
llmod_id.push_str(".rs");
|
||||||
|
|
||||||
let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
|
let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
|
||||||
|
|
|
@ -1496,7 +1496,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
|
||||||
});
|
});
|
||||||
|
|
||||||
fn fallback_path(cx: &CrateContext) -> CString {
|
fn fallback_path(cx: &CrateContext) -> CString {
|
||||||
cx.link_meta.crateid.name.as_slice().to_c_str()
|
cx.link_meta.crate_name.as_slice().to_c_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -566,7 +566,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext,
|
||||||
|
|
||||||
let ps = ccx.tcx.map.with_path(id, |path| {
|
let ps = ccx.tcx.map.with_path(id, |path| {
|
||||||
let abi = Some(ast_map::PathName(special_idents::clownshoe_abi.name));
|
let abi = Some(ast_map::PathName(special_idents::clownshoe_abi.name));
|
||||||
link::mangle(path.chain(abi.move_iter()), None, None)
|
link::mangle(path.chain(abi.move_iter()), None)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Compute the type that the function would have if it were just a
|
// Compute the type that the function would have if it were just a
|
||||||
|
|
|
@ -129,9 +129,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||||
hash_id.hash(&mut state);
|
hash_id.hash(&mut state);
|
||||||
mono_ty.hash(&mut state);
|
mono_ty.hash(&mut state);
|
||||||
|
|
||||||
exported_name(path,
|
exported_name(path, format!("h{}", state.result()).as_slice())
|
||||||
format!("h{}", state.result()).as_slice(),
|
|
||||||
ccx.link_meta.crateid.version_or_default())
|
|
||||||
});
|
});
|
||||||
debug!("monomorphize_fn mangled to {}", s);
|
debug!("monomorphize_fn mangled to {}", s);
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ use syntax::codemap;
|
||||||
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
|
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
|
||||||
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
|
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::crateid::CrateId;
|
|
||||||
use util::ppaux::{ty_to_str, UserString};
|
use util::ppaux::{ty_to_str, UserString};
|
||||||
|
|
||||||
struct Env<'a> {
|
struct Env<'a> {
|
||||||
|
@ -116,11 +115,8 @@ fn test_env(_test_name: &str,
|
||||||
let krate_config = Vec::new();
|
let krate_config = Vec::new();
|
||||||
let input = driver::StrInput(source_string.to_owned());
|
let input = driver::StrInput(source_string.to_owned());
|
||||||
let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
|
let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
|
||||||
let krate_id = CrateId { path: "test".to_owned(),
|
|
||||||
name: "test".to_owned(),
|
|
||||||
version: None };
|
|
||||||
let (krate, ast_map) =
|
let (krate, ast_map) =
|
||||||
driver::phase_2_configure_and_expand(&sess, krate, &krate_id)
|
driver::phase_2_configure_and_expand(&sess, krate, "test")
|
||||||
.expect("phase 2 aborted");
|
.expect("phase 2 aborted");
|
||||||
|
|
||||||
// run just enough stuff to build a tcx:
|
// run just enough stuff to build a tcx:
|
||||||
|
|
|
@ -124,8 +124,9 @@ impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
|
||||||
&None,
|
&None,
|
||||||
self.attrs.as_slice(),
|
self.attrs.as_slice(),
|
||||||
cx.sess());
|
cx.sess());
|
||||||
let id = link::find_crate_id(self.attrs.as_slice(),
|
let name = link::find_crate_name(None,
|
||||||
t_outputs.out_filestem.as_slice());
|
self.attrs.as_slice(),
|
||||||
|
t_outputs.out_filestem.as_slice());
|
||||||
|
|
||||||
// Clean the crate, translating the entire libsyntax AST to one that is
|
// Clean the crate, translating the entire libsyntax AST to one that is
|
||||||
// understood by rustdoc.
|
// understood by rustdoc.
|
||||||
|
@ -188,7 +189,7 @@ impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Crate {
|
Crate {
|
||||||
name: id.name.to_string(),
|
name: name.to_string(),
|
||||||
module: Some(module),
|
module: Some(module),
|
||||||
externs: externs,
|
externs: externs,
|
||||||
primitives: primitives,
|
primitives: primitives,
|
||||||
|
|
|
@ -12,6 +12,7 @@ use rustc;
|
||||||
use rustc::{driver, middle};
|
use rustc::{driver, middle};
|
||||||
use rustc::middle::{privacy, ty};
|
use rustc::middle::{privacy, ty};
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
|
use rustc::back::link;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
@ -83,7 +84,8 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
|
||||||
use rustc::driver::driver::{FileInput,
|
use rustc::driver::driver::{FileInput,
|
||||||
phase_1_parse_input,
|
phase_1_parse_input,
|
||||||
phase_2_configure_and_expand,
|
phase_2_configure_and_expand,
|
||||||
phase_3_run_analysis_passes};
|
phase_3_run_analysis_passes,
|
||||||
|
build_output_filenames};
|
||||||
use rustc::driver::config::build_configuration;
|
use rustc::driver::config::build_configuration;
|
||||||
|
|
||||||
let input = FileInput(cpath.clone());
|
let input = FileInput(cpath.clone());
|
||||||
|
@ -115,13 +117,19 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>)
|
||||||
}
|
}
|
||||||
|
|
||||||
let krate = phase_1_parse_input(&sess, cfg, &input);
|
let krate = phase_1_parse_input(&sess, cfg, &input);
|
||||||
|
|
||||||
|
let t_outputs = build_output_filenames(&input, &None, &None,
|
||||||
|
krate.attrs.as_slice(), &sess);
|
||||||
|
let name = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
|
||||||
|
t_outputs.out_filestem.as_slice());
|
||||||
|
|
||||||
let (krate, ast_map)
|
let (krate, ast_map)
|
||||||
= phase_2_configure_and_expand(&sess, krate, &from_str("rustdoc").unwrap())
|
= phase_2_configure_and_expand(&sess, krate, name.as_slice())
|
||||||
.expect("phase_2_configure_and_expand aborted in rustdoc!");
|
.expect("phase_2_configure_and_expand aborted in rustdoc!");
|
||||||
|
|
||||||
let driver::driver::CrateAnalysis {
|
let driver::driver::CrateAnalysis {
|
||||||
exported_items, public_items, ty_cx, ..
|
exported_items, public_items, ty_cx, ..
|
||||||
} = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
} = phase_3_run_analysis_passes(sess, &krate, ast_map, name);
|
||||||
|
|
||||||
debug!("crate: {:?}", krate);
|
debug!("crate: {:?}", krate);
|
||||||
(DocContext {
|
(DocContext {
|
||||||
|
|
|
@ -8,12 +8,14 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![crate_id = "rustdoc#0.11.0"]
|
#![crate_id = "rustdoc#0.11.0"] // NOTE: remove after stage0
|
||||||
|
#![crate_name = "rustdoc"]
|
||||||
#![experimental]
|
#![experimental]
|
||||||
#![desc = "rustdoc, the Rust documentation extractor"]
|
#![desc = "rustdoc, the Rust documentation extractor"]
|
||||||
#![license = "MIT/ASL2"]
|
#![license = "MIT/ASL2"]
|
||||||
#![crate_type = "dylib"]
|
#![crate_type = "dylib"]
|
||||||
#![crate_type = "rlib"]
|
#![crate_type = "rlib"]
|
||||||
|
#![allow(unused_attribute)] // NOTE: remove after stage0
|
||||||
|
|
||||||
#![feature(globs, struct_variant, managed_boxes, macro_rules, phase)]
|
#![feature(globs, struct_variant, managed_boxes, macro_rules, phase)]
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ pub fn run(input: &str,
|
||||||
}));
|
}));
|
||||||
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
|
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
|
||||||
let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
|
let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
|
||||||
&from_str("rustdoc-test").unwrap())
|
"rustdoc-test")
|
||||||
.expect("phase_2_configure_and_expand aborted in rustdoc!");
|
.expect("phase_2_configure_and_expand aborted in rustdoc!");
|
||||||
|
|
||||||
let ctx = box(GC) core::DocContext {
|
let ctx = box(GC) core::DocContext {
|
||||||
|
|
|
@ -18,7 +18,6 @@ use diagnostic::SpanHandler;
|
||||||
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
|
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
|
||||||
use parse::token::InternedString;
|
use parse::token::InternedString;
|
||||||
use parse::token;
|
use parse::token;
|
||||||
use crateid::CrateId;
|
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::collections::BitvSet;
|
use std::collections::BitvSet;
|
||||||
|
@ -271,11 +270,8 @@ pub fn sort_meta_items(items: &[Gc<MetaItem>]) -> Vec<Gc<MetaItem>> {
|
||||||
}).collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_crateid(attrs: &[Attribute]) -> Option<CrateId> {
|
pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
|
||||||
match first_attr_value_str_by_name(attrs, "crate_id") {
|
first_attr_value_str_by_name(attrs, "crate_name")
|
||||||
None => None,
|
|
||||||
Some(id) => from_str::<CrateId>(id.get()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(PartialEq)]
|
#[deriving(PartialEq)]
|
||||||
|
|
|
@ -452,7 +452,7 @@ impl<'a> ExtCtxt<'a> {
|
||||||
pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
|
pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
|
||||||
pub fn mod_path(&self) -> Vec<ast::Ident> {
|
pub fn mod_path(&self) -> Vec<ast::Ident> {
|
||||||
let mut v = Vec::new();
|
let mut v = Vec::new();
|
||||||
v.push(token::str_to_ident(self.ecfg.crate_id.name.as_slice()));
|
v.push(token::str_to_ident(self.ecfg.crate_name.as_slice()));
|
||||||
v.extend(self.mod_path.iter().map(|a| *a));
|
v.extend(self.mod_path.iter().map(|a| *a));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ use attr;
|
||||||
use attr::AttrMetaMethods;
|
use attr::AttrMetaMethods;
|
||||||
use codemap;
|
use codemap;
|
||||||
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
|
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
|
||||||
use crateid::CrateId;
|
|
||||||
use ext::base::*;
|
use ext::base::*;
|
||||||
use fold;
|
use fold;
|
||||||
use fold::*;
|
use fold::*;
|
||||||
|
@ -985,7 +984,7 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
|
||||||
|
|
||||||
pub struct ExpansionConfig {
|
pub struct ExpansionConfig {
|
||||||
pub deriving_hash_type_parameter: bool,
|
pub deriving_hash_type_parameter: bool,
|
||||||
pub crate_id: CrateId,
|
pub crate_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExportedMacros {
|
pub struct ExportedMacros {
|
||||||
|
@ -1184,7 +1183,7 @@ mod test {
|
||||||
// should fail:
|
// should fail:
|
||||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_name: "test".to_str(),
|
||||||
};
|
};
|
||||||
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
||||||
}
|
}
|
||||||
|
@ -1201,7 +1200,7 @@ mod test {
|
||||||
Vec::new(), &sess);
|
Vec::new(), &sess);
|
||||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_name: "test".to_str(),
|
||||||
};
|
};
|
||||||
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
|
||||||
}
|
}
|
||||||
|
@ -1217,7 +1216,7 @@ mod test {
|
||||||
Vec::new(), &sess);
|
Vec::new(), &sess);
|
||||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_name: "test".to_str(),
|
||||||
};
|
};
|
||||||
expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
|
expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
|
||||||
}
|
}
|
||||||
|
@ -1254,7 +1253,7 @@ mod test {
|
||||||
// the cfg argument actually does matter, here...
|
// the cfg argument actually does matter, here...
|
||||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||||
deriving_hash_type_parameter: false,
|
deriving_hash_type_parameter: false,
|
||||||
crate_id: from_str("test").unwrap(),
|
crate_name: "test".to_str(),
|
||||||
};
|
};
|
||||||
expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
|
expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue