Skip to content

Commit

Permalink
Refactored ast_map and friends, mainly to have Paths without storing …
Browse files Browse the repository at this point in the history
…them.
  • Loading branch information
eddyb committed Feb 14, 2014
1 parent 22c34f3 commit a02b10a
Show file tree
Hide file tree
Showing 92 changed files with 1,985 additions and 2,571 deletions.
2 changes: 1 addition & 1 deletion src/libfourcc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) ->

let little = match endian {
None => false,
Some(Ident{ident, span}) => match token::get_ident(ident.name).get() {
Some(Ident{ident, span}) => match token::get_ident(ident).get() {
"little" => true,
"big" => false,
"target" => target_endian_little(cx, sp),
Expand Down
130 changes: 52 additions & 78 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ use serialize::hex::ToHex;
use extra::tempfile::TempDir;
use syntax::abi;
use syntax::ast;
use syntax::ast_map::{PathMod, PathName, PathPrettyName};
use syntax::ast_map::{PathElem, PathElems, PathName};
use syntax::ast_map;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::crateid::CrateId;
use syntax::parse::token;

#[deriving(Clone, Eq, TotalOrd, TotalEq)]
pub enum OutputType {
Expand Down Expand Up @@ -531,11 +532,8 @@ fn truncated_hash_result(symbol_hasher: &mut Sha256) -> ~str {


// This calculates STH for a symbol, as defined above
pub fn symbol_hash(tcx: ty::ctxt,
symbol_hasher: &mut Sha256,
t: ty::t,
link_meta: &LinkMeta)
-> ~str {
fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &mut Sha256,
t: ty::t, link_meta: &LinkMeta) -> ~str {
// NB: do *not* use abbrevs here as we want the symbol names
// to be independent of one another in the crate.

Expand All @@ -551,13 +549,10 @@ pub fn symbol_hash(tcx: ty::ctxt,
hash
}

pub fn get_symbol_hash(ccx: &CrateContext, t: ty::t) -> ~str {
{
let type_hashcodes = ccx.type_hashcodes.borrow();
match type_hashcodes.get().find(&t) {
Some(h) => return h.to_str(),
None => {}
}
fn get_symbol_hash(ccx: &CrateContext, t: ty::t) -> ~str {
match ccx.type_hashcodes.borrow().get().find(&t) {
Some(h) => return h.to_str(),
None => {}
}

let mut type_hashcodes = ccx.type_hashcodes.borrow_mut();
Expand Down Expand Up @@ -615,8 +610,9 @@ pub fn sanitize(s: &str) -> ~str {
return result;
}

pub fn mangle(sess: Session, ss: ast_map::Path,
hash: Option<&str>, vers: Option<&str>) -> ~str {
pub fn mangle<PI: Iterator<PathElem>>(mut path: PI,
hash: Option<&str>,
vers: Option<&str>) -> ~str {
// Follow C++ namespace-mangling style, see
// http://en.wikipedia.org/wiki/Name_mangling for more info.
//
Expand All @@ -625,49 +621,27 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
// when using unix's linker. Perhaps one day when we just use a linker from LLVM
// we won't need to do this name mangling. The problem with name mangling is
// that it seriously limits the available characters. For example we can't
// have things like @T or ~[T] in symbol names when one would theoretically
// have things like &T or ~[T] in symbol names when one would theoretically
// want them for things like impls of traits on that type.
//
// To be able to work on all platforms and get *some* reasonable output, we
// use C++ name-mangling.

let mut n = ~"_ZN"; // _Z == Begin name-sequence, N == nested

let push = |n: &mut ~str, s: &str| {
fn push(n: &mut ~str, s: &str) {
let sani = sanitize(s);
n.push_str(format!("{}{}", sani.len(), sani));
};
}

// First, connect each component with <len, name> pairs.
for s in ss.iter() {
match *s {
PathName(s) | PathMod(s) | PathPrettyName(s, _) => {
push(&mut n, sess.str_of(s))
}
}
for e in path {
push(&mut n, token::get_name(e.name()).get().as_slice())
}

// next, if any identifiers are "pretty" and need extra information tacked
// on, then use the hash to generate two unique characters. For now
// hopefully 2 characters is enough to avoid collisions.
static EXTRA_CHARS: &'static str =
"abcdefghijklmnopqrstuvwxyz\
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
0123456789";
let mut hash = match hash { Some(s) => s.to_owned(), None => ~"" };
for s in ss.iter() {
match *s {
PathPrettyName(_, extra) => {
let hi = (extra >> 32) as u32 as uint;
let lo = extra as u32 as uint;
hash.push_char(EXTRA_CHARS[hi % EXTRA_CHARS.len()] as char);
hash.push_char(EXTRA_CHARS[lo % EXTRA_CHARS.len()] as char);
}
_ => {}
}
}
if hash.len() > 0 {
push(&mut n, hash);
match hash {
Some(s) => push(&mut n, s),
None => {}
}
match vers {
Some(s) => push(&mut n, s),
Expand All @@ -678,10 +652,7 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
n
}

pub fn exported_name(sess: Session,
path: ast_map::Path,
hash: &str,
vers: &str) -> ~str {
pub fn exported_name(path: PathElems, hash: &str, vers: &str) -> ~str {
// 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)) {
Expand All @@ -690,53 +661,56 @@ pub fn exported_name(sess: Session,
vers.to_owned()
};

mangle(sess, path, Some(hash), Some(vers.as_slice()))
mangle(path, Some(hash), Some(vers.as_slice()))
}

pub fn mangle_exported_name(ccx: &CrateContext,
path: ast_map::Path,
t: ty::t) -> ~str {
let hash = get_symbol_hash(ccx, t);
return exported_name(ccx.sess, path,
hash,
ccx.link_meta.crateid.version_or_default());
pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
t: ty::t, id: ast::NodeId) -> ~str {
let mut hash = get_symbol_hash(ccx, t);

// Paths can be completely identical for different nodes,
// e.g. `fn foo() { { fn a() {} } { fn a() {} } }`, so we
// generate unique characters from the node id. For now
// hopefully 3 characters is enough to avoid collisions.
static EXTRA_CHARS: &'static str =
"abcdefghijklmnopqrstuvwxyz\
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
0123456789";
let id = id as uint;
let extra1 = id % EXTRA_CHARS.len();
let id = id / EXTRA_CHARS.len();
let extra2 = id % EXTRA_CHARS.len();
let id = id / EXTRA_CHARS.len();
let extra3 = id % EXTRA_CHARS.len();
hash.push_char(EXTRA_CHARS[extra1] as char);
hash.push_char(EXTRA_CHARS[extra2] as char);
hash.push_char(EXTRA_CHARS[extra3] as char);

exported_name(path, hash, ccx.link_meta.crateid.version_or_default())
}

pub fn mangle_internal_name_by_type_only(ccx: &CrateContext,
t: ty::t,
name: &str) -> ~str {
let s = ppaux::ty_to_short_str(ccx.tcx, t);
let path = [PathName(token::intern(name)),
PathName(token::intern(s))];
let hash = get_symbol_hash(ccx, t);
return mangle(ccx.sess,
~[PathName(ccx.sess.ident_of(name)),
PathName(ccx.sess.ident_of(s))],
Some(hash.as_slice()),
None);
mangle(ast_map::Values(path.iter()), Some(hash.as_slice()), None)
}

pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
t: ty::t,
name: &str) -> ~str {
let s = ppaux::ty_to_str(ccx.tcx, t);
let path = [PathName(token::intern(s)),
gensym_name(name)];
let hash = get_symbol_hash(ccx, t);
let (_, name) = gensym_name(name);
return mangle(ccx.sess,
~[PathName(ccx.sess.ident_of(s)), name],
Some(hash.as_slice()),
None);
}

pub fn mangle_internal_name_by_path_and_seq(ccx: &CrateContext,
mut path: ast_map::Path,
flav: &str) -> ~str {
let (_, name) = gensym_name(flav);
path.push(name);
mangle(ccx.sess, path, None, None)
mangle(ast_map::Values(path.iter()), Some(hash.as_slice()), None)
}

pub fn mangle_internal_name_by_path(ccx: &CrateContext,
path: ast_map::Path) -> ~str {
mangle(ccx.sess, path, None, None)
pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> ~str {
mangle(path.chain(Some(gensym_name(flav)).move_iter()), None, None)
}

pub fn output_lib_filename(lm: &LinkMeta) -> ~str {
Expand Down
6 changes: 2 additions & 4 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|_| middle::resolve_lifetime::krate(sess, krate));

time(time_passes, "looking for entry point", (),
|_| middle::entry::find_entry_point(sess, krate, ast_map));
|_| middle::entry::find_entry_point(sess, krate, &ast_map));

sess.macro_registrar_fn.with_mut(|r| *r =
time(time_passes, "looking for macro registrar", (), |_|
Expand All @@ -288,7 +288,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
middle::const_eval::process_crate(krate, ty_cx));

time(time_passes, "const checking", (), |_|
middle::check_const::check_crate(sess, krate, ast_map, def_map,
middle::check_const::check_crate(sess, krate, def_map,
method_map, ty_cx));

let maps = (external_exports, last_private_map);
Expand Down Expand Up @@ -638,7 +638,6 @@ pub fn pretty_print_input(sess: Session,
let mut rdr = MemReader::new(src.as_bytes().to_owned());
let stdout = io::stdout();
pprust::print_crate(sess.codemap,
token::get_ident_interner(),
sess.span_diagnostic,
&krate,
source_name(input),
Expand Down Expand Up @@ -1135,7 +1134,6 @@ pub fn early_error(msg: &str) -> ! {
pub fn list_metadata(sess: Session, path: &Path,
out: &mut io::Writer) -> io::IoResult<()> {
metadata::loader::list_file_metadata(
token::get_ident_interner(),
session::sess_os_to_meta_os(sess.targ_cfg.os), path, out)
}

Expand Down
21 changes: 1 addition & 20 deletions src/librustc/driver/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ use syntax::ast::{IntTy, UintTy};
use syntax::codemap::Span;
use syntax::diagnostic;
use syntax::parse::ParseSess;
use syntax::{ast, codemap};
use syntax::abi;
use syntax::parse::token;
use syntax::{abi, ast, codemap};
use syntax;

use std::cell::{Cell, RefCell};
Expand Down Expand Up @@ -301,23 +299,6 @@ impl Session_ {
pub fn show_span(&self) -> bool {
self.debugging_opt(SHOW_SPAN)
}

// DEPRECATED. This function results in a lot of allocations when they
// are not necessary.
pub fn str_of(&self, id: ast::Ident) -> ~str {
let string = token::get_ident(id.name);
string.get().to_str()
}

// pointless function, now...
pub fn ident_of(&self, st: &str) -> ast::Ident {
token::str_to_ident(st)
}

// pointless function, now...
pub fn intr(&self) -> @syntax::parse::token::IdentInterner {
token::get_ident_interner()
}
}

/// Some reasonable defaults
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/front/assign_node_ids_and_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ impl ast_map::FoldOps for NodeIdAssigner {
}

pub fn assign_node_ids_and_map(sess: Session, krate: ast::Crate) -> (ast::Crate, ast_map::Map) {
ast_map::map_crate(sess.diagnostic(), krate, NodeIdAssigner { sess: sess })
ast_map::map_crate(krate, NodeIdAssigner { sess: sess })
}
15 changes: 6 additions & 9 deletions src/librustc/front/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,7 @@ impl Context {

impl Visitor<()> for Context {
fn visit_ident(&mut self, sp: Span, id: ast::Ident, _: ()) {
let string = token::get_ident(id.name);
let s = string.get();

if !s.is_ascii() {
if !token::get_ident(id).get().is_ascii() {
self.gate_feature("non_ascii_idents", sp,
"non-ascii idents are not fully supported.");
}
Expand Down Expand Up @@ -196,29 +193,29 @@ impl Visitor<()> for Context {
let msg = " is not stable enough for use and are subject to change";


if id == self.sess.ident_of("macro_rules") {
if id == token::str_to_ident("macro_rules") {
self.gate_feature("macro_rules", path.span, "macro definitions are \
not stable enough for use and are subject to change");
}

else if id == self.sess.ident_of("asm") {
else if id == token::str_to_ident("asm") {
self.gate_feature("asm", path.span, "inline assembly is not \
stable enough for use and is subject to change");
}

else if id == self.sess.ident_of("log_syntax") {
else if id == token::str_to_ident("log_syntax") {
self.gate_feature("log_syntax", path.span, "`log_syntax!` is not \
stable enough for use and is subject to change");
}

else if id == self.sess.ident_of("trace_macros") {
else if id == token::str_to_ident("trace_macros") {
self.gate_feature("trace_macros", path.span, "`trace_macros` is not \
stable enough for use and is subject to change");
}

else {
for &quote in quotes.iter() {
if id == self.sess.ident_of(quote) {
if id == token::str_to_ident(quote) {
self.gate_feature("quote", path.span, quote + msg);
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/front/std_inject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
impl fold::Folder for StandardLibraryInjector {
fn fold_crate(&mut self, krate: ast::Crate) -> ast::Crate {
let mut vis = ~[ast::ViewItem {
node: ast::ViewItemExternMod(self.sess.ident_of("std"),
node: ast::ViewItemExternMod(token::str_to_ident("std"),
with_version("std"),
ast::DUMMY_NODE_ID),
attrs: ~[
Expand All @@ -90,15 +90,15 @@ impl fold::Folder for StandardLibraryInjector {

if use_uv(&krate) && !self.sess.building_library.get() {
vis.push(ast::ViewItem {
node: ast::ViewItemExternMod(self.sess.ident_of("green"),
node: ast::ViewItemExternMod(token::str_to_ident("green"),
with_version("green"),
ast::DUMMY_NODE_ID),
attrs: ~[],
vis: ast::Inherited,
span: DUMMY_SP
});
vis.push(ast::ViewItem {
node: ast::ViewItemExternMod(self.sess.ident_of("rustuv"),
node: ast::ViewItemExternMod(token::str_to_ident("rustuv"),
with_version("rustuv"),
ast::DUMMY_NODE_ID),
attrs: ~[],
Expand Down Expand Up @@ -163,12 +163,12 @@ impl fold::Folder for PreludeInjector {
global: false,
segments: ~[
ast::PathSegment {
identifier: self.sess.ident_of("std"),
identifier: token::str_to_ident("std"),
lifetimes: opt_vec::Empty,
types: opt_vec::Empty,
},
ast::PathSegment {
identifier: self.sess.ident_of("prelude"),
identifier: token::str_to_ident("prelude"),
lifetimes: opt_vec::Empty,
types: opt_vec::Empty,
},
Expand Down
Loading

1 comment on commit a02b10a

@huonw
Copy link

@huonw huonw commented on a02b10a Feb 14, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=nikomatsakis

Please sign in to comment.