@@ -663,8 +663,7 @@ pub fn truncated_hash_result(symbol_hasher: &mut hash::State) -> ~str {
663663pub fn symbol_hash ( tcx : ty:: ctxt ,
664664 symbol_hasher : & mut hash:: State ,
665665 t : ty:: t ,
666- link_meta : LinkMeta )
667- -> @str {
666+ link_meta : LinkMeta ) -> @str {
668667 // NB: do *not* use abbrevs here as we want the symbol names
669668 // to be independent of one another in the crate.
670669
@@ -719,7 +718,7 @@ pub fn sanitize(s: &str) -> ~str {
719718 'a' .. 'z'
720719 | 'A' .. 'Z'
721720 | '0' .. '9'
722- | '_' => result. push_char ( c) ,
721+ | '_' | '.' => result. push_char ( c) ,
723722
724723 _ => {
725724 let mut tstr = ~"";
@@ -740,22 +739,37 @@ pub fn sanitize(s: &str) -> ~str {
740739 return result;
741740}
742741
743- pub fn mangle ( sess : Session , ss : path ) -> ~str {
742+ pub fn mangle ( sess : Session , ss : path ,
743+ hash : Option < & str > , vers : Option < & str > ) -> ~str {
744744 // Follow C++ namespace-mangling style, see
745745 // http://en.wikipedia.org/wiki/Name_mangling for more info.
746+ //
747+ // It turns out that on OSX you can actually have arbitrary symbols in
748+ // function names (at least when given to LLVM), but this is not possible
749+ // when using unix's linker. Perhaps one day when we just a linker from LLVM
750+ // we won't need to do this name mangling. The problem with name mangling is
751+ // that it seriously limits the available characters. For example we can't
752+ // have things like @T or ~[T] in symbol names when one would theoretically
753+ // want them for things like impls of traits on that type.
754+ //
755+ // To be able to work on all platforms and get *some* reasonable output, we
756+ // use C++ name-mangling.
746757
747758 let mut n = ~"_ZN"; // _Z == Begin name-sequence, N == nested
748759
760+ let push = |s : & str | {
761+ let sani = sanitize ( s) ;
762+ n. push_str ( fmt ! ( "%u%s" , sani. len( ) , sani) ) ;
763+ } ;
764+
749765 // First, connect each component with <len, name> pairs.
750766 for s in ss. iter ( ) {
751767 match * s {
752768 path_name( s) | path_mod( s) | path_pretty_name( s, _) => {
753- let sani = sanitize ( sess. str_of ( s) ) ;
754- n. push_str ( fmt ! ( "%u%s" , sani. len( ) , sani) ) ;
769+ push ( sess. str_of ( s) )
755770 }
756771 }
757772 }
758- n. push_char ( 'E' ) ; // End name-sequence.
759773
760774 // next, if any identifiers are "pretty" and need extra information tacked
761775 // on, then use the hash to generate two unique characters. For now
@@ -764,28 +778,43 @@ pub fn mangle(sess: Session, ss: path) -> ~str {
764778 "abcdefghijklmnopqrstuvwxyz\
765779 ABCDEFGHIJKLMNOPQRSTUVWXYZ\
766780 0123456789";
781+ let mut hash = match hash { Some ( s) => s. to_owned ( ) , None => ~"" } ;
767782 for s in ss. iter ( ) {
768783 match * s {
769784 path_pretty_name( _, extra) => {
770785 let hi = ( extra >> 32 ) as u32 as uint ;
771786 let lo = extra as u32 as uint ;
772- n . push_char ( EXTRA_CHARS [ hi % EXTRA_CHARS . len ( ) ] as char ) ;
773- n . push_char ( EXTRA_CHARS [ lo % EXTRA_CHARS . len ( ) ] as char ) ;
787+ hash . push_char ( EXTRA_CHARS [ hi % EXTRA_CHARS . len ( ) ] as char ) ;
788+ hash . push_char ( EXTRA_CHARS [ lo % EXTRA_CHARS . len ( ) ] as char ) ;
774789 }
775790 _ => { }
776791 }
777792 }
793+ if hash. len( ) > 0 {
794+ push( hash) ;
795+ }
796+ match vers {
797+ Some ( s) => push ( s) ,
798+ None => { }
799+ }
800+
801+ n. push_char ( 'E' ) ; // End name-sequence.
778802 n
779803}
780804
781805pub fn exported_name ( sess : Session ,
782806 path : path ,
783807 hash : & str ,
784808 vers : & str ) -> ~str {
785- mangle ( sess,
786- vec:: append_one (
787- vec:: append_one ( path, path_name ( sess. ident_of ( hash) ) ) ,
788- path_name ( sess. ident_of ( vers) ) ) )
809+ // The version will get mangled to have a leading '_', but it makes more
810+ // sense to lead with a 'v' b/c this is a version...
811+ let vers = if vers. len ( ) > 0 && !char:: is_XID_start ( vers. char_at ( 0 ) ) {
812+ "v" + vers
813+ } else {
814+ vers. to_owned ( )
815+ } ;
816+
817+ mangle ( sess, path, Some ( hash) , Some ( vers. as_slice ( ) ) )
789818}
790819
791820pub fn mangle_exported_name ( ccx : & mut CrateContext ,
@@ -803,31 +832,33 @@ pub fn mangle_internal_name_by_type_only(ccx: &mut CrateContext,
803832 let s = ppaux:: ty_to_short_str ( ccx. tcx , t) ;
804833 let hash = get_symbol_hash ( ccx, t) ;
805834 return mangle ( ccx. sess ,
806- ~[ path_name ( ccx. sess . ident_of ( name) ) ,
807- path_name ( ccx. sess . ident_of ( s) ) ,
808- path_name ( ccx. sess . ident_of ( hash) ) ] ) ;
835+ ~[ path_name ( ccx. sess . ident_of ( name) ) ,
836+ path_name ( ccx. sess . ident_of ( s) ) ] ,
837+ Some ( hash. as_slice ( ) ) ,
838+ None ) ;
809839}
810840
811841pub fn mangle_internal_name_by_type_and_seq ( ccx : & mut CrateContext ,
812- t : ty:: t ,
813- name : & str ) -> ~str {
842+ t : ty:: t ,
843+ name : & str ) -> ~str {
814844 let s = ppaux:: ty_to_str ( ccx. tcx , t) ;
815845 let hash = get_symbol_hash ( ccx, t) ;
816846 return mangle ( ccx. sess ,
817- ~[ path_name ( ccx. sess . ident_of ( s) ) ,
818- path_name ( ccx. sess . ident_of ( hash) ) ,
819- path_name ( gensym_name ( name) ) ] ) ;
847+ ~[ path_name ( ccx. sess . ident_of ( s) ) ,
848+ path_name ( gensym_name ( name) ) ] ,
849+ Some ( hash. as_slice ( ) ) ,
850+ None ) ;
820851}
821852
822853pub fn mangle_internal_name_by_path_and_seq ( ccx : & mut CrateContext ,
823854 mut path : path ,
824855 flav : & str ) -> ~str {
825856 path. push ( path_name ( gensym_name ( flav) ) ) ;
826- mangle ( ccx. sess , path)
857+ mangle ( ccx. sess , path, None , None )
827858}
828859
829860pub fn mangle_internal_name_by_path ( ccx : & mut CrateContext , path : path ) -> ~str {
830- mangle ( ccx. sess , path)
861+ mangle ( ccx. sess , path, None , None )
831862}
832863
833864pub fn mangle_internal_name_by_seq ( _ccx : & mut CrateContext , flav : & str ) -> ~str {
0 commit comments