@@ -4965,6 +4965,63 @@ impl<'a> Hash for &'a TemplateParam {
4965
4965
}
4966
4966
}
4967
4967
4968
+ /// The `<template-param-decl>` production.
4969
+ ///
4970
+ /// ```text
4971
+ /// <template-param-decl> ::= Ty # type parameter
4972
+ /// ::= Tn <type> # non-type parameter
4973
+ /// ::= Tt <template-param-decl>* E # template parameter
4974
+ /// ::= Tp <template-param-decl> # parameter pack
4975
+ /// ```
4976
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
4977
+ pub enum TemplateParamDecl {
4978
+ /// Type Parameter (numbered)
4979
+ Type ( u8 ) ,
4980
+ }
4981
+
4982
+ impl Parse for TemplateParamDecl {
4983
+ fn parse < ' a , ' b > (
4984
+ ctx : & ' a ParseContext ,
4985
+ _subs : & ' a mut SubstitutionTable ,
4986
+ input : IndexStr < ' b > ,
4987
+ ) -> Result < ( TemplateParamDecl , IndexStr < ' b > ) > {
4988
+ try_begin_parse ! ( "TemplateParamDecl" , ctx, input) ;
4989
+
4990
+ let tail = consume ( b"T" , input) ?;
4991
+
4992
+ if let Ok ( tail) = consume ( b"y" , tail) {
4993
+ // TODO: implement a counter
4994
+ return Ok ( ( TemplateParamDecl :: Type ( 0 ) , tail) ) ;
4995
+ }
4996
+
4997
+ // TODO: implement other types as well
4998
+ Err ( error:: Error :: UnexpectedText )
4999
+ }
5000
+ }
5001
+
5002
+ impl < ' subs , W > Demangle < ' subs , W > for TemplateParamDecl
5003
+ where
5004
+ W : ' subs + DemangleWrite ,
5005
+ {
5006
+ fn demangle < ' prev , ' ctx > (
5007
+ & ' subs self ,
5008
+ ctx : & ' ctx mut DemangleContext < ' subs , W > ,
5009
+ scope : Option < ArgScopeStack < ' prev , ' subs > > ,
5010
+ ) -> fmt:: Result {
5011
+ let ctx = try_begin_demangle ! ( self , ctx, scope) ;
5012
+
5013
+ match self {
5014
+ TemplateParamDecl :: Type ( n) => {
5015
+ write ! ( ctx, "typename $T" ) ?;
5016
+ if * n > 0 {
5017
+ write ! ( ctx, "{}" , n - 1 ) ?;
5018
+ }
5019
+ }
5020
+ }
5021
+ Ok ( ( ) )
5022
+ }
5023
+ }
5024
+
4968
5025
/// The `<template-template-param>` production.
4969
5026
///
4970
5027
/// ```text
@@ -6964,7 +7021,7 @@ impl Parse for Discriminator {
6964
7021
/// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
6965
7022
/// ```
6966
7023
#[ derive( Clone , Debug , PartialEq , Eq ) ]
6967
- pub struct ClosureTypeName ( LambdaSig , Option < usize > ) ;
7024
+ pub struct ClosureTypeName ( Vec < TemplateParamDecl > , LambdaSig , Option < usize > ) ;
6968
7025
6969
7026
impl Parse for ClosureTypeName {
6970
7027
fn parse < ' a , ' b > (
@@ -6974,7 +7031,13 @@ impl Parse for ClosureTypeName {
6974
7031
) -> Result < ( ClosureTypeName , IndexStr < ' b > ) > {
6975
7032
try_begin_parse ! ( "ClosureTypeName" , ctx, input) ;
6976
7033
6977
- let tail = consume ( b"Ul" , input) ?;
7034
+ let mut tail = consume ( b"Ul" , input) ?;
7035
+ let mut params = vec ! [ ] ;
7036
+ while let Ok ( _) = consume ( b"T" , tail) {
7037
+ let ( decl, _tail) = TemplateParamDecl :: parse ( ctx, subs, tail) ?;
7038
+ params. push ( decl) ;
7039
+ tail = _tail;
7040
+ }
6978
7041
let ( sig, tail) = LambdaSig :: parse ( ctx, subs, tail) ?;
6979
7042
let tail = consume ( b"E" , tail) ?;
6980
7043
let ( num, tail) = if let Ok ( ( num, tail) ) = parse_number ( 10 , false , tail) {
@@ -6983,7 +7046,7 @@ impl Parse for ClosureTypeName {
6983
7046
( None , tail)
6984
7047
} ;
6985
7048
let tail = consume ( b"_" , tail) ?;
6986
- Ok ( ( ClosureTypeName ( sig, num) , tail) )
7049
+ Ok ( ( ClosureTypeName ( params , sig, num) , tail) )
6987
7050
}
6988
7051
}
6989
7052
@@ -6998,9 +7061,24 @@ where
6998
7061
) -> fmt:: Result {
6999
7062
let ctx = try_begin_demangle ! ( self , ctx, scope) ;
7000
7063
7001
- write ! ( ctx, "{{lambda(" ) ?;
7002
- self . 0 . demangle ( ctx, scope) ?;
7003
- write ! ( ctx, ")#{}}}" , self . 1 . map_or( 1 , |n| n + 2 ) ) ?;
7064
+ // llvm tools format this as:
7065
+ // `'lambda'<typename $T, typename $T0>`
7066
+ write ! ( ctx, "{{lambda" ) ?;
7067
+ if !self . 0 . is_empty ( ) {
7068
+ write ! ( ctx, "<" ) ?;
7069
+ let mut need_comma = false ;
7070
+ for arg in & self . 0 {
7071
+ if need_comma {
7072
+ write ! ( ctx, ", " ) ?;
7073
+ }
7074
+ arg. demangle ( ctx, scope) ?;
7075
+ need_comma = true ;
7076
+ }
7077
+ write ! ( ctx, ">" ) ?;
7078
+ }
7079
+ write ! ( ctx, "(" ) ?;
7080
+ self . 1 . demangle ( ctx, scope) ?;
7081
+ write ! ( ctx, ")#{}}}" , self . 2 . map_or( 1 , |n| n + 2 ) ) ?;
7004
7082
Ok ( ( ) )
7005
7083
}
7006
7084
}
@@ -10391,11 +10469,11 @@ mod tests {
10391
10469
assert_parse ! ( ClosureTypeName {
10392
10470
Ok => {
10393
10471
b"UlvE_..." => {
10394
- ClosureTypeName ( LambdaSig ( vec![ ] ) , None ) ,
10472
+ ClosureTypeName ( vec! [ ] , LambdaSig ( vec![ ] ) , None ) ,
10395
10473
b"..."
10396
10474
}
10397
10475
b"UlvE36_..." => {
10398
- ClosureTypeName ( LambdaSig ( vec![ ] ) , Some ( 36 ) ) ,
10476
+ ClosureTypeName ( vec! [ ] , LambdaSig ( vec![ ] ) , Some ( 36 ) ) ,
10399
10477
b"..."
10400
10478
}
10401
10479
}
@@ -10919,6 +10997,7 @@ mod tests {
10919
10997
b"UllE_..." => {
10920
10998
UnqualifiedName :: ClosureType (
10921
10999
ClosureTypeName (
11000
+ vec![ ] ,
10922
11001
LambdaSig ( vec![
10923
11002
TypeHandle :: Builtin (
10924
11003
BuiltinType :: Standard (
0 commit comments