use mir;
use monomorphize::{self, Instance};
use partitioning::{self, PartitioningStrategy, CodegenUnit};
-use symbol_map::SymbolMap;
use symbol_names_test;
use trans_item::{TransItem, DefPathBasedNames};
use type_::Type;
scx: &SharedCrateContext<'a, 'tcx>,
translation_items: &FxHashSet<TransItem<'tcx>>,
llvm_modules: &[ModuleLlvm],
- symbol_map: &SymbolMap<'tcx>,
exported_symbols: &ExportedSymbols) {
let export_threshold =
symbol_export::crates_export_threshold(&sess.crate_types.borrow());
let mut linkage_fixed_explicitly = FxHashSet();
for trans_item in translation_items {
- let symbol_name = symbol_map.get_or_compute(scx, *trans_item);
+ let symbol_name = str::to_owned(&trans_item.symbol_name(tcx));
if trans_item.explicit_linkage(tcx).is_some() {
linkage_fixed_explicitly.insert(symbol_name.clone());
}
// Run the translation item collector and partition the collected items into
// codegen units.
- let (translation_items, codegen_units, symbol_map) =
+ let (translation_items, codegen_units) =
collect_and_partition_translation_items(&shared_ccx);
let mut all_stats = Stats::default();
let sess = shared_ccx.sess();
- let exported_symbols = ExportedSymbols::compute_from(&shared_ccx,
- &symbol_map);
+ let exported_symbols = ExportedSymbols::compute(&shared_ccx);
// Get the list of llvm modules we created. We'll do a few wacky
// transforms on them now.
&shared_ccx,
&translation_items,
&llvm_modules,
- &symbol_map,
&exported_symbols);
});
}
}
+#[inline(never)] // give this a place in the profiler
+fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_items: I)
+ where I: Iterator<Item=&'a TransItem<'tcx>>
+{
+ let mut symbols: Vec<_> = trans_items.map(|trans_item| {
+ (trans_item, trans_item.symbol_name(tcx))
+ }).collect();
+
+ (&mut symbols[..]).sort_by(|&(_, ref sym1), &(_, ref sym2)|{
+ sym1.cmp(sym2)
+ });
+
+ for pair in (&symbols[..]).windows(2) {
+ let sym1 = &pair[0].1;
+ let sym2 = &pair[1].1;
+
+ if *sym1 == *sym2 {
+ let trans_item1 = pair[0].0;
+ let trans_item2 = pair[1].0;
+
+ let span1 = trans_item1.local_span(tcx);
+ let span2 = trans_item2.local_span(tcx);
+
+ // Deterministically select one of the spans for error reporting
+ let span = match (span1, span2) {
+ (Some(span1), Some(span2)) => {
+ Some(if span1.lo.0 > span2.lo.0 {
+ span1
+ } else {
+ span2
+ })
+ }
+ (Some(span), None) |
+ (None, Some(span)) => Some(span),
+ _ => None
+ };
+
+ let error_message = format!("symbol `{}` is already defined", sym1);
+
+ if let Some(span) = span {
+ tcx.sess.span_fatal(span, &error_message)
+ } else {
+ tcx.sess.fatal(&error_message)
+ }
+ }
+ }
+}
+
fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
-> (FxHashSet<TransItem<'tcx>>,
- Vec<CodegenUnit<'tcx>>,
- SymbolMap<'tcx>) {
+ Vec<CodegenUnit<'tcx>>) {
let time_passes = scx.sess().time_passes();
let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
collector::collect_crate_translation_items(&scx, collection_mode)
});
- let symbol_map = SymbolMap::build(scx, items.iter().cloned());
+ assert_symbols_are_distinct(scx.tcx(), items.iter());
let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
PartitioningStrategy::PerModule
}
}
- (translation_items, codegen_units, symbol_map)
+ (translation_items, codegen_units)
}