@@ -556,6 +556,9 @@ where
556556 // argument pack.
557557 is_template_argument_pack : bool ,
558558
559+ // We are currently demangling an object with an explicit named parameter.
560+ is_explicit_obj_param : bool ,
561+
559562 // Whether to show function parameters.
560563 // This must be set to true before calling `demangle` on `Encoding`
561564 // unless that call is via the toplevel call to `MangledName::demangle`.
@@ -615,6 +618,7 @@ where
615618 is_template_prefix : false ,
616619 is_template_prefix_in_nested_name : false ,
617620 is_template_argument_pack : false ,
621+ is_explicit_obj_param : false ,
618622 show_params : !options. no_params ,
619623 show_return_type : !options. no_return_type ,
620624 show_expression_literal_types : !options. hide_expression_literal_types ,
@@ -1036,6 +1040,12 @@ where
10361040 return Ok ( ( ) ) ;
10371041 }
10381042
1043+ // Only the first param should have `this`.
1044+ if ctx. is_explicit_obj_param {
1045+ write ! ( ctx, "this " ) ?;
1046+ ctx. is_explicit_obj_param = false ;
1047+ }
1048+
10391049 let mut need_comma = false ;
10401050 for arg in self . iter ( ) {
10411051 if need_comma {
@@ -1938,6 +1948,8 @@ impl<'a> GetLeafName<'a> for UnscopedTemplateName {
19381948/// ```text
19391949/// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
19401950/// ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
1951+ /// ::= N H <prefix> <unqualified-name> E
1952+ /// ::= N H <template-prefix> <template-args> E
19411953/// ```
19421954#[ derive( Clone , Debug , PartialEq , Eq ) ]
19431955pub enum NestedName {
@@ -1951,6 +1963,16 @@ pub enum NestedName {
19511963
19521964 /// A nested template name. The `<template-args>` are part of the `PrefixHandle`.
19531965 Template ( CvQualifiers , Option < RefQualifier > , PrefixHandle ) ,
1966+
1967+ /// A nested name with an explicit object.
1968+ UnqualifiedExplicitObject (
1969+ Option < PrefixHandle > ,
1970+ UnqualifiedName ,
1971+ ExplicitObjectParameter ,
1972+ ) ,
1973+
1974+ /// A nested template name with an explicit object.
1975+ TemplateExplicitObject ( PrefixHandle , ExplicitObjectParameter ) ,
19541976}
19551977
19561978impl Parse for NestedName {
@@ -1963,19 +1985,29 @@ impl Parse for NestedName {
19631985
19641986 let tail = consume ( b"N" , input) ?;
19651987
1966- let ( cv_qualifiers, tail) =
1967- if let Ok ( ( q, tail) ) = try_recurse ! ( CvQualifiers :: parse( ctx, subs, tail) ) {
1968- ( q, tail)
1969- } else {
1970- ( Default :: default ( ) , tail)
1971- } ;
1988+ let ( cv_qualifiers, ref_qualifier, explicit_obj_param, tail) = match tail. peek ( ) {
1989+ Some ( b'H' ) => {
1990+ let ( explicit_obj_param, tail) = ExplicitObjectParameter :: parse ( ctx, subs, tail) ?;
1991+ ( Default :: default ( ) , None , Some ( explicit_obj_param) , tail)
1992+ }
1993+ _ => {
1994+ let ( cv_qualifiers, tail) =
1995+ if let Ok ( ( q, tail) ) = try_recurse ! ( CvQualifiers :: parse( ctx, subs, tail) ) {
1996+ ( q, tail)
1997+ } else {
1998+ ( Default :: default ( ) , tail)
1999+ } ;
19722000
1973- let ( ref_qualifier, tail) =
1974- if let Ok ( ( r, tail) ) = try_recurse ! ( RefQualifier :: parse( ctx, subs, tail) ) {
1975- ( Some ( r) , tail)
1976- } else {
1977- ( None , tail)
1978- } ;
2001+ let ( ref_qualifier, tail) =
2002+ if let Ok ( ( r, tail) ) = try_recurse ! ( RefQualifier :: parse( ctx, subs, tail) ) {
2003+ ( Some ( r) , tail)
2004+ } else {
2005+ ( None , tail)
2006+ } ;
2007+
2008+ ( cv_qualifiers, ref_qualifier, None , tail)
2009+ }
2010+ } ;
19792011
19802012 let ( prefix, tail) = PrefixHandle :: parse ( ctx, subs, tail) ?;
19812013 let tail = consume ( b"E" , tail) ?;
@@ -1986,12 +2018,12 @@ impl Parse for NestedName {
19862018 PrefixHandle :: WellKnown ( _) => None ,
19872019 } ;
19882020
1989- match substitutable {
1990- Some ( & Substitutable :: Prefix ( Prefix :: Unqualified ( ref name) ) ) => Ok ( (
2021+ match ( substitutable, explicit_obj_param ) {
2022+ ( Some ( & Substitutable :: Prefix ( Prefix :: Unqualified ( ref name) ) ) , None ) => Ok ( (
19912023 NestedName :: Unqualified ( cv_qualifiers, ref_qualifier, None , name. clone ( ) ) ,
19922024 tail,
19932025 ) ) ,
1994- Some ( & Substitutable :: Prefix ( Prefix :: Nested ( ref prefix, ref name) ) ) => Ok ( (
2026+ ( Some ( & Substitutable :: Prefix ( Prefix :: Nested ( ref prefix, ref name) ) ) , None ) => Ok ( (
19952027 NestedName :: Unqualified (
19962028 cv_qualifiers,
19972029 ref_qualifier,
@@ -2000,20 +2032,38 @@ impl Parse for NestedName {
20002032 ) ,
20012033 tail,
20022034 ) ) ,
2003- Some ( & Substitutable :: Prefix ( Prefix :: Template ( ..) ) ) => Ok ( (
2035+ ( Some ( & Substitutable :: Prefix ( Prefix :: Template ( ..) ) ) , None ) => Ok ( (
20042036 NestedName :: Template ( cv_qualifiers, ref_qualifier, prefix) ,
20052037 tail,
20062038 ) ) ,
2039+ ( Some ( & Substitutable :: Prefix ( Prefix :: Unqualified ( ref name) ) ) , Some ( param) ) => Ok ( (
2040+ NestedName :: UnqualifiedExplicitObject ( None , name. clone ( ) , param) ,
2041+ tail,
2042+ ) ) ,
2043+ ( Some ( & Substitutable :: Prefix ( Prefix :: Nested ( ref prefix, ref name) ) ) , Some ( param) ) => {
2044+ Ok ( (
2045+ NestedName :: UnqualifiedExplicitObject (
2046+ Some ( prefix. clone ( ) ) ,
2047+ name. clone ( ) ,
2048+ param,
2049+ ) ,
2050+ tail,
2051+ ) )
2052+ }
2053+ ( Some ( & Substitutable :: Prefix ( Prefix :: Template ( ..) ) ) , Some ( param) ) => {
2054+ Ok ( ( NestedName :: TemplateExplicitObject ( prefix, param) , tail) )
2055+ }
20072056 _ => Err ( error:: Error :: UnexpectedText ) ,
20082057 }
20092058 }
20102059}
20112060
20122061impl NestedName {
20132062 /// Get the CV-qualifiers for this name.
2014- pub fn cv_qualifiers ( & self ) -> & CvQualifiers {
2063+ pub fn cv_qualifiers ( & self ) -> Option < & CvQualifiers > {
20152064 match * self {
2016- NestedName :: Unqualified ( ref q, ..) | NestedName :: Template ( ref q, ..) => q,
2065+ NestedName :: Unqualified ( ref q, ..) | NestedName :: Template ( ref q, ..) => Some ( q) ,
2066+ _ => None ,
20172067 }
20182068 }
20192069
@@ -2031,8 +2081,20 @@ impl NestedName {
20312081 // conceptually belongs to `<nested-name>`.
20322082 fn prefix ( & self ) -> Option < & PrefixHandle > {
20332083 match * self {
2034- NestedName :: Unqualified ( _, _, ref p, _) => p. as_ref ( ) ,
2035- NestedName :: Template ( _, _, ref p) => Some ( p) ,
2084+ NestedName :: Unqualified ( _, _, ref p, _)
2085+ | NestedName :: UnqualifiedExplicitObject ( ref p, ..) => p. as_ref ( ) ,
2086+ NestedName :: Template ( _, _, ref p) | NestedName :: TemplateExplicitObject ( ref p, _) => {
2087+ Some ( p)
2088+ }
2089+ }
2090+ }
2091+
2092+ /// Check to see if the object has an explicit named parameter.
2093+ pub fn has_explicit_obj_param ( & self ) -> bool {
2094+ match * self {
2095+ NestedName :: UnqualifiedExplicitObject ( _, _, ref _e)
2096+ | NestedName :: TemplateExplicitObject ( _, ref _e) => true ,
2097+ _ => false ,
20362098 }
20372099 }
20382100}
@@ -2049,7 +2111,8 @@ where
20492111 let ctx = try_begin_demangle ! ( self , ctx, scope) ;
20502112
20512113 match * self {
2052- NestedName :: Unqualified ( _, _, ref p, ref name) => {
2114+ NestedName :: Unqualified ( _, _, ref p, ref name)
2115+ | NestedName :: UnqualifiedExplicitObject ( ref p, ref name, _) => {
20532116 ctx. push_demangle_node ( DemangleNodeType :: NestedName ) ;
20542117 if let Some ( p) = p. as_ref ( ) {
20552118 p. demangle ( ctx, scope) ?;
@@ -2058,19 +2121,25 @@ where
20582121 name. demangle ( ctx, scope) ?;
20592122 ctx. pop_demangle_node ( ) ;
20602123 }
2061- NestedName :: Template ( _, _, ref p) => {
2124+ NestedName :: Template ( _, _, ref p) | NestedName :: TemplateExplicitObject ( ref p , _ ) => {
20622125 ctx. is_template_prefix_in_nested_name = true ;
20632126 p. demangle ( ctx, scope) ?;
20642127 ctx. is_template_prefix_in_nested_name = false ;
20652128 }
20662129 }
20672130
2131+ if self . has_explicit_obj_param ( ) {
2132+ ctx. is_explicit_obj_param = true ;
2133+ }
2134+
20682135 if let Some ( inner) = ctx. pop_inner ( ) {
20692136 inner. demangle_as_inner ( ctx, scope) ?;
20702137 }
20712138
2072- if self . cv_qualifiers ( ) != & CvQualifiers :: default ( ) && ctx. show_params {
2073- self . cv_qualifiers ( ) . demangle ( ctx, scope) ?;
2139+ if let Some ( cv_qualifiers) = self . cv_qualifiers ( ) {
2140+ if cv_qualifiers != & CvQualifiers :: default ( ) && ctx. show_params {
2141+ cv_qualifiers. demangle ( ctx, scope) ?;
2142+ }
20742143 }
20752144
20762145 if let Some ( ref refs) = self . ref_qualifier ( ) {
@@ -2085,7 +2154,8 @@ where
20852154impl GetTemplateArgs for NestedName {
20862155 fn get_template_args < ' a > ( & ' a self , subs : & ' a SubstitutionTable ) -> Option < & ' a TemplateArgs > {
20872156 match * self {
2088- NestedName :: Template ( _, _, ref prefix) => prefix. get_template_args ( subs) ,
2157+ NestedName :: Template ( _, _, ref prefix)
2158+ | NestedName :: TemplateExplicitObject ( ref prefix, _) => prefix. get_template_args ( subs) ,
20892159 _ => None ,
20902160 }
20912161 }
@@ -2094,10 +2164,12 @@ impl GetTemplateArgs for NestedName {
20942164impl < ' a > GetLeafName < ' a > for NestedName {
20952165 fn get_leaf_name ( & ' a self , subs : & ' a SubstitutionTable ) -> Option < LeafName < ' a > > {
20962166 match * self {
2097- NestedName :: Unqualified ( _, _, ref prefix, ref name) => name
2167+ NestedName :: Unqualified ( _, _, ref prefix, ref name)
2168+ | NestedName :: UnqualifiedExplicitObject ( ref prefix, ref name, _) => name
20982169 . get_leaf_name ( subs)
20992170 . or_else ( || prefix. as_ref ( ) . and_then ( |p| p. get_leaf_name ( subs) ) ) ,
2100- NestedName :: Template ( _, _, ref prefix) => prefix. get_leaf_name ( subs) ,
2171+ NestedName :: Template ( _, _, ref prefix)
2172+ | NestedName :: TemplateExplicitObject ( ref prefix, _) => prefix. get_leaf_name ( subs) ,
21012173 }
21022174 }
21032175}
@@ -4064,6 +4136,14 @@ define_vocabulary! {
40644136 }
40654137}
40664138
4139+ define_vocabulary ! {
4140+ /// A named explicit object parameter.
4141+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
4142+ pub enum ExplicitObjectParameter {
4143+ ExplicitObjectParameter ( b"H" , "this" )
4144+ }
4145+ }
4146+
40674147define_vocabulary ! {
40684148 /// A one of the standard variants of the <builtin-type> production.
40694149 ///
0 commit comments