@@ -4965,6 +4965,63 @@ impl<'a> Hash for &'a TemplateParam {
49654965 }
49664966}
49674967
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+
49685025/// The `<template-template-param>` production.
49695026///
49705027/// ```text
@@ -6964,7 +7021,7 @@ impl Parse for Discriminator {
69647021/// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
69657022/// ```
69667023#[ derive( Clone , Debug , PartialEq , Eq ) ]
6967- pub struct ClosureTypeName ( LambdaSig , Option < usize > ) ;
7024+ pub struct ClosureTypeName ( Vec < TemplateParamDecl > , LambdaSig , Option < usize > ) ;
69687025
69697026impl Parse for ClosureTypeName {
69707027 fn parse < ' a , ' b > (
@@ -6974,7 +7031,13 @@ impl Parse for ClosureTypeName {
69747031 ) -> Result < ( ClosureTypeName , IndexStr < ' b > ) > {
69757032 try_begin_parse ! ( "ClosureTypeName" , ctx, input) ;
69767033
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+ }
69787041 let ( sig, tail) = LambdaSig :: parse ( ctx, subs, tail) ?;
69797042 let tail = consume ( b"E" , tail) ?;
69807043 let ( num, tail) = if let Ok ( ( num, tail) ) = parse_number ( 10 , false , tail) {
@@ -6983,7 +7046,7 @@ impl Parse for ClosureTypeName {
69837046 ( None , tail)
69847047 } ;
69857048 let tail = consume ( b"_" , tail) ?;
6986- Ok ( ( ClosureTypeName ( sig, num) , tail) )
7049+ Ok ( ( ClosureTypeName ( params , sig, num) , tail) )
69877050 }
69887051}
69897052
@@ -6998,9 +7061,24 @@ where
69987061 ) -> fmt:: Result {
69997062 let ctx = try_begin_demangle ! ( self , ctx, scope) ;
70007063
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 ) ) ?;
70047082 Ok ( ( ) )
70057083 }
70067084}
@@ -10391,11 +10469,11 @@ mod tests {
1039110469 assert_parse ! ( ClosureTypeName {
1039210470 Ok => {
1039310471 b"UlvE_..." => {
10394- ClosureTypeName ( LambdaSig ( vec![ ] ) , None ) ,
10472+ ClosureTypeName ( vec! [ ] , LambdaSig ( vec![ ] ) , None ) ,
1039510473 b"..."
1039610474 }
1039710475 b"UlvE36_..." => {
10398- ClosureTypeName ( LambdaSig ( vec![ ] ) , Some ( 36 ) ) ,
10476+ ClosureTypeName ( vec! [ ] , LambdaSig ( vec![ ] ) , Some ( 36 ) ) ,
1039910477 b"..."
1040010478 }
1040110479 }
@@ -10919,6 +10997,7 @@ mod tests {
1091910997 b"UllE_..." => {
1092010998 UnqualifiedName :: ClosureType (
1092110999 ClosureTypeName (
11000+ vec![ ] ,
1092211001 LambdaSig ( vec![
1092311002 TypeHandle :: Builtin (
1092411003 BuiltinType :: Standard (
0 commit comments