@@ -7265,6 +7265,7 @@ where
7265
7265
/// ::= TF <type> # typinfo function
7266
7266
/// ::= TH <name> # TLS initialization function
7267
7267
/// ::= TW <name> # TLS wrapper function
7268
+ /// ::= Gr <resource name> # Java Resource
7268
7269
/// ```
7269
7270
#[ derive( Clone , Debug , PartialEq , Eq ) ]
7270
7271
pub enum SpecialName {
@@ -7304,6 +7305,9 @@ pub enum SpecialName {
7304
7305
7305
7306
/// A TLS wrapper function.
7306
7307
TlsWrapper ( Name ) ,
7308
+
7309
+ /// A Java Resource.
7310
+ JavaResource ( Vec < ResourceName > ) ,
7307
7311
}
7308
7312
7309
7313
impl Parse for SpecialName {
@@ -7393,6 +7397,26 @@ impl Parse for SpecialName {
7393
7397
} ;
7394
7398
Ok ( ( SpecialName :: GuardTemporary ( name, idx) , tail) )
7395
7399
}
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
+ }
7396
7420
_ => Err ( error:: Error :: UnexpectedText ) ,
7397
7421
}
7398
7422
}
@@ -7480,10 +7504,100 @@ where
7480
7504
write ! ( ctx, "TLS wrapper function for " ) ?;
7481
7505
name. demangle ( ctx, scope)
7482
7506
}
7507
+ SpecialName :: JavaResource ( ref names) => {
7508
+ write ! ( ctx, "java resource " ) ?;
7509
+ for name in names {
7510
+ name. demangle ( ctx, scope) ?;
7511
+ }
7512
+ Ok ( ( ) )
7513
+ }
7483
7514
}
7484
7515
}
7485
7516
}
7486
7517
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
+ }
7487
7601
/// Expect and consume the given byte str, and return the advanced `IndexStr` if
7488
7602
/// we saw the expectation. Otherwise return an error of kind
7489
7603
/// `error::Error::UnexpectedText` if the input doesn't match, or
@@ -7598,7 +7712,7 @@ mod tests {
7598
7712
FunctionParam , FunctionType , GlobalCtorDtor , Identifier , Initializer , LambdaSig ,
7599
7713
LocalName , MangledName , MemberName , Name , NestedName , NonSubstitution , Number ,
7600
7714
NvOffset , OperatorName , Parse , ParseContext , PointerToMemberType , Prefix ,
7601
- PrefixHandle , RefQualifier , SeqId , SimpleId , SimpleOperatorName , SourceName ,
7715
+ PrefixHandle , RefQualifier , ResourceName , SeqId , SimpleId , SimpleOperatorName , SourceName ,
7602
7716
SpecialName , StandardBuiltinType , Substitution , TaggedName , TemplateArg ,
7603
7717
TemplateArgs , TemplateParam , TemplateTemplateParam , TemplateTemplateParamHandle ,
7604
7718
Type , TypeHandle , UnnamedTypeName , UnqualifiedName , UnresolvedName ,
@@ -10398,6 +10512,13 @@ mod tests {
10398
10512
1 ) ,
10399
10513
b"..."
10400
10514
}
10515
+ b"Gr4_abc..." => {
10516
+ SpecialName :: JavaResource ( vec![ ResourceName {
10517
+ start: 4 ,
10518
+ end: 7 ,
10519
+ } ] ) ,
10520
+ b"..."
10521
+ }
10401
10522
b"TCc7_i..." => {
10402
10523
SpecialName :: ConstructionVtable (
10403
10524
TypeHandle :: Builtin ( BuiltinType :: Standard ( StandardBuiltinType :: Char ) ) ,
@@ -10440,6 +10561,7 @@ mod tests {
10440
10561
b"GR3abc0" => Error :: UnexpectedEnd ,
10441
10562
// This number is not allowed to be negative.
10442
10563
b"TCcn7_i..." => Error :: UnexpectedText ,
10564
+ b"Gr3abc0" => Error :: UnexpectedText ,
10443
10565
}
10444
10566
} ) ;
10445
10567
}
0 commit comments