@@ -1932,6 +1932,287 @@ func (sa *SizeofArgs) goString(indent int, field string) string {
1932
1932
return fmt .Sprintf ("%*s%sSizeofArgs:\n %s" , indent , "" , field , args )
1933
1933
}
1934
1934
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
+
1935
2216
// Cast is a type cast.
1936
2217
type Cast struct {
1937
2218
To AST
@@ -2981,12 +3262,24 @@ func (da *DefaultArg) goString(indent int, field string) string {
2981
3262
2982
3263
// Closure is a closure, or lambda expression.
2983
3264
type Closure struct {
2984
- Types []AST
2985
- Num int
3265
+ TemplateArgs []AST
3266
+ Types []AST
3267
+ Num int
2986
3268
}
2987
3269
2988
3270
func (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 ("(" )
2990
3283
for i , t := range cl .Types {
2991
3284
if i > 0 {
2992
3285
ps .writeString (", " )
@@ -2998,6 +3291,9 @@ func (cl *Closure) print(ps *printState) {
2998
3291
2999
3292
func (cl * Closure ) Traverse (fn func (AST ) bool ) {
3000
3293
if fn (cl ) {
3294
+ for _ , a := range cl .TemplateArgs {
3295
+ a .Traverse (fn )
3296
+ }
3001
3297
for _ , t := range cl .Types {
3002
3298
t .Traverse (fn )
3003
3299
}
@@ -3008,8 +3304,20 @@ func (cl *Closure) Copy(fn func(AST) AST, skip func(AST) bool) AST {
3008
3304
if skip (cl ) {
3009
3305
return nil
3010
3306
}
3011
- types := make ([]AST , len (cl .Types ))
3012
3307
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 ))
3013
3321
for i , t := range cl .Types {
3014
3322
tc := t .Copy (fn , skip )
3015
3323
if tc == nil {
@@ -3019,10 +3327,11 @@ func (cl *Closure) Copy(fn func(AST) AST, skip func(AST) bool) AST {
3019
3327
changed = true
3020
3328
}
3021
3329
}
3330
+
3022
3331
if ! changed {
3023
3332
return fn (cl )
3024
3333
}
3025
- cl = & Closure {Types : types , Num : cl .Num }
3334
+ cl = & Closure {TemplateArgs : args , Types : types , Num : cl .Num }
3026
3335
if r := fn (cl ); r != nil {
3027
3336
return r
3028
3337
}
@@ -3034,6 +3343,16 @@ func (cl *Closure) GoString() string {
3034
3343
}
3035
3344
3036
3345
func (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
+ }
3037
3356
var types string
3038
3357
if len (cl .Types ) == 0 {
3039
3358
types = fmt .Sprintf ("%*sTypes: nil" , indent + 2 , "" )
@@ -3044,7 +3363,8 @@ func (cl *Closure) goString(indent int, field string) string {
3044
3363
types += t .goString (indent + 4 , fmt .Sprintf ("%d: " , i ))
3045
3364
}
3046
3365
}
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 )
3048
3368
}
3049
3369
3050
3370
// UnnamedType is an unnamed type, that just has an index.
0 commit comments