@@ -7265,6 +7265,7 @@ where
72657265/// ::= TF <type> # typinfo function
72667266/// ::= TH <name> # TLS initialization function
72677267/// ::= TW <name> # TLS wrapper function
7268+ /// ::= Gr <resource name> # Java Resource
72687269/// ```
72697270#[ derive( Clone , Debug , PartialEq , Eq ) ]
72707271pub enum SpecialName {
@@ -7304,6 +7305,9 @@ pub enum SpecialName {
73047305
73057306 /// A TLS wrapper function.
73067307 TlsWrapper ( Name ) ,
7308+
7309+ /// A Java Resource.
7310+ JavaResource ( Vec < ResourceName > ) ,
73077311}
73087312
73097313impl Parse for SpecialName {
@@ -7393,6 +7397,26 @@ impl Parse for SpecialName {
73937397 } ;
73947398 Ok ( ( SpecialName :: GuardTemporary ( name, idx) , tail) )
73957399 }
7400+ b"Gr" => {
7401+ let ( resource_name_len, tail) = parse_number ( 10 , false , tail) ?;
7402+ if resource_name_len == 0 {
7403+ return Err ( error:: Error :: UnexpectedText ) ;
7404+ }
7405+
7406+ let ( head, tail) = match tail. try_split_at ( resource_name_len as _ ) {
7407+ Some ( ( head, tail) ) => ( head, tail) ,
7408+ None => return Err ( error:: Error :: UnexpectedEnd ) ,
7409+ } ;
7410+
7411+ let head = consume ( b"_" , head) ?;
7412+
7413+ let ( resource_names, empty) = zero_or_more :: < ResourceName > ( ctx, subs, head) ?;
7414+ if !empty. is_empty ( ) {
7415+ return Err ( error:: Error :: UnexpectedText ) ;
7416+ }
7417+
7418+ Ok ( ( SpecialName :: JavaResource ( resource_names) , tail) )
7419+ }
73967420 _ => Err ( error:: Error :: UnexpectedText ) ,
73977421 }
73987422 }
@@ -7480,10 +7504,100 @@ where
74807504 write ! ( ctx, "TLS wrapper function for " ) ?;
74817505 name. demangle ( ctx, scope)
74827506 }
7507+ SpecialName :: JavaResource ( ref names) => {
7508+ write ! ( ctx, "java resource " ) ?;
7509+ for name in names {
7510+ name. demangle ( ctx, scope) ?;
7511+ }
7512+ Ok ( ( ) )
7513+ }
74837514 }
74847515 }
74857516}
74867517
7518+ /// The `<resource name>` pseudo-terminal.
7519+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
7520+ pub struct ResourceName {
7521+ start : usize ,
7522+ end : usize ,
7523+ }
7524+
7525+ impl Parse for ResourceName {
7526+ fn parse < ' a , ' b > (
7527+ ctx : & ' a ParseContext ,
7528+ _subs : & ' a mut SubstitutionTable ,
7529+ input : IndexStr < ' b > ,
7530+ ) -> Result < ( ResourceName , IndexStr < ' b > ) > {
7531+ try_begin_parse ! ( "ResourceName" , ctx, input) ;
7532+
7533+ if input. is_empty ( ) {
7534+ return Err ( error:: Error :: UnexpectedEnd ) ;
7535+ }
7536+
7537+ let mut end = input
7538+ . as_ref ( )
7539+ . iter ( )
7540+ . map ( |& c| c as char )
7541+ . take_while ( |& c| c != '$' || c. is_digit ( 36 ) )
7542+ . count ( ) ;
7543+
7544+ if end == 0 {
7545+ return Err ( error:: Error :: UnexpectedText ) ;
7546+ }
7547+
7548+ if input. range_from ( end..) . peek ( ) == Some ( b'$' ) {
7549+ match input. range_from ( end..) . peek_second ( ) {
7550+ Some ( b'S' ) | Some ( b'_' ) | Some ( b'$' ) => end += 2 ,
7551+ _ => return Err ( error:: Error :: UnexpectedText )
7552+ }
7553+ }
7554+
7555+ let tail = input. range_from ( end..) ;
7556+
7557+ let resource_name = ResourceName {
7558+ start : input. index ( ) ,
7559+ end : tail. index ( ) ,
7560+ } ;
7561+
7562+ Ok ( ( resource_name, tail) )
7563+ }
7564+ }
7565+
7566+ impl < ' subs , W > Demangle < ' subs , W > for ResourceName
7567+ where
7568+ W : ' subs + DemangleWrite ,
7569+ {
7570+ #[ inline]
7571+ fn demangle < ' prev , ' ctx > (
7572+ & ' subs self ,
7573+ ctx : & ' ctx mut DemangleContext < ' subs , W > ,
7574+ scope : Option < ArgScopeStack < ' prev , ' subs > > ,
7575+ ) -> fmt:: Result {
7576+ let ctx = try_begin_demangle ! ( self , ctx, scope) ;
7577+
7578+ let mut i = self . start ;
7579+ while i < self . end {
7580+ let ch = ctx. input [ i] ;
7581+ if ch == b'$' {
7582+ // Skip past the '$'
7583+ i += 1 ;
7584+ match ctx. input [ i] {
7585+ b'S' => write ! ( ctx, "{}" , '/' ) ?,
7586+ b'_' => write ! ( ctx, "{}" , '.' ) ?,
7587+ b'$' => write ! ( ctx, "{}" , '$' ) ?,
7588+ _ => {
7589+ // Fall through
7590+ } ,
7591+ }
7592+ } else {
7593+ write ! ( ctx, "{}" , ch as char ) ?;
7594+ }
7595+ i += 1 ;
7596+ }
7597+
7598+ Ok ( ( ) )
7599+ }
7600+ }
74877601/// Expect and consume the given byte str, and return the advanced `IndexStr` if
74887602/// we saw the expectation. Otherwise return an error of kind
74897603/// `error::Error::UnexpectedText` if the input doesn't match, or
@@ -7598,7 +7712,7 @@ mod tests {
75987712 FunctionParam , FunctionType , GlobalCtorDtor , Identifier , Initializer , LambdaSig ,
75997713 LocalName , MangledName , MemberName , Name , NestedName , NonSubstitution , Number ,
76007714 NvOffset , OperatorName , Parse , ParseContext , PointerToMemberType , Prefix ,
7601- PrefixHandle , RefQualifier , SeqId , SimpleId , SimpleOperatorName , SourceName ,
7715+ PrefixHandle , RefQualifier , ResourceName , SeqId , SimpleId , SimpleOperatorName , SourceName ,
76027716 SpecialName , StandardBuiltinType , Substitution , TaggedName , TemplateArg ,
76037717 TemplateArgs , TemplateParam , TemplateTemplateParam , TemplateTemplateParamHandle ,
76047718 Type , TypeHandle , UnnamedTypeName , UnqualifiedName , UnresolvedName ,
@@ -10398,6 +10512,13 @@ mod tests {
1039810512 1 ) ,
1039910513 b"..."
1040010514 }
10515+ b"Gr4_abc..." => {
10516+ SpecialName :: JavaResource ( vec![ ResourceName {
10517+ start: 4 ,
10518+ end: 7 ,
10519+ } ] ) ,
10520+ b"..."
10521+ }
1040110522 b"TCc7_i..." => {
1040210523 SpecialName :: ConstructionVtable (
1040310524 TypeHandle :: Builtin ( BuiltinType :: Standard ( StandardBuiltinType :: Char ) ) ,
@@ -10440,6 +10561,7 @@ mod tests {
1044010561 b"GR3abc0" => Error :: UnexpectedEnd ,
1044110562 // This number is not allowed to be negative.
1044210563 b"TCcn7_i..." => Error :: UnexpectedText ,
10564+ b"Gr3abc0" => Error :: UnexpectedText ,
1044310565 }
1044410566 } ) ;
1044510567 }
0 commit comments