@@ -103,7 +103,7 @@ use rustc_mir::monomorphize::Instance;
103103
104104use syntax_pos:: symbol:: Symbol ;
105105
106- use std:: fmt:: Write ;
106+ use std:: fmt:: { self , Write } ;
107107use std:: mem:: discriminant;
108108
109109pub fn provide ( providers : & mut Providers ) {
@@ -221,7 +221,7 @@ fn get_symbol_hash<'a, 'tcx>(
221221}
222222
223223fn def_symbol_name < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> ty:: SymbolName {
224- let mut buffer = SymbolPathBuffer :: new ( ) ;
224+ let mut buffer = SymbolPathBuffer :: new ( tcx ) ;
225225 item_path:: with_forced_absolute_paths ( || {
226226 tcx. push_item_path ( & mut buffer, def_id, false ) ;
227227 } ) ;
@@ -317,7 +317,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
317317
318318 let hash = get_symbol_hash ( tcx, def_id, instance, instance_ty, substs) ;
319319
320- let mut buf = SymbolPathBuffer :: from_interned ( tcx. def_symbol_name ( def_id) ) ;
320+ let mut buf = SymbolPathBuffer :: from_interned ( tcx. def_symbol_name ( def_id) , tcx ) ;
321321
322322 if instance. is_vtable_shim ( ) {
323323 buf. push ( "{{vtable-shim}}" ) ;
@@ -339,26 +339,28 @@ 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- # [ derive ( Debug ) ]
343- struct SymbolPathBuffer {
342+ struct SymbolPathBuffer < ' a , ' tcx > {
343+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
344344 result : String ,
345345 temp_buf : String ,
346346}
347347
348- impl SymbolPathBuffer {
349- fn new ( ) -> Self {
348+ impl SymbolPathBuffer < ' a , ' tcx > {
349+ fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> Self {
350350 let mut result = SymbolPathBuffer {
351351 result : String :: with_capacity ( 64 ) ,
352352 temp_buf : String :: with_capacity ( 16 ) ,
353+ tcx,
353354 } ;
354355 result. result . push_str ( "_ZN" ) ; // _Z == Begin name-sequence, N == nested
355356 result
356357 }
357358
358- fn from_interned ( symbol : ty:: SymbolName ) -> Self {
359+ fn from_interned ( symbol : ty:: SymbolName , tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> Self {
359360 let mut result = SymbolPathBuffer {
360361 result : String :: with_capacity ( 64 ) ,
361362 temp_buf : String :: with_capacity ( 16 ) ,
363+ tcx,
362364 } ;
363365 result. result . push_str ( & symbol. as_str ( ) ) ;
364366 result
@@ -377,15 +379,15 @@ impl SymbolPathBuffer {
377379 }
378380}
379381
380- impl ItemPathBuffer for SymbolPathBuffer {
382+ impl ItemPathBuffer for SymbolPathBuffer < ' a , ' tcx > {
381383 fn root_mode ( & self ) -> & RootMode {
382384 const ABSOLUTE : & RootMode = & RootMode :: Absolute ;
383385 ABSOLUTE
384386 }
385387
386388 fn push ( & mut self , text : & str ) {
387389 self . temp_buf . clear ( ) ;
388- let need_underscore = sanitize ( & mut self . temp_buf , text) ;
390+ let need_underscore = sanitize ( & mut self . temp_buf , text, self . tcx ) ;
389391 let _ = write ! (
390392 self . result,
391393 "{}" ,
@@ -398,12 +400,24 @@ impl ItemPathBuffer for SymbolPathBuffer {
398400 }
399401}
400402
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 ( )
410+ }
411+ }
412+
401413// Name sanitation. LLVM will happily accept identifiers with weird names, but
402414// gas doesn't!
403415// 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.
404418//
405419// returns true if an underscore must be added at the start
406- pub fn sanitize ( result : & mut String , s : & str ) -> bool {
420+ pub fn sanitize ( result : & mut String , s : & str , tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> bool {
407421 for c in s. chars ( ) {
408422 match c {
409423 // Escape these with $ sequences
@@ -416,12 +430,25 @@ pub fn sanitize(result: &mut String, s: &str) -> bool {
416430 ')' => result. push_str ( "$RP$" ) ,
417431 ',' => result. push_str ( "$C$" ) ,
418432
419- // '.' doesn't occur in types and functions, so reuse it
420- // for ':' and '-'
421- '-' | ':' => result. push ( '.' ) ,
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+ } ,
422449
423450 // These are legal symbols
424- 'a' ..='z' | 'A' ..='Z' | '0' ..='9' | '_' | '.' | ' $' => result. push ( c) ,
451+ 'a' ..='z' | 'A' ..='Z' | '0' ..='9' | '_' | '$' => result. push ( c) ,
425452
426453 _ => {
427454 result. push ( '$' ) ;
0 commit comments