@@ -128,34 +128,6 @@ fn get_dest_addr(dest: dest) -> ValueRef {
128
128
}
129
129
}
130
130
131
- // Name sanitation. LLVM will happily accept identifiers with weird names, but
132
- // gas doesn't!
133
- fn sanitize ( s : str ) -> str {
134
- let result = "" ;
135
- for c: u8 in s {
136
- if c == '@' as u8 {
137
- result += "boxed_" ;
138
- } else {
139
- if c == ',' as u8 {
140
- result += "_" ;
141
- } else {
142
- if c == '{' as u8 || c == '(' as u8 {
143
- result += "_of_" ;
144
- } else {
145
- if c != 10u8 && c != '}' as u8 && c != ')' as u8 &&
146
- c != ' ' as u8 && c != '\t' as u8 && c != ';' as u8
147
- {
148
- let v = [ c] ;
149
- result += str:: from_bytes ( v) ;
150
- }
151
- }
152
- }
153
- }
154
- }
155
- ret result;
156
- }
157
-
158
-
159
131
fn log_fn_time ( ccx : @crate_ctxt , name : str , start : time:: timeval ,
160
132
end : time:: timeval ) {
161
133
let elapsed = 1000 * ( ( end. sec - start. sec ) as int ) +
@@ -412,6 +384,14 @@ fn set_glue_inlining(f: ValueRef, t: ty::t) {
412
384
} else { set_always_inline ( f) ; }
413
385
}
414
386
387
+ // Double-check that we never ask LLVM to declare the same symbol twice. It
388
+ // silently mangles such symbols, breaking our linkage model.
389
+ fn note_unique_llvm_symbol ( ccx : @crate_ctxt , sym : str ) {
390
+ if ccx. all_llvm_symbols . contains_key ( sym) {
391
+ ccx. sess . bug ( "duplicate LLVM symbol: " + sym) ;
392
+ }
393
+ ccx. all_llvm_symbols . insert ( sym, ( ) ) ;
394
+ }
415
395
416
396
// Generates the declaration for (but doesn't emit) a type descriptor.
417
397
fn declare_tydesc ( ccx : @crate_ctxt , t : ty:: t ) -> @tydesc_info {
@@ -424,8 +404,8 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
424
404
let name;
425
405
if ccx. sess . opts . debuginfo {
426
406
name = mangle_internal_name_by_type_only ( ccx, t, "tydesc" ) ;
427
- name = sanitize ( name) ;
428
407
} else { name = mangle_internal_name_by_seq ( ccx, "tydesc" ) ; }
408
+ note_unique_llvm_symbol ( ccx, name) ;
429
409
let gvar = str:: as_c_str ( name, { |buf|
430
410
llvm:: LLVMAddGlobal ( ccx. llmod , ccx. tydesc_type , buf)
431
411
} ) ;
@@ -449,8 +429,10 @@ fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
449
429
let fn_nm;
450
430
if ccx. sess . opts . debuginfo {
451
431
fn_nm = mangle_internal_name_by_type_only ( ccx, t, "glue_" + name) ;
452
- fn_nm = sanitize ( fn_nm) ;
453
- } else { fn_nm = mangle_internal_name_by_seq ( ccx, "glue_" + name) ; }
432
+ } else {
433
+ fn_nm = mangle_internal_name_by_seq ( ccx, "glue_" + name) ;
434
+ }
435
+ note_unique_llvm_symbol ( ccx, fn_nm) ;
454
436
let llfn = decl_cdecl_fn ( ccx. llmod , fn_nm, llfnty) ;
455
437
set_glue_inlining ( llfn, t) ;
456
438
ret llfn;
@@ -4414,6 +4396,7 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
4414
4396
path_name ( "discrim" ) ] ;
4415
4397
let s = mangle_exported_name ( ccx, p, ty:: mk_int ( ccx. tcx ) ) ;
4416
4398
let disr_val = vi[ i] . disr_val ;
4399
+ note_unique_llvm_symbol ( ccx, s) ;
4417
4400
let discrim_gvar = str:: as_c_str ( s, { |buf|
4418
4401
llvm:: LLVMAddGlobal ( ccx. llmod , ccx. int_type , buf)
4419
4402
} ) ;
@@ -4669,6 +4652,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
4669
4652
sha: sha,
4670
4653
type_sha1s: ty:: new_ty_hash ( ) ,
4671
4654
type_short_names: ty:: new_ty_hash ( ) ,
4655
+ all_llvm_symbols: str_hash :: < ( ) > ( ) ,
4672
4656
tcx: tcx,
4673
4657
maps: maps,
4674
4658
stats :
0 commit comments