Use new symbol names for items of various kinds.
This commit is contained in:
parent
68de171890
commit
7def3768c6
@ -24,11 +24,9 @@ use middle::cstore::{self, CrateStore, LinkMeta};
|
||||
use middle::cstore::{LinkagePreference, NativeLibraryKind};
|
||||
use middle::def_id::DefId;
|
||||
use middle::dependency_format::Linkage;
|
||||
use middle::ty::{Ty, TyCtxt};
|
||||
use rustc::front::map::DefPath;
|
||||
use trans::{CrateContext, CrateTranslation, gensym_name};
|
||||
use middle::ty::TyCtxt;
|
||||
use trans::CrateTranslation;
|
||||
use util::common::time;
|
||||
use util::sha2::{Digest, Sha256};
|
||||
use util::fs::fix_windows_verbatim_for_gcc;
|
||||
use rustc_back::tempdir::TempDir;
|
||||
|
||||
@ -38,16 +36,14 @@ use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::iter::once;
|
||||
use std::mem;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
use flate;
|
||||
use serialize::hex::ToHex;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::{self, InternedString};
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
|
||||
use rustc_front::hir;
|
||||
@ -195,50 +191,10 @@ pub fn build_link_meta(sess: &Session,
|
||||
return r;
|
||||
}
|
||||
|
||||
fn truncated_hash_result(symbol_hasher: &mut Sha256) -> String {
|
||||
let output = symbol_hasher.result_bytes();
|
||||
// 64 bits should be enough to avoid collisions.
|
||||
output[.. 8].to_hex().to_string()
|
||||
}
|
||||
|
||||
pub fn def_to_string(_tcx: &TyCtxt, did: DefId) -> String {
|
||||
format!("{}:{}", did.krate, did.index.as_usize())
|
||||
}
|
||||
|
||||
// This calculates STH for a symbol, as defined above
|
||||
fn symbol_hash<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
symbol_hasher: &mut Sha256,
|
||||
t: Ty<'tcx>,
|
||||
link_meta: &LinkMeta)
|
||||
-> String {
|
||||
// NB: do *not* use abbrevs here as we want the symbol names
|
||||
// to be independent of one another in the crate.
|
||||
|
||||
symbol_hasher.reset();
|
||||
symbol_hasher.input_str(&link_meta.crate_name);
|
||||
symbol_hasher.input_str("-");
|
||||
symbol_hasher.input_str(link_meta.crate_hash.as_str());
|
||||
symbol_hasher.input_str(&tcx.sess.crate_disambiguator.borrow()[..]);
|
||||
symbol_hasher.input_str("-");
|
||||
symbol_hasher.input(&tcx.sess.cstore.encode_type(tcx, t, def_to_string));
|
||||
// Prefix with 'h' so that it never blends into adjacent digits
|
||||
let mut hash = String::from("h");
|
||||
hash.push_str(&truncated_hash_result(symbol_hasher));
|
||||
hash
|
||||
}
|
||||
|
||||
fn get_symbol_hash<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> String {
|
||||
if let Some(h) = ccx.type_hashcodes().borrow().get(&t) {
|
||||
return h.to_string()
|
||||
}
|
||||
|
||||
let mut symbol_hasher = ccx.symbol_hasher().borrow_mut();
|
||||
let hash = symbol_hash(ccx.tcx(), &mut *symbol_hasher, t, ccx.link_meta());
|
||||
ccx.type_hashcodes().borrow_mut().insert(t, hash.clone());
|
||||
hash
|
||||
}
|
||||
|
||||
|
||||
// Name sanitation. LLVM will happily accept identifiers with weird names, but
|
||||
// gas doesn't!
|
||||
// gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
|
||||
@ -324,53 +280,6 @@ pub fn mangle<PI: Iterator<Item=InternedString>>(path: PI, hash: Option<&str>) -
|
||||
n
|
||||
}
|
||||
|
||||
pub fn exported_name(path: DefPath, hash: &str) -> String {
|
||||
let path = path.into_iter()
|
||||
.map(|e| e.data.as_interned_str());
|
||||
mangle(path, Some(hash))
|
||||
}
|
||||
|
||||
pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: DefPath,
|
||||
t: Ty<'tcx>, id: ast::NodeId) -> String {
|
||||
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.
|
||||
const EXTRA_CHARS: &'static str =
|
||||
"abcdefghijklmnopqrstuvwxyz\
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
|
||||
0123456789";
|
||||
let id = id as usize;
|
||||
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(EXTRA_CHARS.as_bytes()[extra1] as char);
|
||||
hash.push(EXTRA_CHARS.as_bytes()[extra2] as char);
|
||||
hash.push(EXTRA_CHARS.as_bytes()[extra3] as char);
|
||||
|
||||
exported_name(path, &hash[..])
|
||||
}
|
||||
|
||||
pub fn mangle_internal_name_by_type_and_seq<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
t: Ty<'tcx>,
|
||||
name: &str) -> String {
|
||||
let path = [token::intern(&t.to_string()).as_str(), gensym_name(name).as_str()];
|
||||
let hash = get_symbol_hash(ccx, t);
|
||||
mangle(path.iter().cloned(), Some(&hash[..]))
|
||||
}
|
||||
|
||||
pub fn mangle_internal_name_by_path_and_seq(path: DefPath, flav: &str) -> String {
|
||||
let names =
|
||||
path.into_iter()
|
||||
.map(|e| e.data.as_interned_str())
|
||||
.chain(once(gensym_name(flav).as_str())); // append unique version of "flav"
|
||||
mangle(names, None)
|
||||
}
|
||||
|
||||
pub fn get_linker(sess: &Session) -> (String, Command) {
|
||||
if let Some(ref linker) = sess.opts.cg.linker {
|
||||
(linker.clone(), Command::new(linker))
|
||||
|
@ -7,6 +7,7 @@
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Translate the completed AST to the LLVM IR.
|
||||
//!
|
||||
//! Some functions here, such as trans_block and trans_expr, return a value --
|
||||
@ -29,8 +30,7 @@ pub use self::ValueOrigin::*;
|
||||
use super::CrateTranslation;
|
||||
use super::ModuleTranslation;
|
||||
|
||||
use back::link::mangle_exported_name;
|
||||
use back::link;
|
||||
use back::{link, symbol_names};
|
||||
use lint;
|
||||
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
|
||||
use llvm;
|
||||
@ -2421,10 +2421,11 @@ pub fn create_entry_wrapper(ccx: &CrateContext, sp: Span, main_llfn: ValueRef) {
|
||||
}
|
||||
|
||||
pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
id: ast::NodeId,
|
||||
ty: Ty<'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
attrs: &[ast::Attribute])
|
||||
-> String {
|
||||
let id = ccx.tcx().map.as_local_node_id(instance.def).unwrap();
|
||||
|
||||
match ccx.external_srcs().borrow().get(&id) {
|
||||
Some(&did) => {
|
||||
let sym = ccx.sess().cstore.item_symbol(did);
|
||||
@ -2438,16 +2439,16 @@ pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
// Use provided name
|
||||
Some(name) => name.to_string(),
|
||||
_ => {
|
||||
let path = ccx.tcx().map.def_path_from_id(id);
|
||||
if attr::contains_name(attrs, "no_mangle") {
|
||||
// Don't mangle
|
||||
let path = ccx.tcx().map.def_path_from_id(id);
|
||||
path.last().unwrap().data.to_string()
|
||||
} else {
|
||||
match weak_lang_items::link_name(attrs) {
|
||||
Some(name) => name.to_string(),
|
||||
None => {
|
||||
// Usual name mangling
|
||||
mangle_exported_name(ccx, path, ty, id)
|
||||
symbol_names::exported_name(ccx, &instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
Some(hir_map::NodeImplItem(&hir::ImplItem {
|
||||
ref attrs, id, span, node: hir::ImplItemKind::Method(..), ..
|
||||
})) => {
|
||||
let sym = exported_name(ccx, id, ty, attrs);
|
||||
let sym = exported_name(ccx, instance, attrs);
|
||||
|
||||
if declare::get_defined_value(ccx, &sym).is_some() {
|
||||
ccx.sess().span_fatal(span,
|
||||
|
@ -1032,7 +1032,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
|
||||
// we need to get the symbol from metadata instead of
|
||||
// using the current crate's name/version
|
||||
// information in the hash of the symbol
|
||||
let sym = exported_name(ccx, id, ty, attrs);
|
||||
let sym = exported_name(ccx, instance, attrs);
|
||||
debug!("making {}", sym);
|
||||
|
||||
// Create the global before evaluating the initializer;
|
||||
|
@ -57,7 +57,7 @@ fn runtest(me: &str) {
|
||||
let out = p.wait_with_output().unwrap();
|
||||
assert!(!out.status.success());
|
||||
let s = str::from_utf8(&out.stderr).unwrap();
|
||||
assert!(s.contains("stack backtrace") && s.contains(" - foo"),
|
||||
assert!(s.contains("stack backtrace") && s.contains(" - backtrace::foo"),
|
||||
"bad output: {}", s);
|
||||
|
||||
// Make sure the stack trace is *not* printed
|
||||
@ -67,7 +67,7 @@ fn runtest(me: &str) {
|
||||
let out = p.wait_with_output().unwrap();
|
||||
assert!(!out.status.success());
|
||||
let s = str::from_utf8(&out.stderr).unwrap();
|
||||
assert!(!s.contains("stack backtrace") && !s.contains(" - foo"),
|
||||
assert!(!s.contains("stack backtrace") && !s.contains(" - backtrace::foo"),
|
||||
"bad output2: {}", s);
|
||||
|
||||
// Make sure a stack trace is printed
|
||||
@ -77,7 +77,7 @@ fn runtest(me: &str) {
|
||||
let s = str::from_utf8(&out.stderr).unwrap();
|
||||
// loosened the following from double::h to double:: due to
|
||||
// spurious failures on mac, 32bit, optimized
|
||||
assert!(s.contains("stack backtrace") && s.contains(" - double"),
|
||||
assert!(s.contains("stack backtrace") && s.contains(" - backtrace::double"),
|
||||
"bad output3: {}", s);
|
||||
|
||||
// Make sure a stack trace isn't printed too many times
|
||||
|
@ -8,13 +8,13 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:issue-17718.rs
|
||||
// aux-build:issue-17718-aux.rs
|
||||
|
||||
|
||||
#![feature(core)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
extern crate issue_17718 as other;
|
||||
extern crate issue_17718_aux as other;
|
||||
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user