@@ -38,11 +38,12 @@ use serialize::hex::ToHex;
38
38
use extra:: tempfile:: TempDir ;
39
39
use syntax:: abi;
40
40
use syntax:: ast;
41
- use syntax:: ast_map:: { PathMod , PathName , PathPrettyName } ;
41
+ use syntax:: ast_map:: { PathElem , PathElems , PathName } ;
42
42
use syntax:: ast_map;
43
43
use syntax:: attr;
44
44
use syntax:: attr:: AttrMetaMethods ;
45
45
use syntax:: crateid:: CrateId ;
46
+ use syntax:: parse:: token;
46
47
47
48
#[ deriving( Clone , Eq , TotalOrd , TotalEq ) ]
48
49
pub enum OutputType {
@@ -531,11 +532,8 @@ fn truncated_hash_result(symbol_hasher: &mut Sha256) -> ~str {
531
532
532
533
533
534
// This calculates STH for a symbol, as defined above
534
- pub fn symbol_hash ( tcx : ty:: ctxt ,
535
- symbol_hasher : & mut Sha256 ,
536
- t : ty:: t ,
537
- link_meta : & LinkMeta )
538
- -> ~str {
535
+ fn symbol_hash ( tcx : ty:: ctxt , symbol_hasher : & mut Sha256 ,
536
+ t : ty:: t , link_meta : & LinkMeta ) -> ~str {
539
537
// NB: do *not* use abbrevs here as we want the symbol names
540
538
// to be independent of one another in the crate.
541
539
@@ -551,13 +549,10 @@ pub fn symbol_hash(tcx: ty::ctxt,
551
549
hash
552
550
}
553
551
554
- pub fn get_symbol_hash ( ccx : & CrateContext , t : ty:: t ) -> ~str {
555
- {
556
- let type_hashcodes = ccx. type_hashcodes . borrow ( ) ;
557
- match type_hashcodes. get ( ) . find ( & t) {
558
- Some ( h) => return h. to_str ( ) ,
559
- None => { }
560
- }
552
+ fn get_symbol_hash ( ccx : & CrateContext , t : ty:: t ) -> ~str {
553
+ match ccx. type_hashcodes . borrow ( ) . get ( ) . find ( & t) {
554
+ Some ( h) => return h. to_str ( ) ,
555
+ None => { }
561
556
}
562
557
563
558
let mut type_hashcodes = ccx. type_hashcodes . borrow_mut ( ) ;
@@ -615,8 +610,9 @@ pub fn sanitize(s: &str) -> ~str {
615
610
return result;
616
611
}
617
612
618
- pub fn mangle ( sess : Session , ss : ast_map:: Path ,
619
- hash : Option < & str > , vers : Option < & str > ) -> ~str {
613
+ pub fn mangle < PI : Iterator < PathElem > > ( mut path : PI ,
614
+ hash : Option < & str > ,
615
+ vers : Option < & str > ) -> ~str {
620
616
// Follow C++ namespace-mangling style, see
621
617
// http://en.wikipedia.org/wiki/Name_mangling for more info.
622
618
//
@@ -625,49 +621,27 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
625
621
// when using unix's linker. Perhaps one day when we just use a linker from LLVM
626
622
// we won't need to do this name mangling. The problem with name mangling is
627
623
// that it seriously limits the available characters. For example we can't
628
- // have things like @ T or ~[T] in symbol names when one would theoretically
624
+ // have things like & T or ~[T] in symbol names when one would theoretically
629
625
// want them for things like impls of traits on that type.
630
626
//
631
627
// To be able to work on all platforms and get *some* reasonable output, we
632
628
// use C++ name-mangling.
633
629
634
630
let mut n = ~"_ZN"; // _Z == Begin name-sequence, N == nested
635
631
636
- let push = | n : & mut ~str , s : & str | {
632
+ fn push ( n : & mut ~str , s : & str ) {
637
633
let sani = sanitize ( s) ;
638
634
n. push_str ( format ! ( "{}{}" , sani. len( ) , sani) ) ;
639
- } ;
635
+ }
640
636
641
637
// First, connect each component with <len, name> pairs.
642
- for s in ss. iter ( ) {
643
- match * s {
644
- PathName ( s) | PathMod ( s) | PathPrettyName ( s, _) => {
645
- push ( & mut n, sess. str_of ( s) )
646
- }
647
- }
638
+ for e in path {
639
+ push ( & mut n, token:: get_name ( e. name ( ) ) . get ( ) . as_slice ( ) )
648
640
}
649
641
650
- // next, if any identifiers are "pretty" and need extra information tacked
651
- // on, then use the hash to generate two unique characters. For now
652
- // hopefully 2 characters is enough to avoid collisions.
653
- static EXTRA_CHARS : & ' static str =
654
- "abcdefghijklmnopqrstuvwxyz\
655
- ABCDEFGHIJKLMNOPQRSTUVWXYZ\
656
- 0123456789";
657
- let mut hash = match hash { Some ( s) => s. to_owned ( ) , None => ~"" } ;
658
- for s in ss. iter ( ) {
659
- match * s {
660
- PathPrettyName ( _, extra) => {
661
- let hi = ( extra >> 32 ) as u32 as uint ;
662
- let lo = extra as u32 as uint ;
663
- hash. push_char ( EXTRA_CHARS [ hi % EXTRA_CHARS . len ( ) ] as char ) ;
664
- hash. push_char ( EXTRA_CHARS [ lo % EXTRA_CHARS . len ( ) ] as char ) ;
665
- }
666
- _ => { }
667
- }
668
- }
669
- if hash. len( ) > 0 {
670
- push( & mut n, hash) ;
642
+ match hash {
643
+ Some ( s) => push ( & mut n, s) ,
644
+ None => { }
671
645
}
672
646
match vers {
673
647
Some ( s) => push ( & mut n, s) ,
@@ -678,10 +652,7 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
678
652
n
679
653
}
680
654
681
- pub fn exported_name ( sess : Session ,
682
- path : ast_map:: Path ,
683
- hash : & str ,
684
- vers : & str ) -> ~str {
655
+ pub fn exported_name ( path : PathElems , hash : & str , vers : & str ) -> ~str {
685
656
// The version will get mangled to have a leading '_', but it makes more
686
657
// sense to lead with a 'v' b/c this is a version...
687
658
let vers = if vers. len ( ) > 0 && !char:: is_XID_start ( vers. char_at ( 0 ) ) {
@@ -690,53 +661,56 @@ pub fn exported_name(sess: Session,
690
661
vers. to_owned ( )
691
662
} ;
692
663
693
- mangle ( sess , path, Some ( hash) , Some ( vers. as_slice ( ) ) )
664
+ mangle ( path, Some ( hash) , Some ( vers. as_slice ( ) ) )
694
665
}
695
666
696
- pub fn mangle_exported_name ( ccx : & CrateContext ,
697
- path : ast_map:: Path ,
698
- t : ty:: t ) -> ~str {
699
- let hash = get_symbol_hash ( ccx, t) ;
700
- return exported_name ( ccx. sess , path,
701
- hash,
702
- ccx. link_meta . crateid . version_or_default ( ) ) ;
667
+ pub fn mangle_exported_name ( ccx : & CrateContext , path : PathElems ,
668
+ t : ty:: t , id : ast:: NodeId ) -> ~str {
669
+ let mut hash = get_symbol_hash ( ccx, t) ;
670
+
671
+ // Paths can be completely identical for different nodes,
672
+ // e.g. `fn foo() { { fn a() {} } { fn a() {} } }`, so we
673
+ // generate unique characters from the node id. For now
674
+ // hopefully 3 characters is enough to avoid collisions.
675
+ static EXTRA_CHARS : & ' static str =
676
+ "abcdefghijklmnopqrstuvwxyz\
677
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ\
678
+ 0123456789";
679
+ let id = id as uint ;
680
+ let extra1 = id % EXTRA_CHARS . len ( ) ;
681
+ let id = id / EXTRA_CHARS . len ( ) ;
682
+ let extra2 = id % EXTRA_CHARS . len ( ) ;
683
+ let id = id / EXTRA_CHARS . len ( ) ;
684
+ let extra3 = id % EXTRA_CHARS . len ( ) ;
685
+ hash. push_char ( EXTRA_CHARS [ extra1] as char ) ;
686
+ hash. push_char ( EXTRA_CHARS [ extra2] as char ) ;
687
+ hash. push_char ( EXTRA_CHARS [ extra3] as char ) ;
688
+
689
+ exported_name ( path, hash, ccx. link_meta . crateid . version_or_default ( ) )
703
690
}
704
691
705
692
pub fn mangle_internal_name_by_type_only ( ccx : & CrateContext ,
706
693
t : ty:: t ,
707
694
name : & str ) -> ~str {
708
695
let s = ppaux:: ty_to_short_str ( ccx. tcx , t) ;
696
+ let path = [ PathName ( token:: intern ( name) ) ,
697
+ PathName ( token:: intern ( s) ) ] ;
709
698
let hash = get_symbol_hash ( ccx, t) ;
710
- return mangle ( ccx. sess ,
711
- ~[ PathName ( ccx. sess . ident_of ( name) ) ,
712
- PathName ( ccx. sess . ident_of ( s) ) ] ,
713
- Some ( hash. as_slice ( ) ) ,
714
- None ) ;
699
+ mangle ( ast_map:: Values ( path. iter ( ) ) , Some ( hash. as_slice ( ) ) , None )
715
700
}
716
701
717
702
pub fn mangle_internal_name_by_type_and_seq ( ccx : & CrateContext ,
718
703
t : ty:: t ,
719
704
name : & str ) -> ~str {
720
705
let s = ppaux:: ty_to_str ( ccx. tcx , t) ;
706
+ let path = [ PathName ( token:: intern ( s) ) ,
707
+ gensym_name ( name) ] ;
721
708
let hash = get_symbol_hash ( ccx, t) ;
722
- let ( _, name) = gensym_name ( name) ;
723
- return mangle ( ccx. sess ,
724
- ~[ PathName ( ccx. sess . ident_of ( s) ) , name] ,
725
- Some ( hash. as_slice ( ) ) ,
726
- None ) ;
727
- }
728
-
729
- pub fn mangle_internal_name_by_path_and_seq ( ccx : & CrateContext ,
730
- mut path : ast_map:: Path ,
731
- flav : & str ) -> ~str {
732
- let ( _, name) = gensym_name ( flav) ;
733
- path. push ( name) ;
734
- mangle ( ccx. sess , path, None , None )
709
+ mangle ( ast_map:: Values ( path. iter ( ) ) , Some ( hash. as_slice ( ) ) , None )
735
710
}
736
711
737
- pub fn mangle_internal_name_by_path ( ccx : & CrateContext ,
738
- path : ast_map:: Path ) -> ~str {
739
- mangle ( ccx. sess , path, None , None )
712
+ pub fn mangle_internal_name_by_path_and_seq ( path : PathElems , flav : & str ) -> ~str {
713
+ mangle ( path. chain ( Some ( gensym_name ( flav) ) . move_iter ( ) ) , None , None )
740
714
}
741
715
742
716
pub fn output_lib_filename ( lm : & LinkMeta ) -> ~str {
0 commit comments