@@ -38,11 +38,12 @@ use serialize::hex::ToHex;
3838use extra:: tempfile:: TempDir ;
3939use syntax:: abi;
4040use syntax:: ast;
41- use syntax:: ast_map:: { PathMod , PathName , PathPrettyName } ;
41+ use syntax:: ast_map:: { PathElem , PathElems , PathName } ;
4242use syntax:: ast_map;
4343use syntax:: attr;
4444use syntax:: attr:: AttrMetaMethods ;
4545use syntax:: crateid:: CrateId ;
46+ use syntax:: parse:: token;
4647
4748#[ deriving( Clone , Eq , TotalOrd , TotalEq ) ]
4849pub enum OutputType {
@@ -531,11 +532,8 @@ fn truncated_hash_result(symbol_hasher: &mut Sha256) -> ~str {
531532
532533
533534// 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 {
539537 // NB: do *not* use abbrevs here as we want the symbol names
540538 // to be independent of one another in the crate.
541539
@@ -551,13 +549,10 @@ pub fn symbol_hash(tcx: ty::ctxt,
551549 hash
552550}
553551
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 => { }
561556 }
562557
563558 let mut type_hashcodes = ccx. type_hashcodes . borrow_mut ( ) ;
@@ -615,8 +610,9 @@ pub fn sanitize(s: &str) -> ~str {
615610 return result;
616611}
617612
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 {
620616 // Follow C++ namespace-mangling style, see
621617 // http://en.wikipedia.org/wiki/Name_mangling for more info.
622618 //
@@ -625,49 +621,27 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
625621 // when using unix's linker. Perhaps one day when we just use a linker from LLVM
626622 // we won't need to do this name mangling. The problem with name mangling is
627623 // 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
629625 // want them for things like impls of traits on that type.
630626 //
631627 // To be able to work on all platforms and get *some* reasonable output, we
632628 // use C++ name-mangling.
633629
634630 let mut n = ~"_ZN"; // _Z == Begin name-sequence, N == nested
635631
636- let push = | n : & mut ~str , s : & str | {
632+ fn push ( n : & mut ~str , s : & str ) {
637633 let sani = sanitize ( s) ;
638634 n. push_str ( format ! ( "{}{}" , sani. len( ) , sani) ) ;
639- } ;
635+ }
640636
641637 // 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 ( ) )
648640 }
649641
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 => { }
671645 }
672646 match vers {
673647 Some ( s) => push ( & mut n, s) ,
@@ -678,10 +652,7 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
678652 n
679653}
680654
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 {
685656 // The version will get mangled to have a leading '_', but it makes more
686657 // sense to lead with a 'v' b/c this is a version...
687658 let vers = if vers. len ( ) > 0 && !char:: is_XID_start ( vers. char_at ( 0 ) ) {
@@ -690,53 +661,56 @@ pub fn exported_name(sess: Session,
690661 vers. to_owned ( )
691662 } ;
692663
693- mangle ( sess , path, Some ( hash) , Some ( vers. as_slice ( ) ) )
664+ mangle ( path, Some ( hash) , Some ( vers. as_slice ( ) ) )
694665}
695666
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 ( ) )
703690}
704691
705692pub fn mangle_internal_name_by_type_only ( ccx : & CrateContext ,
706693 t : ty:: t ,
707694 name : & str ) -> ~str {
708695 let s = ppaux:: ty_to_short_str ( ccx. tcx , t) ;
696+ let path = [ PathName ( token:: intern ( name) ) ,
697+ PathName ( token:: intern ( s) ) ] ;
709698 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 )
715700}
716701
717702pub fn mangle_internal_name_by_type_and_seq ( ccx : & CrateContext ,
718703 t : ty:: t ,
719704 name : & str ) -> ~str {
720705 let s = ppaux:: ty_to_str ( ccx. tcx , t) ;
706+ let path = [ PathName ( token:: intern ( s) ) ,
707+ gensym_name ( name) ] ;
721708 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 )
735710}
736711
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 )
740714}
741715
742716pub fn output_lib_filename ( lm : & LinkMeta ) -> ~str {
0 commit comments