use lib::llvm::ModuleRef;
use lib;
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::common::gensym_name;
use middle::ty;
use syntax::ast;
use syntax::ast_map::{PathElem, PathElems, PathName};
use syntax::ast_map;
-use syntax::attr;
use syntax::attr::AttrMetaMethods;
-use syntax::crateid::CrateId;
+use syntax::codemap::Span;
use syntax::parse::token;
#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
*/
// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
-pub fn find_crate_id(attrs: &[ast::Attribute], out_filestem: &str) -> CrateId {
- match attr::find_crateid(attrs) {
- None => 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()
- }),
- Some(s) => s,
+pub fn find_crate_name(sess: Option<&Session>,
+ attrs: &[ast::Attribute],
+ out_filestem: &str) -> String {
+ use syntax::crateid::CrateId;
+
+ let validate = |s: String, span: Option<Span>| {
+ creader::validate_crate_name(sess, s.as_slice(), span);
+ 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
// the crate id in the hash because lookups are only done by (name/vers),
// not by path.
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, out_filestem: &str) -> LinkMeta {
+pub fn build_link_meta(krate: &ast::Crate, name: String) -> LinkMeta {
let r = LinkMeta {
- crateid: find_crate_id(krate.attrs.as_slice(), out_filestem),
+ crate_name: name,
crate_hash: Svh::calculate(krate),
};
info!("{}", r);
// to be independent of one another in the crate.
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(link_meta.crate_hash.as_str());
symbol_hasher.input_str("-");
}
pub fn mangle<PI: Iterator<PathElem>>(mut path: PI,
- hash: Option<&str>,
- vers: Option<&str>) -> String {
+ hash: Option<&str>) -> String {
// Follow C++ namespace-mangling style, see
// http://en.wikipedia.org/wiki/Name_mangling for more info.
//
Some(s) => push(&mut n, s),
None => {}
}
- match vers {
- Some(s) => push(&mut n, s),
- None => {}
- }
n.push_char('E'); // End name-sequence.
n
}
-pub fn exported_name(path: PathElems, hash: &str, vers: &str) -> String {
- // The version will get mangled to have a leading '_', but it makes more
- // 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 exported_name(path: PathElems, hash: &str) -> String {
+ mangle(path, Some(hash))
}
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()[extra3] as char);
- exported_name(path,
- hash.as_slice(),
- ccx.link_meta.crateid.version_or_default())
+ exported_name(path, hash.as_slice())
}
pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
let path = [PathName(token::intern(s.as_slice())),
gensym_name(name)];
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 {
- mangle(path.chain(Some(gensym_name(flav)).move_iter()), None, None)
-}
-
-pub fn output_lib_filename(id: &CrateId) -> String {
- format!("{}-{}-{}", id.name, crate_id_hash(id), id.version_or_default())
+ mangle(path.chain(Some(gensym_name(flav)).move_iter()), None)
}
pub fn get_cc_prog(sess: &Session) -> String {
pub fn link_binary(sess: &Session,
trans: &CrateTranslation,
outputs: &OutputFilenames,
- id: &CrateId) -> Vec<Path> {
+ crate_name: &str) -> Vec<Path> {
let mut out_filenames = Vec::new();
for &crate_type in sess.crate_types.borrow().iter() {
if invalid_output_for_target(sess, crate_type) {
sess.bug(format!("invalid output type `{}` for target os `{}`",
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);
}
}
}
-pub fn filename_for_input(sess: &Session, crate_type: config::CrateType,
- id: &CrateId, out_filename: &Path) -> Path {
- let libname = output_lib_filename(id);
+pub fn filename_for_input(sess: &Session,
+ crate_type: config::CrateType,
+ name: &str,
+ out_filename: &Path) -> Path {
+ let libname = format!("{}-{}", name, crate_name_hash(sess, name));
match crate_type {
config::CrateTypeRlib => {
out_filename.with_filename(format!("lib{}.rlib", libname))
trans: &CrateTranslation,
crate_type: config::CrateType,
outputs: &OutputFilenames,
- id: &CrateId) -> Path {
+ crate_name: &str) -> Path {
let obj_filename = outputs.temp_path(OutputTypeObject);
let out_filename = match outputs.single_output_file {
Some(ref file) => file.clone(),
None => {
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)
}
};
pub debugging_opts: u64,
/// Whether to write dependency files. It's (enabled, optional filename).
pub write_dependency_info: (bool, Option<Path>),
- /// Crate id-related things to maybe print. It's (crate_id, crate_name, crate_file_name).
- pub print_metas: (bool, bool, bool),
+ /// Crate id-related things to maybe print. It's (crate_name, crate_file_name).
+ pub print_metas: (bool, bool),
pub cg: CodegenOptions,
pub color: ColorConfig,
}
no_analysis: false,
debugging_opts: 0,
write_dependency_info: (false, None),
- print_metas: (false, false, false),
+ print_metas: (false, false),
cg: basic_codegen_options(),
color: Auto,
}
"[bin|lib|rlib|dylib|staticlib]"),
optmulti("", "emit", "Comma separated list of types of output for the compiler to emit",
"[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-file-name", "Output the file(s) that would be written if compilation \
continued and exit"),
matches.opt_str("dep-info")
.map(|p| Path::new(p)));
- let print_metas = (matches.opt_present("crate-id"),
- matches.opt_present("crate-name"),
+ let print_metas = (matches.opt_present("crate-name"),
matches.opt_present("crate-file-name"));
let cg = build_codegen_options(matches);
use syntax::ast;
use syntax::attr;
use syntax::attr::{AttrMetaMethods};
-use syntax::crateid::CrateId;
use syntax::parse;
use syntax::parse::token;
use syntax::print::{pp, pprust};
// large chunks of memory alive and we want to free them as soon as
// possible to keep the peak memory usage low
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);
if stop_after_phase_1(&sess) { return; }
let outputs = build_output_filenames(input,
output,
krate.attrs.as_slice(),
&sess);
- let id = link::find_crate_id(krate.attrs.as_slice(),
- outputs.out_filestem.as_slice());
+ let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
+ outputs.out_filestem.as_slice());
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,
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; }
- 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);
if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
- let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate,
- analysis, &outputs);
+ let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate, analysis);
// Discard interned strings as they are no longer required.
token::get_ident_interner().clear();
/// Returns `None` if we're aborting after handling -W help.
pub fn phase_2_configure_and_expand(sess: &Session,
mut krate: ast::Crate,
- crate_id: &CrateId)
+ crate_name: &str)
-> Option<(ast::Crate, syntax::ast_map::Map)> {
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", (), |_|
front::feature_gate::check_crate(sess, &krate));
}
let cfg = syntax::ext::expand::ExpansionConfig {
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,
cfg,
pub public_items: middle::privacy::PublicItems,
pub ty_cx: ty::ctxt,
pub reachable: NodeSet,
+ pub name: String,
}
/// Run the resolution, typechecking, region checking and other
/// structures carrying the results of the analysis.
pub fn phase_3_run_analysis_passes(sess: Session,
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();
exported_items: exported_items,
public_items: public_items,
reachable: reachable_map,
+ name: name,
}
}
/// Run the translation phase to LLVM, after which the AST and analysis can
/// be discarded.
pub fn phase_4_translate_to_llvm(krate: ast::Crate,
- analysis: CrateAnalysis,
- outputs: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
+ analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
let time_passes = analysis.ty_cx.sess.time_passes();
time(time_passes, "resolving dependency formats", (), |_|
// Option dance to work around the lack of stack once closures.
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
link::link_binary(sess,
trans,
outputs,
- &trans.link.crateid));
+ trans.link.crate_name.as_slice()));
}
pub fn stop_after_phase_3(sess: &Session) -> bool {
fn write_out_deps(sess: &Session,
input: &Input,
outputs: &OutputFilenames,
- krate: &ast::Crate) {
- let id = link::find_crate_id(krate.attrs.as_slice(),
- outputs.out_filestem.as_slice());
+ id: &str) {
let mut out_filenames = Vec::new();
for output_type in sess.opts.output_types.iter() {
match *output_type {
link::OutputTypeExe => {
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);
}
}
ppm: PpMode,
ofile: Option<Path>) {
let krate = phase_1_parse_input(&sess, cfg, input);
- let id = link::find_crate_id(krate.attrs.as_slice(),
- input.filestem().as_slice());
+ let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
+ input.filestem().as_slice());
let (krate, ast_map, is_expanded) = match ppm {
PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
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,
Some(p) => p,
};
}
PpmTyped => {
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 {
analysis: analysis
};
}
}
};
- 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)
}
_ => {
let mut stem = input.filestem();
- // If a crateid is present, we use it as the link name
- let crateid = attr::find_crateid(attrs);
- match crateid {
+ // If a crate name is present, we use it as the link name
+ match attr::find_crate_name(attrs) {
None => {}
- Some(crateid) => stem = crateid.name.to_string(),
+ Some(name) => stem = name.get().to_string(),
}
OutputFilenames {
out_directory: dirpath,
odir: &Option<Path>,
ofile: &Option<Path>)
-> 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
- if crate_id || crate_name || crate_file_name {
+ if crate_name || crate_file_name {
let attrs = parse_crate_attrs(sess, input);
let t_outputs = driver::build_output_filenames(input,
odir,
ofile,
attrs.as_slice(),
sess);
- let id = link::find_crate_id(attrs.as_slice(),
- t_outputs.out_filestem.as_slice());
+ let id = link::find_crate_name(Some(sess), attrs.as_slice(),
+ t_outputs.out_filestem.as_slice());
- if crate_id {
- println!("{}", id.to_str());
- }
if crate_name {
- println!("{}", id.name);
+ println!("{}", id);
}
if crate_file_name {
let crate_types = driver::collect_crate_types(sess, attrs.as_slice());
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(""));
println!("{}", fname.filename_display());
}
use std::mem;
use std::gc::{Gc, GC};
-pub static VERSION: &'static str = "0.11.0";
-
pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
-> ast::Crate {
if use_std(&krate) {
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> {
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
let mut vis = vec!(ast::ViewItem {
node: ast::ViewItemExternCrate(token::str_to_ident("std"),
- with_version("std"),
- ast::DUMMY_NODE_ID),
+ None,
+ ast::DUMMY_NODE_ID),
attrs: vec!(
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
InternedString::new("phase"),
if use_start(&krate) && any_exe {
vis.push(ast::ViewItem {
node: ast::ViewItemExternCrate(token::str_to_ident("native"),
- with_version("native"),
- ast::DUMMY_NODE_ID),
+ None,
+ ast::DUMMY_NODE_ID),
attrs: Vec::new(),
vis: ast::Inherited,
span: DUMMY_SP
use driver::session::Session;
use front::config;
-use front::std_inject::with_version;
use std::cell::RefCell;
use std::gc::{Gc, GC};
ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_string(),
}),
path: RefCell::new(Vec::new()),
testfns: RefCell::new(Vec::new()),
ast::DUMMY_NODE_ID))),
ast::Public)
} else {
- (ast::ViewItemExternCrate(id_test,
- with_version("test"),
- ast::DUMMY_NODE_ID),
+ (ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
ast::Inherited)
};
ast::ViewItem {
}
fn is_test_crate(krate: &ast::Crate) -> bool {
- match attr::find_crateid(krate.attrs.as_slice()) {
- Some(ref s) if "test" == s.name.as_slice() => true,
+ match attr::find_crate_name(krate.attrs.as_slice()) {
+ Some(ref s) if "test" == s.get().as_slice() => true,
_ => false
}
}
#![allow(non_camel_case_types)]
use std::mem;
-use syntax::crateid::CrateId;
use back::svh::Svh;
// EBML enum definitions and utils shared by the encoder and decoder
pub static tag_crate_dep: uint = 0x19;
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_mod_impl: uint = 0x1f;
#[deriving(Clone, Show)]
pub struct LinkMeta {
- pub crateid: CrateId,
+ pub crate_name: String,
pub crate_hash: Svh,
}
//! Validates all used crates and extern libraries and loads their metadata
-use back::link;
use back::svh::Svh;
use driver::session::Session;
use driver::{driver, config};
use syntax::diagnostic::SpanHandler;
use syntax::parse::token::InternedString;
use syntax::parse::token;
-use syntax::crateid::CrateId;
use syntax::visit;
struct Env<'a> {
fn dump_crates(cstore: &CStore) {
debug!("resolved crates:");
cstore.iter_crate_data_origins(|_, data, opt_source| {
- debug!("crate_id: {}", data.crate_id());
+ debug!(" name: {}", data.name());
debug!(" cnum: {}", data.cnum);
debug!(" hash: {}", data.hash());
opt_source.map(|cs| {
fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
let mut map = HashMap::new();
cstore.iter_crate_data(|cnum, data| {
- let crateid = data.crate_id();
- let key = (crateid.name.clone(), crateid.path.clone());
- map.find_or_insert_with(key, |_| Vec::new()).push(cnum);
+ map.find_or_insert_with(data.name(), |_| Vec::new()).push(cnum);
});
- for ((name, _), dupes) in map.move_iter() {
+ for (name, dupes) in map.move_iter() {
if dupes.len() == 1 { continue }
diag.handler().warn(
- format!("using multiple versions of crate `{}`",
- name).as_slice());
+ format!("using multiple versions of crate `{}`", name).as_slice());
for dupe in dupes.move_iter() {
let data = cstore.get_crate_data(dupe);
diag.span_note(data.span, "used here");
- loader::note_crateid_attr(diag, &data.crate_id());
+ loader::note_crate_name(diag, data.name().as_slice());
}
}
}
let (cnum, _, _) = resolve_crate(e,
&None,
info.ident.as_slice(),
- &info.crate_id,
+ info.name.as_slice(),
None,
i.span);
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
struct CrateInfo {
ident: String,
- crate_id: CrateId,
+ name: String,
id: ast::NodeId,
should_link: bool,
}
let ident = token::get_ident(ident);
debug!("resolving extern crate stmt. ident: {:?} path_opt: {:?}",
ident, path_opt);
- let crate_id = match *path_opt {
+ let name = match *path_opt {
Some((ref path_str, _)) => {
- let crateid: Option<CrateId> = from_str(path_str.get());
- match crateid {
- None => {
- e.sess.span_err(i.span, "malformed crate id");
- return None
- }
- Some(id) => id
- }
+ let name = path_str.get().to_str();
+ validate_crate_name(Some(e.sess), name.as_slice(),
+ Some(i.span));
+ name
}
- None => from_str(ident.get().to_str().as_slice()).unwrap()
+ None => ident.get().to_str(),
};
Some(CrateInfo {
ident: ident.get().to_string(),
- crate_id: crate_id,
+ name: name,
id: id,
should_link: should_link(i),
})
}
}
+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) {
match i.node {
ast::ItemForeignMod(ref fm) => {
}
}
-fn existing_match(e: &Env, crate_id: &CrateId,
+fn existing_match(e: &Env, name: &str,
hash: Option<&Svh>) -> Option<ast::CrateNum> {
let mut ret = None;
e.sess.cstore.iter_crate_data(|cnum, data| {
- let other_id = data.crate_id();
- if crate_id.matches(&other_id) {
+ if data.name().as_slice() == name {
let other_hash = data.hash();
match hash {
Some(hash) if *hash != other_hash => {}
fn register_crate<'a>(e: &mut Env,
root: &Option<CratePaths>,
ident: &str,
- crate_id: &CrateId,
+ name: &str,
span: Span,
lib: loader::Library)
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
let loader::Library{ dylib, rlib, metadata } = lib;
let cmeta = Rc::new( cstore::crate_metadata {
- name: crate_id.name.to_string(),
+ name: name.to_string(),
data: metadata,
cnum_map: cnum_map,
cnum: cnum,
fn resolve_crate<'a>(e: &mut Env,
root: &Option<CratePaths>,
ident: &str,
- crate_id: &CrateId,
+ name: &str,
hash: Option<&Svh>,
span: Span)
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
cstore::CrateSource) {
- match existing_match(e, crate_id, hash) {
+ match existing_match(e, name, hash) {
None => {
- let id_hash = link::crate_id_hash(crate_id);
let mut load_ctxt = loader::Context {
sess: e.sess,
span: span,
ident: ident,
- crate_id: crate_id,
- id_hash: id_hash.as_slice(),
+ crate_name: name,
hash: hash.map(|a| &*a),
filesearch: e.sess.target_filesearch(),
os: e.sess.targ_cfg.os,
rejected_via_triple: vec!(),
};
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,
e.sess.cstore.get_crate_data(cnum),
// The map from crate numbers in the crate we're resolving to local crate
// numbers
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,
- dep.crate_id.name.as_slice(),
- &dep.crate_id,
+ dep.name.as_slice(),
+ dep.name.as_slice(),
Some(&dep.hash),
span);
(dep.cnum, local_cnum)
let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
let is_cross = target_triple != driver::host_triple();
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 mut load_ctxt = loader::Context {
sess: self.env.sess,
span: krate.span,
ident: info.ident.as_slice(),
- crate_id: &info.crate_id,
- id_hash: id_hash.as_slice(),
+ crate_name: info.name.as_slice(),
hash: None,
filesearch: self.env.sess.host_filesearch(),
triple: driver::host_triple(),
macros: macros,
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(&mut self.env, &None, info.ident.as_slice(),
- &info.crate_id, krate.span, library);
+ info.name.as_slice(), krate.span, library);
}
pc
}
use std::rc::Rc;
use std::collections::HashMap;
use syntax::ast;
-use syntax::crateid::CrateId;
use syntax::codemap::Span;
use syntax::parse::token::IdentInterner;
impl crate_metadata {
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()) }
}
use syntax::print::pprust;
use syntax::ast;
use syntax::codemap;
-use syntax::crateid::CrateId;
pub type Cmd<'a> = &'a crate_metadata;
#[deriving(Clone)]
pub struct CrateDep {
pub cnum: ast::CrateNum,
- pub crate_id: CrateId,
+ pub name: String,
pub hash: Svh,
}
d.as_str_slice().to_string()
}
reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
- let crate_id =
- from_str(docstr(depdoc,
- tag_crate_dep_crateid).as_slice()).unwrap();
+ let name = docstr(depdoc, tag_crate_dep_crate_name);
let hash = Svh::new(docstr(depdoc, tag_crate_dep_hash).as_slice());
deps.push(CrateDep {
cnum: crate_num,
- crate_id: crate_id,
+ name: name,
hash: hash,
});
crate_num += 1;
fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
try!(write!(out, "=External Dependencies=\n"));
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"));
Ok(())
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);
- reader::maybe_get_doc(cratedoc, tag_crate_crateid).map(|doc| {
- from_str(doc.as_str_slice()).unwrap()
+ reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
+ 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 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 {
- let cratedoc = ebml::Doc::new(data);
- let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);
- from_str(hashdoc.as_str_slice()).unwrap()
+pub fn get_crate_name(data: &[u8]) -> String {
+ maybe_get_crate_name(data).expect("no crate name in crate")
}
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
use syntax::ast_map;
use syntax::ast_util::*;
use syntax::ast_util;
-use syntax::attr::AttrMetaMethods;
use syntax::attr;
-use syntax::crateid::CrateId;
+use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::SpanHandler;
-use syntax::parse::token::InternedString;
use syntax::parse::token::special_idents;
use syntax::parse::token;
use syntax::visit::Visitor;
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 get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
// Pull the cnums and name,vers,hash out of cstore
cstore.iter_crate_data(|key, val| {
let dep = decoder::CrateDep {
cnum: key,
- crate_id: decoder::get_crate_id(val.data()),
- hash: decoder::get_crate_hash(val.data())
+ name: decoder::get_crate_name(val.data()),
+ hash: decoder::get_crate_hash(val.data()),
};
deps.push(dep);
});
fn encode_crate_dep(ebml_w: &mut Encoder,
dep: decoder::CrateDep) {
ebml_w.start_tag(tag_crate_dep);
- ebml_w.start_tag(tag_crate_dep_crateid);
- ebml_w.writer.write(dep.crate_id.to_str().as_bytes());
+ ebml_w.start_tag(tag_crate_dep_crate_name);
+ ebml_w.writer.write(dep.name.as_bytes());
ebml_w.end_tag();
ebml_w.start_tag(tag_crate_dep_hash);
ebml_w.writer.write(dep.hash.as_str().as_bytes());
ebml_w.end_tag();
}
-fn encode_crate_id(ebml_w: &mut Encoder, crate_id: &CrateId) {
- ebml_w.start_tag(tag_crate_crateid);
- ebml_w.writer.write(crate_id.to_str().as_bytes());
+fn encode_crate_name(ebml_w: &mut Encoder, crate_name: &str) {
+ ebml_w.start_tag(tag_crate_crate_name);
+ ebml_w.writer.write(crate_name.as_bytes());
ebml_w.end_tag();
}
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,
tcx.sess
.targ_cfg
encode_dylib_dependency_formats(&mut ebml_w, &ecx);
let mut i = ebml_w.writer.tell().unwrap();
- let crate_attrs = synthesize_crate_attrs(&ecx, krate);
- encode_attributes(&mut ebml_w, crate_attrs.as_slice());
+ encode_attributes(&mut ebml_w, krate.attrs.as_slice());
stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;
i = ebml_w.writer.tell().unwrap();
return;
}
- let (cratename, crateid) = match attr::find_crateid(krate.attrs.as_slice()) {
- Some(crateid) => (crateid.name.clone(), crateid.to_str()),
+ let cratename = match attr::find_crate_name(krate.attrs.as_slice()) {
+ Some(name) => name.get().to_string(),
None => {
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
let mut root_path = match os::getenv("DXR_RUST_TEMP_FOLDER") {
use driver::config;
use driver::config::{NoDebugInfo, FullDebugInfo};
use driver::session::Session;
-use driver::driver::OutputFilenames;
use driver::driver::{CrateAnalysis, CrateTranslation};
use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
use lib::llvm::{llvm, Vector};
}.as_slice());
let llmeta = C_bytes(cx, compressed.as_slice());
let llconst = C_struct(cx, [llmeta], false);
- let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,
- cx.link_meta.crateid.version_or_default(), cx.link_meta.crate_hash);
+ let name = format!("rust_metadata_{}_{}",
+ cx.link_meta.crate_name,
+ cx.link_meta.crate_hash);
let llglobal = name.with_c_str(|buf| {
unsafe {
llvm::LLVMAddGlobal(cx.metadata_llmod, val_ty(llconst).to_ref(), buf)
}
pub fn trans_crate(krate: ast::Crate,
- analysis: CrateAnalysis,
- output: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
- let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, .. } = analysis;
+ analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
+ let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
// Before we touch LLVM, make sure that multithreading is enabled.
unsafe {
}
}
- let link_meta = link::build_link_meta(&krate,
- output.out_filestem.as_slice());
+ let link_meta = link::build_link_meta(&krate, name);
// Append ".rs" to crate name as LLVM module identifier.
//
// crashes if the module identifier is same as other symbols
// such as a function name in the module.
// 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");
let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
});
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()
}
}
let ps = ccx.tcx.map.with_path(id, |path| {
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
hash_id.hash(&mut state);
mono_ty.hash(&mut state);
- exported_name(path,
- format!("h{}", state.result()).as_slice(),
- ccx.link_meta.crateid.version_or_default())
+ exported_name(path, format!("h{}", state.result()).as_slice())
});
debug!("monomorphize_fn mangled to {}", s);
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
use syntax::ast;
-use syntax::crateid::CrateId;
use util::ppaux::{ty_to_str, UserString};
struct Env<'a> {
let krate_config = Vec::new();
let input = driver::StrInput(source_string.to_owned());
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) =
- driver::phase_2_configure_and_expand(&sess, krate, &krate_id)
+ driver::phase_2_configure_and_expand(&sess, krate, "test")
.expect("phase 2 aborted");
// run just enough stuff to build a tcx:
&None,
self.attrs.as_slice(),
cx.sess());
- let id = link::find_crate_id(self.attrs.as_slice(),
- t_outputs.out_filestem.as_slice());
+ let name = link::find_crate_name(None,
+ self.attrs.as_slice(),
+ t_outputs.out_filestem.as_slice());
// Clean the crate, translating the entire libsyntax AST to one that is
// understood by rustdoc.
}
Crate {
- name: id.name.to_string(),
+ name: name.to_string(),
module: Some(module),
externs: externs,
primitives: primitives,
use rustc::{driver, middle};
use rustc::middle::{privacy, ty};
use rustc::lint;
+use rustc::back::link;
use syntax::ast;
use syntax::parse::token;
use rustc::driver::driver::{FileInput,
phase_1_parse_input,
phase_2_configure_and_expand,
- phase_3_run_analysis_passes};
+ phase_3_run_analysis_passes,
+ build_output_filenames};
use rustc::driver::config::build_configuration;
let input = FileInput(cpath.clone());
}
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)
- = 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!");
let driver::driver::CrateAnalysis {
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);
(DocContext {
// option. This file may not be copied, modified, or distributed
// 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]
#![desc = "rustdoc, the Rust documentation extractor"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
+#![allow(unused_attribute)] // NOTE: remove after stage0
#![feature(globs, struct_variant, managed_boxes, macro_rules, phase)]
}));
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
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!");
let ctx = box(GC) core::DocContext {
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use parse::token::InternedString;
use parse::token;
-use crateid::CrateId;
use std::collections::HashSet;
use std::collections::BitvSet;
}).collect()
}
-pub fn find_crateid(attrs: &[Attribute]) -> Option<CrateId> {
- match first_attr_value_str_by_name(attrs, "crate_id") {
- None => None,
- Some(id) => from_str::<CrateId>(id.get()),
- }
+pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
+ first_attr_value_str_by_name(attrs, "crate_name")
}
#[deriving(PartialEq)]
pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
pub fn mod_path(&self) -> Vec<ast::Ident> {
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));
return v;
}
use attr::AttrMetaMethods;
use codemap;
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
-use crateid::CrateId;
use ext::base::*;
use fold;
use fold::*;
pub struct ExpansionConfig {
pub deriving_hash_type_parameter: bool,
- pub crate_id: CrateId,
+ pub crate_name: String,
}
pub struct ExportedMacros {
// should fail:
let cfg = ::syntax::ext::expand::ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_str(),
};
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
}
Vec::new(), &sess);
let cfg = ::syntax::ext::expand::ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_str(),
};
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
}
Vec::new(), &sess);
let cfg = ::syntax::ext::expand::ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_str(),
};
expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
}
// the cfg argument actually does matter, here...
let cfg = ::syntax::ext::expand::ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_str(),
};
expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
}