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;
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;
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, ., _, $
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))
// <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 --
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;
}
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);
// 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)
}
}
}
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,
// 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;
--- /dev/null
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <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.
+
+#![feature(const_fn)]
+
+use std::sync::atomic;
+
+pub const C1: usize = 1;
+pub const C2: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
+pub const C3: fn() = foo;
+pub const C4: usize = C1 * C1 + C1 / C1;
+pub const C5: &'static usize = &C4;
+
+pub static S1: usize = 3;
+pub static S2: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
+
+fn foo() {}
+++ /dev/null
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <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.
-
-#![feature(const_fn)]
-
-use std::sync::atomic;
-
-pub const C1: usize = 1;
-pub const C2: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
-pub const C3: fn() = foo;
-pub const C4: usize = C1 * C1 + C1 / C1;
-pub const C5: &'static usize = &C4;
-
-pub static S1: usize = 3;
-pub static S2: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
-
-fn foo() {}
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
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
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
// 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};