@@ -103,7 +103,7 @@ use rustc_mir::monomorphize::Instance;
103103
104104use syntax_pos:: symbol:: Symbol ;
105105
106- use std:: fmt:: { self , Write } ;
106+ use std:: fmt:: Write ;
107107use std:: mem:: discriminant;
108108
109109pub fn provide ( providers : & mut Providers ) {
@@ -339,28 +339,29 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
339339//
340340// To be able to work on all platforms and get *some* reasonable output, we
341341// use C++ name-mangling.
342- struct SymbolPathBuffer < ' a , ' tcx > {
343- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
342+ # [ derive ( Debug ) ]
343+ struct SymbolPathBuffer {
344344 result : String ,
345345 temp_buf : String ,
346+ strict_naming : bool ,
346347}
347348
348- impl SymbolPathBuffer < ' a , ' tcx > {
349- fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> Self {
349+ impl SymbolPathBuffer {
350+ fn new ( tcx : TyCtxt < ' _ , ' _ , ' _ > ) -> Self {
350351 let mut result = SymbolPathBuffer {
351352 result : String :: with_capacity ( 64 ) ,
352353 temp_buf : String :: with_capacity ( 16 ) ,
353- tcx,
354+ strict_naming : tcx. has_strict_asm_symbol_naming ( ) ,
354355 } ;
355356 result. result . push_str ( "_ZN" ) ; // _Z == Begin name-sequence, N == nested
356357 result
357358 }
358359
359- fn from_interned ( symbol : ty:: SymbolName , tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> Self {
360+ fn from_interned ( symbol : ty:: SymbolName , tcx : TyCtxt < ' _ , ' _ , ' _ > ) -> Self {
360361 let mut result = SymbolPathBuffer {
361362 result : String :: with_capacity ( 64 ) ,
362363 temp_buf : String :: with_capacity ( 16 ) ,
363- tcx,
364+ strict_naming : tcx. has_strict_asm_symbol_naming ( ) ,
364365 } ;
365366 result. result . push_str ( & symbol. as_str ( ) ) ;
366367 result
@@ -377,93 +378,88 @@ impl SymbolPathBuffer<'a, 'tcx> {
377378 let _ = write ! ( self . result, "17h{:016x}E" , hash) ;
378379 self . result
379380 }
380- }
381381
382- impl ItemPathBuffer for SymbolPathBuffer < ' a , ' tcx > {
383- fn root_mode ( & self ) -> & RootMode {
384- const ABSOLUTE : & RootMode = & RootMode :: Absolute ;
385- ABSOLUTE
386- }
387-
388- fn push ( & mut self , text : & str ) {
382+ // Name sanitation. LLVM will happily accept identifiers with weird names, but
383+ // gas doesn't!
384+ // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
385+ // NVPTX assembly has more strict naming rules than gas, so additionally, dots
386+ // are replaced with '$' there.
387+ fn sanitize_and_append ( & mut self , s : & str ) {
389388 self . temp_buf . clear ( ) ;
390- let need_underscore = sanitize ( & mut self . temp_buf , text, self . tcx ) ;
389+
390+ for c in s. chars ( ) {
391+ match c {
392+ // Escape these with $ sequences
393+ '@' => self . temp_buf . push_str ( "$SP$" ) ,
394+ '*' => self . temp_buf . push_str ( "$BP$" ) ,
395+ '&' => self . temp_buf . push_str ( "$RF$" ) ,
396+ '<' => self . temp_buf . push_str ( "$LT$" ) ,
397+ '>' => self . temp_buf . push_str ( "$GT$" ) ,
398+ '(' => self . temp_buf . push_str ( "$LP$" ) ,
399+ ')' => self . temp_buf . push_str ( "$RP$" ) ,
400+ ',' => self . temp_buf . push_str ( "$C$" ) ,
401+
402+ '-' | ':' => if self . strict_naming {
403+ // NVPTX doesn't support these characters in symbol names.
404+ self . temp_buf . push ( '$' )
405+ }
406+ else {
407+ // '.' doesn't occur in types and functions, so reuse it
408+ // for ':' and '-'
409+ self . temp_buf . push ( '.' )
410+ } ,
411+
412+ '.' => if self . strict_naming {
413+ self . temp_buf . push ( '$' )
414+ }
415+ else {
416+ self . temp_buf . push ( '.' )
417+ } ,
418+
419+ // These are legal symbols
420+ 'a' ..='z' | 'A' ..='Z' | '0' ..='9' | '_' | '$' => self . temp_buf . push ( c) ,
421+
422+ _ => {
423+ self . temp_buf . push ( '$' ) ;
424+ for c in c. escape_unicode ( ) . skip ( 1 ) {
425+ match c {
426+ '{' => { }
427+ '}' => self . temp_buf . push ( '$' ) ,
428+ c => self . temp_buf . push ( c) ,
429+ }
430+ }
431+ }
432+ }
433+ }
434+
435+ let need_underscore = {
436+ // Underscore-qualify anything that didn't start as an ident.
437+ !self . temp_buf . is_empty ( )
438+ && self . temp_buf . as_bytes ( ) [ 0 ] != '_' as u8
439+ && !( self . temp_buf . as_bytes ( ) [ 0 ] as char ) . is_xid_start ( )
440+ } ;
441+
391442 let _ = write ! (
392443 self . result,
393444 "{}" ,
394445 self . temp_buf. len( ) + ( need_underscore as usize )
395446 ) ;
447+
396448 if need_underscore {
397449 self . result . push ( '_' ) ;
398450 }
451+
399452 self . result . push_str ( & self . temp_buf ) ;
400453 }
401454}
402455
403- // Manual Debug implementation to omit non-Debug `tcx` field.
404- impl fmt:: Debug for SymbolPathBuffer < ' _ , ' _ > {
405- fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
406- fmt. debug_struct ( "SymbolPathBuffer" )
407- . field ( "result" , & self . result )
408- . field ( "temp_buf" , & self . temp_buf )
409- . finish ( )
456+ impl ItemPathBuffer for SymbolPathBuffer {
457+ fn root_mode ( & self ) -> & RootMode {
458+ const ABSOLUTE : & RootMode = & RootMode :: Absolute ;
459+ ABSOLUTE
410460 }
411- }
412-
413- // Name sanitation. LLVM will happily accept identifiers with weird names, but
414- // gas doesn't!
415- // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
416- // NVPTX assembly has more strict naming rules than gas, so additionally, dots
417- // are replaced with '$' there.
418- //
419- // returns true if an underscore must be added at the start
420- pub fn sanitize ( result : & mut String , s : & str , tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> bool {
421- for c in s. chars ( ) {
422- match c {
423- // Escape these with $ sequences
424- '@' => result. push_str ( "$SP$" ) ,
425- '*' => result. push_str ( "$BP$" ) ,
426- '&' => result. push_str ( "$RF$" ) ,
427- '<' => result. push_str ( "$LT$" ) ,
428- '>' => result. push_str ( "$GT$" ) ,
429- '(' => result. push_str ( "$LP$" ) ,
430- ')' => result. push_str ( "$RP$" ) ,
431- ',' => result. push_str ( "$C$" ) ,
432-
433- '-' | ':' => if tcx. has_strict_asm_symbol_naming ( ) {
434- // NVPTX doesn't support these characters in symbol names.
435- result. push ( '$' )
436- }
437- else {
438- // '.' doesn't occur in types and functions, so reuse it
439- // for ':' and '-'
440- result. push ( '.' )
441- } ,
442-
443- '.' => if tcx. has_strict_asm_symbol_naming ( ) {
444- result. push ( '$' )
445- }
446- else {
447- result. push ( '.' )
448- } ,
449-
450- // These are legal symbols
451- 'a' ..='z' | 'A' ..='Z' | '0' ..='9' | '_' | '$' => result. push ( c) ,
452461
453- _ => {
454- result. push ( '$' ) ;
455- for c in c. escape_unicode ( ) . skip ( 1 ) {
456- match c {
457- '{' => { }
458- '}' => result. push ( '$' ) ,
459- c => result. push ( c) ,
460- }
461- }
462- }
463- }
462+ fn push ( & mut self , text : & str ) {
463+ self . sanitize_and_append ( text) ;
464464 }
465-
466- // Underscore-qualify anything that didn't start as an ident.
467- !result. is_empty ( ) && result. as_bytes ( ) [ 0 ] != '_' as u8
468- && !( result. as_bytes ( ) [ 0 ] as char ) . is_xid_start ( )
469465}
0 commit comments