@@ -1932,6 +1932,287 @@ func (sa *SizeofArgs) goString(indent int, field string) string {
19321932 return fmt .Sprintf ("%*s%sSizeofArgs:\n %s" , indent , "" , field , args )
19331933}
19341934
1935+ // TemplateParamName is the name of a template parameter that the
1936+ // demangler introduced for a lambda that has explicit template
1937+ // parameters. This is a prefix with an index.
1938+ type TemplateParamName struct {
1939+ Prefix string
1940+ Index int
1941+ }
1942+
1943+ func (tpn * TemplateParamName ) print (ps * printState ) {
1944+ ps .writeString (tpn .Prefix )
1945+ if tpn .Index > 0 {
1946+ ps .writeString (fmt .Sprintf ("%d" , tpn .Index - 1 ))
1947+ }
1948+ }
1949+
1950+ func (tpn * TemplateParamName ) Traverse (fn func (AST ) bool ) {
1951+ fn (tpn )
1952+ }
1953+
1954+ func (tpn * TemplateParamName ) Copy (fn func (AST ) AST , skip func (AST ) bool ) AST {
1955+ if skip (tpn ) {
1956+ return nil
1957+ }
1958+ return fn (tpn )
1959+ }
1960+
1961+ func (tpn * TemplateParamName ) GoString () string {
1962+ return tpn .goString (0 , "" )
1963+ }
1964+
1965+ func (tpn * TemplateParamName ) goString (indent int , field string ) string {
1966+ name := tpn .Prefix
1967+ if tpn .Index > 0 {
1968+ name += fmt .Sprintf ("%d" , tpn .Index - 1 )
1969+ }
1970+ return fmt .Sprintf ("%*s%sTemplateParamName: %s" , indent , "" , field , name )
1971+ }
1972+
1973+ // TypeTemplateParam is a type template parameter that appears in a
1974+ // lambda with explicit template parameters.
1975+ type TypeTemplateParam struct {
1976+ Name AST
1977+ }
1978+
1979+ func (ttp * TypeTemplateParam ) print (ps * printState ) {
1980+ ps .writeString ("typename " )
1981+ ps .printInner (false )
1982+ ps .print (ttp .Name )
1983+ }
1984+
1985+ func (ttp * TypeTemplateParam ) Traverse (fn func (AST ) bool ) {
1986+ if fn (ttp ) {
1987+ ttp .Name .Traverse (fn )
1988+ }
1989+ }
1990+
1991+ func (ttp * TypeTemplateParam ) Copy (fn func (AST ) AST , skip func (AST ) bool ) AST {
1992+ if skip (ttp ) {
1993+ return nil
1994+ }
1995+ name := ttp .Name .Copy (fn , skip )
1996+ if name == nil {
1997+ return fn (ttp )
1998+ }
1999+ ttp = & TypeTemplateParam {Name : name }
2000+ if r := fn (ttp ); r != nil {
2001+ return r
2002+ }
2003+ return ttp
2004+ }
2005+
2006+ func (ttp * TypeTemplateParam ) GoString () string {
2007+ return ttp .goString (0 , "" )
2008+ }
2009+
2010+ func (ttp * TypeTemplateParam ) goString (indent int , field string ) string {
2011+ return fmt .Sprintf ("%*s%sTypeTemplateParam:\n %s" , indent , "" , field ,
2012+ ttp .Name .goString (indent + 2 , "Name" ))
2013+ }
2014+
2015+ // NonTypeTemplateParam is a non-type template parameter that appears
2016+ // in a lambda with explicit template parameters.
2017+ type NonTypeTemplateParam struct {
2018+ Name AST
2019+ Type AST
2020+ }
2021+
2022+ func (nttp * NonTypeTemplateParam ) print (ps * printState ) {
2023+ ps .inner = append (ps .inner , nttp )
2024+ ps .print (nttp .Type )
2025+ if len (ps .inner ) > 0 {
2026+ ps .writeByte (' ' )
2027+ ps .print (nttp .Name )
2028+ ps .inner = ps .inner [:len (ps .inner )- 1 ]
2029+ }
2030+ }
2031+
2032+ func (nttp * NonTypeTemplateParam ) printInner (ps * printState ) {
2033+ ps .print (nttp .Name )
2034+ }
2035+
2036+ func (nttp * NonTypeTemplateParam ) Traverse (fn func (AST ) bool ) {
2037+ if fn (nttp ) {
2038+ nttp .Name .Traverse (fn )
2039+ nttp .Type .Traverse (fn )
2040+ }
2041+ }
2042+
2043+ func (nttp * NonTypeTemplateParam ) Copy (fn func (AST ) AST , skip func (AST ) bool ) AST {
2044+ if skip (nttp ) {
2045+ return nil
2046+ }
2047+ name := nttp .Name .Copy (fn , skip )
2048+ typ := nttp .Type .Copy (fn , skip )
2049+ if name == nil && typ == nil {
2050+ return fn (nttp )
2051+ }
2052+ if name == nil {
2053+ name = nttp .Name
2054+ }
2055+ if typ == nil {
2056+ typ = nttp .Type
2057+ }
2058+ nttp = & NonTypeTemplateParam {Name : name , Type : typ }
2059+ if r := fn (nttp ); r != nil {
2060+ return r
2061+ }
2062+ return nttp
2063+ }
2064+
2065+ func (nttp * NonTypeTemplateParam ) GoString () string {
2066+ return nttp .goString (0 , "" )
2067+ }
2068+
2069+ func (nttp * NonTypeTemplateParam ) goString (indent int , field string ) string {
2070+ return fmt .Sprintf ("%*s%sNonTypeTemplateParam:\n %s\n %s" , indent , "" , field ,
2071+ nttp .Name .goString (indent + 2 , "Name: " ),
2072+ nttp .Type .goString (indent + 2 , "Type: " ))
2073+ }
2074+
2075+ // TemplateTemplateParam is a template template parameter that appears
2076+ // in a lambda with explicit template parameters.
2077+ type TemplateTemplateParam struct {
2078+ Name AST
2079+ Params []AST
2080+ }
2081+
2082+ func (ttp * TemplateTemplateParam ) print (ps * printState ) {
2083+ ps .writeString ("template<" )
2084+ for i , param := range ttp .Params {
2085+ if i > 0 {
2086+ ps .writeString (", " )
2087+ }
2088+ ps .print (param )
2089+ }
2090+ ps .writeString ("> typename " )
2091+ ps .print (ttp .Name )
2092+ }
2093+
2094+ func (ttp * TemplateTemplateParam ) Traverse (fn func (AST ) bool ) {
2095+ if fn (ttp ) {
2096+ ttp .Name .Traverse (fn )
2097+ for _ , param := range ttp .Params {
2098+ param .Traverse (fn )
2099+ }
2100+ }
2101+ }
2102+
2103+ func (ttp * TemplateTemplateParam ) Copy (fn func (AST ) AST , skip func (AST ) bool ) AST {
2104+ if skip (ttp ) {
2105+ return nil
2106+ }
2107+
2108+ changed := false
2109+
2110+ name := ttp .Name .Copy (fn , skip )
2111+ if name == nil {
2112+ name = ttp .Name
2113+ } else {
2114+ changed = true
2115+ }
2116+
2117+ params := make ([]AST , len (ttp .Params ))
2118+ for i , p := range ttp .Params {
2119+ pc := p .Copy (fn , skip )
2120+ if pc == nil {
2121+ params [i ] = p
2122+ } else {
2123+ params [i ] = pc
2124+ changed = true
2125+ }
2126+ }
2127+
2128+ if ! changed {
2129+ return fn (ttp )
2130+ }
2131+
2132+ ttp = & TemplateTemplateParam {
2133+ Name : name ,
2134+ Params : params ,
2135+ }
2136+ if r := fn (ttp ); r != nil {
2137+ return r
2138+ }
2139+ return ttp
2140+ }
2141+
2142+ func (ttp * TemplateTemplateParam ) GoString () string {
2143+ return ttp .goString (0 , "" )
2144+ }
2145+
2146+ func (ttp * TemplateTemplateParam ) goString (indent int , field string ) string {
2147+ var params strings.Builder
2148+ fmt .Fprintf (& params , "%*sParams:" , indent + 2 , "" )
2149+ for i , p := range ttp .Params {
2150+ params .WriteByte ('\n' )
2151+ params .WriteString (p .goString (indent + 4 , fmt .Sprintf ("%d: " , i )))
2152+ }
2153+ return fmt .Sprintf ("%*s%sTemplateTemplateParam:\n %s\n %s" , indent , "" , field ,
2154+ ttp .Name .goString (indent + 2 , "Name: " ),
2155+ params .String ())
2156+ }
2157+
2158+ // TemplateParamPack is a template parameter pack that appears in a
2159+ // lambda with explicit template parameters.
2160+ type TemplateParamPack struct {
2161+ Param AST
2162+ }
2163+
2164+ func (tpp * TemplateParamPack ) print (ps * printState ) {
2165+ holdInner := ps .inner
2166+ defer func () { ps .inner = holdInner }()
2167+
2168+ ps .inner = []AST {tpp }
2169+ if nttp , ok := tpp .Param .(* NonTypeTemplateParam ); ok {
2170+ ps .print (nttp .Type )
2171+ } else {
2172+ ps .print (tpp .Param )
2173+ }
2174+ if len (ps .inner ) > 0 {
2175+ ps .writeString ("..." )
2176+ }
2177+ }
2178+
2179+ func (tpp * TemplateParamPack ) printInner (ps * printState ) {
2180+ ps .writeString ("..." )
2181+ if nttp , ok := tpp .Param .(* NonTypeTemplateParam ); ok {
2182+ ps .print (nttp .Name )
2183+ }
2184+ }
2185+
2186+ func (tpp * TemplateParamPack ) Traverse (fn func (AST ) bool ) {
2187+ if fn (tpp ) {
2188+ tpp .Param .Traverse (fn )
2189+ }
2190+ }
2191+
2192+ func (tpp * TemplateParamPack ) Copy (fn func (AST ) AST , skip func (AST ) bool ) AST {
2193+ if skip (tpp ) {
2194+ return nil
2195+ }
2196+ param := tpp .Param .Copy (fn , skip )
2197+ if param == nil {
2198+ return fn (tpp )
2199+ }
2200+ tpp = & TemplateParamPack {Param : param }
2201+ if r := fn (tpp ); r != nil {
2202+ return r
2203+ }
2204+ return tpp
2205+ }
2206+
2207+ func (tpp * TemplateParamPack ) GoString () string {
2208+ return tpp .goString (0 , "" )
2209+ }
2210+
2211+ func (tpp * TemplateParamPack ) goString (indent int , field string ) string {
2212+ return fmt .Sprintf ("%*s%sTemplateParamPack:\n %s" , indent , "" , field ,
2213+ tpp .Param .goString (indent + 2 , "Param: " ))
2214+ }
2215+
19352216// Cast is a type cast.
19362217type Cast struct {
19372218 To AST
@@ -2981,12 +3262,24 @@ func (da *DefaultArg) goString(indent int, field string) string {
29813262
29823263// Closure is a closure, or lambda expression.
29833264type Closure struct {
2984- Types []AST
2985- Num int
3265+ TemplateArgs []AST
3266+ Types []AST
3267+ Num int
29863268}
29873269
29883270func (cl * Closure ) print (ps * printState ) {
2989- ps .writeString ("{lambda(" )
3271+ ps .writeString ("{lambda" )
3272+ if len (cl .TemplateArgs ) > 0 {
3273+ ps .writeString ("<" )
3274+ for i , a := range cl .TemplateArgs {
3275+ if i > 0 {
3276+ ps .writeString (", " )
3277+ }
3278+ ps .print (a )
3279+ }
3280+ ps .writeString (">" )
3281+ }
3282+ ps .writeString ("(" )
29903283 for i , t := range cl .Types {
29913284 if i > 0 {
29923285 ps .writeString (", " )
@@ -2998,6 +3291,9 @@ func (cl *Closure) print(ps *printState) {
29983291
29993292func (cl * Closure ) Traverse (fn func (AST ) bool ) {
30003293 if fn (cl ) {
3294+ for _ , a := range cl .TemplateArgs {
3295+ a .Traverse (fn )
3296+ }
30013297 for _ , t := range cl .Types {
30023298 t .Traverse (fn )
30033299 }
@@ -3008,8 +3304,20 @@ func (cl *Closure) Copy(fn func(AST) AST, skip func(AST) bool) AST {
30083304 if skip (cl ) {
30093305 return nil
30103306 }
3011- types := make ([]AST , len (cl .Types ))
30123307 changed := false
3308+
3309+ args := make ([]AST , len (cl .TemplateArgs ))
3310+ for i , a := range cl .TemplateArgs {
3311+ ac := a .Copy (fn , skip )
3312+ if ac == nil {
3313+ args [i ] = a
3314+ } else {
3315+ args [i ] = ac
3316+ changed = true
3317+ }
3318+ }
3319+
3320+ types := make ([]AST , len (cl .Types ))
30133321 for i , t := range cl .Types {
30143322 tc := t .Copy (fn , skip )
30153323 if tc == nil {
@@ -3019,10 +3327,11 @@ func (cl *Closure) Copy(fn func(AST) AST, skip func(AST) bool) AST {
30193327 changed = true
30203328 }
30213329 }
3330+
30223331 if ! changed {
30233332 return fn (cl )
30243333 }
3025- cl = & Closure {Types : types , Num : cl .Num }
3334+ cl = & Closure {TemplateArgs : args , Types : types , Num : cl .Num }
30263335 if r := fn (cl ); r != nil {
30273336 return r
30283337 }
@@ -3034,6 +3343,16 @@ func (cl *Closure) GoString() string {
30343343}
30353344
30363345func (cl * Closure ) goString (indent int , field string ) string {
3346+ var args string
3347+ if len (cl .TemplateArgs ) == 0 {
3348+ args = fmt .Sprintf ("%*sTemplateArgs: nil" , indent + 2 , "" )
3349+ } else {
3350+ args = fmt .Sprintf ("%*sTemplateArgs:" , indent + 2 , "" )
3351+ for i , a := range cl .TemplateArgs {
3352+ args += "\n "
3353+ args += a .goString (indent + 4 , fmt .Sprintf ("%d: " , i ))
3354+ }
3355+ }
30373356 var types string
30383357 if len (cl .Types ) == 0 {
30393358 types = fmt .Sprintf ("%*sTypes: nil" , indent + 2 , "" )
@@ -3044,7 +3363,8 @@ func (cl *Closure) goString(indent int, field string) string {
30443363 types += t .goString (indent + 4 , fmt .Sprintf ("%d: " , i ))
30453364 }
30463365 }
3047- return fmt .Sprintf ("%*s%sClosure: Num: %d\n %s" , indent , "" , field , cl .Num , types )
3366+ return fmt .Sprintf ("%*s%sClosure: Num: %d\n %s\n %s" , indent , "" , field ,
3367+ cl .Num , args , types )
30483368}
30493369
30503370// UnnamedType is an unnamed type, that just has an index.
0 commit comments