...

Source file src/cmd/vendor/github.com/ianlancetaylor/demangle/ast.go

Documentation: cmd/vendor/github.com/ianlancetaylor/demangle

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package demangle
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  )
    11  
    12  // AST is an abstract syntax tree representing a C++ declaration.
    13  // This is sufficient for the demangler but is by no means a general C++ AST.
    14  // This abstract syntax tree is only used for C++ symbols, not Rust symbols.
    15  type AST interface {
    16  	// Internal method to convert to demangled string.
    17  	print(*printState)
    18  
    19  	// Traverse each element of an AST.  If the function returns
    20  	// false, traversal of children of that element is skipped.
    21  	Traverse(func(AST) bool)
    22  
    23  	// Copy an AST with possible transformations.
    24  	// If the skip function returns true, no copy is required.
    25  	// If the copy function returns nil, no copy is required.
    26  	// The Copy method will do the right thing if copy returns nil
    27  	// for some components of an AST but not others, so a good
    28  	// copy function will only return non-nil for AST values that
    29  	// need to change.
    30  	// Copy itself returns either a copy or nil.
    31  	Copy(copy func(AST) AST, skip func(AST) bool) AST
    32  
    33  	// Implement the fmt.GoStringer interface.
    34  	GoString() string
    35  	goString(indent int, field string) string
    36  }
    37  
    38  // ASTToString returns the demangled name of the AST.
    39  func ASTToString(a AST, options ...Option) string {
    40  	tparams := true
    41  	enclosingParams := true
    42  	llvmStyle := false
    43  	max := 0
    44  	for _, o := range options {
    45  		switch {
    46  		case o == NoTemplateParams:
    47  			tparams = false
    48  		case o == NoEnclosingParams:
    49  			enclosingParams = false
    50  		case o == LLVMStyle:
    51  			llvmStyle = true
    52  		case isMaxLength(o):
    53  			max = maxLength(o)
    54  		}
    55  	}
    56  
    57  	ps := printState{
    58  		tparams:         tparams,
    59  		enclosingParams: enclosingParams,
    60  		llvmStyle:       llvmStyle,
    61  		max:             max,
    62  		scopes:          1,
    63  	}
    64  	a.print(&ps)
    65  	s := ps.buf.String()
    66  	if max > 0 && len(s) > max {
    67  		s = s[:max]
    68  	}
    69  	return s
    70  }
    71  
    72  // The printState type holds information needed to print an AST.
    73  type printState struct {
    74  	tparams         bool // whether to print template parameters
    75  	enclosingParams bool // whether to print enclosing parameters
    76  	llvmStyle       bool
    77  	max             int // maximum output length
    78  
    79  	// The scopes field is used to avoid unnecessary parentheses
    80  	// around expressions that use > (or >>). It is incremented if
    81  	// we output a parenthesis or something else that means that >
    82  	// or >> won't be treated as ending a template. It starts out
    83  	// as 1, and is set to 0 when we start writing template
    84  	// arguments. We add parentheses around expressions using > if
    85  	// scopes is 0. The effect is that an expression with > gets
    86  	// parentheses if used as a template argument that is not
    87  	// inside some other set of parentheses.
    88  	scopes int
    89  
    90  	buf  strings.Builder
    91  	last byte // Last byte written to buffer.
    92  
    93  	// The inner field is a list of items to print for a type
    94  	// name.  This is used by types to implement the inside-out
    95  	// C++ declaration syntax.
    96  	inner []AST
    97  
    98  	// The printing field is a list of items we are currently
    99  	// printing.  This avoids endless recursion if a substitution
   100  	// reference creates a cycle in the graph.
   101  	printing []AST
   102  }
   103  
   104  // writeByte adds a byte to the string being printed.
   105  func (ps *printState) writeByte(b byte) {
   106  	ps.last = b
   107  	ps.buf.WriteByte(b)
   108  }
   109  
   110  // writeString adds a string to the string being printed.
   111  func (ps *printState) writeString(s string) {
   112  	if len(s) > 0 {
   113  		ps.last = s[len(s)-1]
   114  	}
   115  	ps.buf.WriteString(s)
   116  }
   117  
   118  // Print an AST.
   119  func (ps *printState) print(a AST) {
   120  	if ps.max > 0 && ps.buf.Len() > ps.max {
   121  		return
   122  	}
   123  
   124  	c := 0
   125  	for _, v := range ps.printing {
   126  		if v == a {
   127  			// We permit the type to appear once, and
   128  			// return without printing anything if we see
   129  			// it twice.  This is for a case like
   130  			// _Z6outer2IsEPFilES1_, where the
   131  			// substitution is printed differently the
   132  			// second time because the set of inner types
   133  			// is different.
   134  			c++
   135  			if c > 1 {
   136  				return
   137  			}
   138  		}
   139  	}
   140  	ps.printing = append(ps.printing, a)
   141  
   142  	a.print(ps)
   143  
   144  	ps.printing = ps.printing[:len(ps.printing)-1]
   145  }
   146  
   147  // printList prints a list of AST values separated by commas,
   148  // optionally skipping some.
   149  func (ps *printState) printList(args []AST, skip func(AST) bool) {
   150  	first := true
   151  	for _, a := range args {
   152  		if skip != nil && skip(a) {
   153  			continue
   154  		}
   155  		if !first {
   156  			ps.writeString(", ")
   157  		}
   158  
   159  		needsParen := false
   160  		if ps.llvmStyle {
   161  			if p, ok := a.(hasPrec); ok {
   162  				if p.prec() >= precComma {
   163  					needsParen = true
   164  				}
   165  			}
   166  		}
   167  		if needsParen {
   168  			ps.startScope('(')
   169  		}
   170  
   171  		ps.print(a)
   172  
   173  		if needsParen {
   174  			ps.endScope(')')
   175  		}
   176  
   177  		first = false
   178  	}
   179  }
   180  
   181  // startScope starts a scope. This is used to decide whether we need
   182  // to parenthesize an expression using > or >>.
   183  func (ps *printState) startScope(b byte) {
   184  	ps.scopes++
   185  	ps.writeByte(b)
   186  }
   187  
   188  // endScope closes a scope.
   189  func (ps *printState) endScope(b byte) {
   190  	ps.scopes--
   191  	ps.writeByte(b)
   192  }
   193  
   194  // precedence is used for operator precedence. This is used to avoid
   195  // unnecessary parentheses when printing expressions in the LLVM style.
   196  type precedence int
   197  
   198  // The precedence values, in order from high to low.
   199  const (
   200  	precPrimary precedence = iota
   201  	precPostfix
   202  	precUnary
   203  	precCast
   204  	precPtrMem
   205  	precMul
   206  	precAdd
   207  	precShift
   208  	precSpaceship
   209  	precRel
   210  	precEqual
   211  	precAnd
   212  	precXor
   213  	precOr
   214  	precLogicalAnd
   215  	precLogicalOr
   216  	precCond
   217  	precAssign
   218  	precComma
   219  	precDefault
   220  )
   221  
   222  // hasPrec matches the AST nodes that have a prec method that returns
   223  // the node's precedence.
   224  type hasPrec interface {
   225  	prec() precedence
   226  }
   227  
   228  // Name is an unqualified name.
   229  type Name struct {
   230  	Name string
   231  }
   232  
   233  func (n *Name) print(ps *printState) {
   234  	ps.writeString(n.Name)
   235  }
   236  
   237  func (n *Name) Traverse(fn func(AST) bool) {
   238  	fn(n)
   239  }
   240  
   241  func (n *Name) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   242  	if skip(n) {
   243  		return nil
   244  	}
   245  	return fn(n)
   246  }
   247  
   248  func (n *Name) GoString() string {
   249  	return n.goString(0, "Name: ")
   250  }
   251  
   252  func (n *Name) goString(indent int, field string) string {
   253  	return fmt.Sprintf("%*s%s%s", indent, "", field, n.Name)
   254  }
   255  
   256  func (n *Name) prec() precedence {
   257  	return precPrimary
   258  }
   259  
   260  // Typed is a typed name.
   261  type Typed struct {
   262  	Name AST
   263  	Type AST
   264  }
   265  
   266  func (t *Typed) print(ps *printState) {
   267  	// We are printing a typed name, so ignore the current set of
   268  	// inner names to print.  Pass down our name as the one to use.
   269  	holdInner := ps.inner
   270  	defer func() { ps.inner = holdInner }()
   271  
   272  	ps.inner = []AST{t}
   273  	ps.print(t.Type)
   274  	if len(ps.inner) > 0 {
   275  		// The type did not print the name; print it now in
   276  		// the default location.
   277  		ps.writeByte(' ')
   278  		ps.print(t.Name)
   279  	}
   280  }
   281  
   282  func (t *Typed) printInner(ps *printState) {
   283  	ps.print(t.Name)
   284  }
   285  
   286  func (t *Typed) Traverse(fn func(AST) bool) {
   287  	if fn(t) {
   288  		t.Name.Traverse(fn)
   289  		t.Type.Traverse(fn)
   290  	}
   291  }
   292  
   293  func (t *Typed) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   294  	if skip(t) {
   295  		return nil
   296  	}
   297  	name := t.Name.Copy(fn, skip)
   298  	typ := t.Type.Copy(fn, skip)
   299  	if name == nil && typ == nil {
   300  		return fn(t)
   301  	}
   302  	if name == nil {
   303  		name = t.Name
   304  	}
   305  	if typ == nil {
   306  		typ = t.Type
   307  	}
   308  	t = &Typed{Name: name, Type: typ}
   309  	if r := fn(t); r != nil {
   310  		return r
   311  	}
   312  	return t
   313  }
   314  
   315  func (t *Typed) GoString() string {
   316  	return t.goString(0, "")
   317  }
   318  
   319  func (t *Typed) goString(indent int, field string) string {
   320  	return fmt.Sprintf("%*s%sTyped:\n%s\n%s", indent, "", field,
   321  		t.Name.goString(indent+2, "Name: "),
   322  		t.Type.goString(indent+2, "Type: "))
   323  }
   324  
   325  // Qualified is a name in a scope.
   326  type Qualified struct {
   327  	Scope AST
   328  	Name  AST
   329  
   330  	// The LocalName field is true if this is parsed as a
   331  	// <local-name>.  We shouldn't really need this, but in some
   332  	// cases (for the unary sizeof operator) the standard
   333  	// demangler prints a local name slightly differently.  We
   334  	// keep track of this for compatibility.
   335  	LocalName bool // A full local name encoding
   336  }
   337  
   338  func (q *Qualified) print(ps *printState) {
   339  	ps.print(q.Scope)
   340  	ps.writeString("::")
   341  	ps.print(q.Name)
   342  }
   343  
   344  func (q *Qualified) Traverse(fn func(AST) bool) {
   345  	if fn(q) {
   346  		q.Scope.Traverse(fn)
   347  		q.Name.Traverse(fn)
   348  	}
   349  }
   350  
   351  func (q *Qualified) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   352  	if skip(q) {
   353  		return nil
   354  	}
   355  	scope := q.Scope.Copy(fn, skip)
   356  	name := q.Name.Copy(fn, skip)
   357  	if scope == nil && name == nil {
   358  		return fn(q)
   359  	}
   360  	if scope == nil {
   361  		scope = q.Scope
   362  	}
   363  	if name == nil {
   364  		name = q.Name
   365  	}
   366  	q = &Qualified{Scope: scope, Name: name, LocalName: q.LocalName}
   367  	if r := fn(q); r != nil {
   368  		return r
   369  	}
   370  	return q
   371  }
   372  
   373  func (q *Qualified) GoString() string {
   374  	return q.goString(0, "")
   375  }
   376  
   377  func (q *Qualified) goString(indent int, field string) string {
   378  	s := ""
   379  	if q.LocalName {
   380  		s = " LocalName: true"
   381  	}
   382  	return fmt.Sprintf("%*s%sQualified:%s\n%s\n%s", indent, "", field,
   383  		s, q.Scope.goString(indent+2, "Scope: "),
   384  		q.Name.goString(indent+2, "Name: "))
   385  }
   386  
   387  func (q *Qualified) prec() precedence {
   388  	return precPrimary
   389  }
   390  
   391  // Template is a template with arguments.
   392  type Template struct {
   393  	Name AST
   394  	Args []AST
   395  }
   396  
   397  func (t *Template) print(ps *printState) {
   398  	// Inner types apply to the template as a whole, they don't
   399  	// cross over into the template.
   400  	holdInner := ps.inner
   401  	defer func() { ps.inner = holdInner }()
   402  
   403  	ps.inner = nil
   404  	ps.print(t.Name)
   405  
   406  	if !ps.tparams {
   407  		// Do not print template parameters.
   408  		return
   409  	}
   410  	// We need an extra space after operator<.
   411  	if ps.last == '<' {
   412  		ps.writeByte(' ')
   413  	}
   414  
   415  	scopes := ps.scopes
   416  	ps.scopes = 0
   417  
   418  	ps.writeByte('<')
   419  	ps.printList(t.Args, ps.isEmpty)
   420  	if ps.last == '>' && !ps.llvmStyle {
   421  		// Avoid syntactic ambiguity in old versions of C++.
   422  		ps.writeByte(' ')
   423  	}
   424  	ps.writeByte('>')
   425  
   426  	ps.scopes = scopes
   427  }
   428  
   429  func (t *Template) Traverse(fn func(AST) bool) {
   430  	if fn(t) {
   431  		t.Name.Traverse(fn)
   432  		for _, a := range t.Args {
   433  			a.Traverse(fn)
   434  		}
   435  	}
   436  }
   437  
   438  func (t *Template) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   439  	if skip(t) {
   440  		return nil
   441  	}
   442  	name := t.Name.Copy(fn, skip)
   443  	changed := name != nil
   444  	args := make([]AST, len(t.Args))
   445  	for i, a := range t.Args {
   446  		ac := a.Copy(fn, skip)
   447  		if ac == nil {
   448  			args[i] = a
   449  		} else {
   450  			args[i] = ac
   451  			changed = true
   452  		}
   453  	}
   454  	if !changed {
   455  		return fn(t)
   456  	}
   457  	if name == nil {
   458  		name = t.Name
   459  	}
   460  	t = &Template{Name: name, Args: args}
   461  	if r := fn(t); r != nil {
   462  		return r
   463  	}
   464  	return t
   465  }
   466  
   467  func (t *Template) GoString() string {
   468  	return t.goString(0, "")
   469  }
   470  
   471  func (t *Template) goString(indent int, field string) string {
   472  	var args string
   473  	if len(t.Args) == 0 {
   474  		args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
   475  	} else {
   476  		args = fmt.Sprintf("%*sArgs:", indent+2, "")
   477  		for i, a := range t.Args {
   478  			args += "\n"
   479  			args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
   480  		}
   481  	}
   482  	return fmt.Sprintf("%*s%sTemplate (%p):\n%s\n%s", indent, "", field, t,
   483  		t.Name.goString(indent+2, "Name: "), args)
   484  }
   485  
   486  // TemplateParam is a template parameter.  The Template field is
   487  // filled in while parsing the demangled string.  We don't normally
   488  // see these while printing--they are replaced by the simplify
   489  // function.
   490  type TemplateParam struct {
   491  	Index    int
   492  	Template *Template
   493  }
   494  
   495  func (tp *TemplateParam) print(ps *printState) {
   496  	if tp.Template == nil {
   497  		panic("TemplateParam Template field is nil")
   498  	}
   499  	if tp.Index >= len(tp.Template.Args) {
   500  		panic("TemplateParam Index out of bounds")
   501  	}
   502  	ps.print(tp.Template.Args[tp.Index])
   503  }
   504  
   505  func (tp *TemplateParam) Traverse(fn func(AST) bool) {
   506  	fn(tp)
   507  	// Don't traverse Template--it points elsewhere in the AST.
   508  }
   509  
   510  func (tp *TemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   511  	if skip(tp) {
   512  		return nil
   513  	}
   514  	return fn(tp)
   515  }
   516  
   517  func (tp *TemplateParam) GoString() string {
   518  	return tp.goString(0, "")
   519  }
   520  
   521  func (tp *TemplateParam) goString(indent int, field string) string {
   522  	return fmt.Sprintf("%*s%sTemplateParam: Template: %p; Index %d", indent, "", field, tp.Template, tp.Index)
   523  }
   524  
   525  // LambdaAuto is a lambda auto parameter.
   526  type LambdaAuto struct {
   527  	Index int
   528  }
   529  
   530  func (la *LambdaAuto) print(ps *printState) {
   531  	// We print the index plus 1 because that is what the standard
   532  	// demangler does.
   533  	if ps.llvmStyle {
   534  		ps.writeString("auto")
   535  	} else {
   536  		fmt.Fprintf(&ps.buf, "auto:%d", la.Index+1)
   537  	}
   538  }
   539  
   540  func (la *LambdaAuto) Traverse(fn func(AST) bool) {
   541  	fn(la)
   542  }
   543  
   544  func (la *LambdaAuto) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   545  	if skip(la) {
   546  		return nil
   547  	}
   548  	return fn(la)
   549  }
   550  
   551  func (la *LambdaAuto) GoString() string {
   552  	return la.goString(0, "")
   553  }
   554  
   555  func (la *LambdaAuto) goString(indent int, field string) string {
   556  	return fmt.Sprintf("%*s%sLambdaAuto: Index %d", indent, "", field, la.Index)
   557  }
   558  
   559  // TemplateParamQualifiedArg is used when the mangled name includes
   560  // both the template parameter declaration and the template argument.
   561  // See https://github.com/itanium-cxx-abi/cxx-abi/issues/47.
   562  type TemplateParamQualifiedArg struct {
   563  	Param AST
   564  	Arg   AST
   565  }
   566  
   567  func (tpqa *TemplateParamQualifiedArg) print(ps *printState) {
   568  	// We only demangle the actual template argument.
   569  	// That is what the LLVM demangler does.
   570  	// The parameter disambiguates the argument,
   571  	// but is hopefully not required by a human reader.
   572  	ps.print(tpqa.Arg)
   573  }
   574  
   575  func (tpqa *TemplateParamQualifiedArg) Traverse(fn func(AST) bool) {
   576  	if fn(tpqa) {
   577  		tpqa.Param.Traverse(fn)
   578  		tpqa.Arg.Traverse(fn)
   579  	}
   580  }
   581  
   582  func (tpqa *TemplateParamQualifiedArg) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   583  	if skip(tpqa) {
   584  		return nil
   585  	}
   586  	param := tpqa.Param.Copy(fn, skip)
   587  	arg := tpqa.Arg.Copy(fn, skip)
   588  	if param == nil && arg == nil {
   589  		return fn(tpqa)
   590  	}
   591  	if param == nil {
   592  		param = tpqa.Param
   593  	}
   594  	if arg == nil {
   595  		arg = tpqa.Arg
   596  	}
   597  	tpqa = &TemplateParamQualifiedArg{Param: param, Arg: arg}
   598  	if r := fn(tpqa); r != nil {
   599  		return r
   600  	}
   601  	return tpqa
   602  }
   603  
   604  func (tpqa *TemplateParamQualifiedArg) GoString() string {
   605  	return tpqa.goString(0, "")
   606  }
   607  
   608  func (tpqa *TemplateParamQualifiedArg) goString(indent int, field string) string {
   609  	return fmt.Sprintf("%*s%sTemplateParamQualifiedArg:\n%s\n%s", indent, "", field,
   610  		tpqa.Param.goString(indent+2, "Param: "),
   611  		tpqa.Arg.goString(indent+2, "Arg: "))
   612  }
   613  
   614  // Qualifiers is an ordered list of type qualifiers.
   615  type Qualifiers struct {
   616  	Qualifiers []AST
   617  }
   618  
   619  func (qs *Qualifiers) print(ps *printState) {
   620  	first := true
   621  	for _, q := range qs.Qualifiers {
   622  		if !first {
   623  			ps.writeByte(' ')
   624  		}
   625  		q.print(ps)
   626  		first = false
   627  	}
   628  }
   629  
   630  func (qs *Qualifiers) Traverse(fn func(AST) bool) {
   631  	if fn(qs) {
   632  		for _, q := range qs.Qualifiers {
   633  			q.Traverse(fn)
   634  		}
   635  	}
   636  }
   637  
   638  func (qs *Qualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   639  	if skip(qs) {
   640  		return nil
   641  	}
   642  	changed := false
   643  	qualifiers := make([]AST, len(qs.Qualifiers))
   644  	for i, q := range qs.Qualifiers {
   645  		qc := q.Copy(fn, skip)
   646  		if qc == nil {
   647  			qualifiers[i] = q
   648  		} else {
   649  			qualifiers[i] = qc
   650  			changed = true
   651  		}
   652  	}
   653  	if !changed {
   654  		return fn(qs)
   655  	}
   656  	qs = &Qualifiers{Qualifiers: qualifiers}
   657  	if r := fn(qs); r != nil {
   658  		return r
   659  	}
   660  	return qs
   661  }
   662  
   663  func (qs *Qualifiers) GoString() string {
   664  	return qs.goString(0, "")
   665  }
   666  
   667  func (qs *Qualifiers) goString(indent int, field string) string {
   668  	quals := fmt.Sprintf("%*s%s", indent, "", field)
   669  	for _, q := range qs.Qualifiers {
   670  		quals += "\n"
   671  		quals += q.goString(indent+2, "")
   672  	}
   673  	return quals
   674  }
   675  
   676  // Qualifier is a single type qualifier.
   677  type Qualifier struct {
   678  	Name  string // qualifier name: const, volatile, etc.
   679  	Exprs []AST  // can be non-nil for noexcept and throw
   680  }
   681  
   682  func (q *Qualifier) print(ps *printState) {
   683  	ps.writeString(q.Name)
   684  	if len(q.Exprs) > 0 {
   685  		ps.startScope('(')
   686  		first := true
   687  		for _, e := range q.Exprs {
   688  			if el, ok := e.(*ExprList); ok && len(el.Exprs) == 0 {
   689  				continue
   690  			}
   691  			if !first {
   692  				ps.writeString(", ")
   693  			}
   694  			ps.print(e)
   695  			first = false
   696  		}
   697  		ps.endScope(')')
   698  	}
   699  }
   700  
   701  func (q *Qualifier) Traverse(fn func(AST) bool) {
   702  	if fn(q) {
   703  		for _, e := range q.Exprs {
   704  			e.Traverse(fn)
   705  		}
   706  	}
   707  }
   708  
   709  func (q *Qualifier) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   710  	if skip(q) {
   711  		return nil
   712  	}
   713  	exprs := make([]AST, len(q.Exprs))
   714  	changed := false
   715  	for i, e := range q.Exprs {
   716  		ec := e.Copy(fn, skip)
   717  		if ec == nil {
   718  			exprs[i] = e
   719  		} else {
   720  			exprs[i] = ec
   721  			changed = true
   722  		}
   723  	}
   724  	if !changed {
   725  		return fn(q)
   726  	}
   727  	q = &Qualifier{Name: q.Name, Exprs: exprs}
   728  	if r := fn(q); r != nil {
   729  		return r
   730  	}
   731  	return q
   732  }
   733  
   734  func (q *Qualifier) GoString() string {
   735  	return q.goString(0, "Qualifier: ")
   736  }
   737  
   738  func (q *Qualifier) goString(indent int, field string) string {
   739  	qs := fmt.Sprintf("%*s%s%s", indent, "", field, q.Name)
   740  	if len(q.Exprs) > 0 {
   741  		for i, e := range q.Exprs {
   742  			qs += "\n"
   743  			qs += e.goString(indent+2, fmt.Sprintf("%d: ", i))
   744  		}
   745  	}
   746  	return qs
   747  }
   748  
   749  // TypeWithQualifiers is a type with standard qualifiers.
   750  type TypeWithQualifiers struct {
   751  	Base       AST
   752  	Qualifiers AST
   753  }
   754  
   755  func (twq *TypeWithQualifiers) print(ps *printState) {
   756  	// Give the base type a chance to print the inner types.
   757  	ps.inner = append(ps.inner, twq)
   758  	ps.print(twq.Base)
   759  	if len(ps.inner) > 0 {
   760  		// The qualifier wasn't printed by Base.
   761  		ps.writeByte(' ')
   762  		ps.print(twq.Qualifiers)
   763  		ps.inner = ps.inner[:len(ps.inner)-1]
   764  	}
   765  }
   766  
   767  // Print qualifiers as an inner type by just printing the qualifiers.
   768  func (twq *TypeWithQualifiers) printInner(ps *printState) {
   769  	ps.writeByte(' ')
   770  	ps.print(twq.Qualifiers)
   771  }
   772  
   773  func (twq *TypeWithQualifiers) Traverse(fn func(AST) bool) {
   774  	if fn(twq) {
   775  		twq.Base.Traverse(fn)
   776  	}
   777  }
   778  
   779  func (twq *TypeWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   780  	if skip(twq) {
   781  		return nil
   782  	}
   783  	base := twq.Base.Copy(fn, skip)
   784  	quals := twq.Qualifiers.Copy(fn, skip)
   785  	if base == nil && quals == nil {
   786  		return fn(twq)
   787  	}
   788  	if base == nil {
   789  		base = twq.Base
   790  	}
   791  	if quals == nil {
   792  		quals = twq.Qualifiers
   793  	}
   794  	twq = &TypeWithQualifiers{Base: base, Qualifiers: quals}
   795  	if r := fn(twq); r != nil {
   796  		return r
   797  	}
   798  	return twq
   799  }
   800  
   801  func (twq *TypeWithQualifiers) GoString() string {
   802  	return twq.goString(0, "")
   803  }
   804  
   805  func (twq *TypeWithQualifiers) goString(indent int, field string) string {
   806  	return fmt.Sprintf("%*s%sTypeWithQualifiers:\n%s\n%s", indent, "", field,
   807  		twq.Qualifiers.goString(indent+2, "Qualifiers: "),
   808  		twq.Base.goString(indent+2, "Base: "))
   809  }
   810  
   811  // MethodWithQualifiers is a method with qualifiers.
   812  type MethodWithQualifiers struct {
   813  	Method       AST
   814  	Qualifiers   AST
   815  	RefQualifier string // "" or "&" or "&&"
   816  }
   817  
   818  func (mwq *MethodWithQualifiers) print(ps *printState) {
   819  	// Give the base type a chance to print the inner types.
   820  	ps.inner = append(ps.inner, mwq)
   821  	ps.print(mwq.Method)
   822  	if len(ps.inner) > 0 {
   823  		if mwq.Qualifiers != nil {
   824  			ps.writeByte(' ')
   825  			ps.print(mwq.Qualifiers)
   826  		}
   827  		if mwq.RefQualifier != "" {
   828  			ps.writeByte(' ')
   829  			ps.writeString(mwq.RefQualifier)
   830  		}
   831  		ps.inner = ps.inner[:len(ps.inner)-1]
   832  	}
   833  }
   834  
   835  func (mwq *MethodWithQualifiers) printInner(ps *printState) {
   836  	if mwq.Qualifiers != nil {
   837  		ps.writeByte(' ')
   838  		ps.print(mwq.Qualifiers)
   839  	}
   840  	if mwq.RefQualifier != "" {
   841  		ps.writeByte(' ')
   842  		ps.writeString(mwq.RefQualifier)
   843  	}
   844  }
   845  
   846  func (mwq *MethodWithQualifiers) Traverse(fn func(AST) bool) {
   847  	if fn(mwq) {
   848  		mwq.Method.Traverse(fn)
   849  	}
   850  }
   851  
   852  func (mwq *MethodWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   853  	if skip(mwq) {
   854  		return nil
   855  	}
   856  	method := mwq.Method.Copy(fn, skip)
   857  	var quals AST
   858  	if mwq.Qualifiers != nil {
   859  		quals = mwq.Qualifiers.Copy(fn, skip)
   860  	}
   861  	if method == nil && quals == nil {
   862  		return fn(mwq)
   863  	}
   864  	if method == nil {
   865  		method = mwq.Method
   866  	}
   867  	if quals == nil {
   868  		quals = mwq.Qualifiers
   869  	}
   870  	mwq = &MethodWithQualifiers{Method: method, Qualifiers: quals, RefQualifier: mwq.RefQualifier}
   871  	if r := fn(mwq); r != nil {
   872  		return r
   873  	}
   874  	return mwq
   875  }
   876  
   877  func (mwq *MethodWithQualifiers) GoString() string {
   878  	return mwq.goString(0, "")
   879  }
   880  
   881  func (mwq *MethodWithQualifiers) goString(indent int, field string) string {
   882  	var q string
   883  	if mwq.Qualifiers != nil {
   884  		q += "\n" + mwq.Qualifiers.goString(indent+2, "Qualifiers: ")
   885  	}
   886  	if mwq.RefQualifier != "" {
   887  		if q != "" {
   888  			q += "\n"
   889  		}
   890  		q += fmt.Sprintf("%*s%s%s", indent+2, "", "RefQualifier: ", mwq.RefQualifier)
   891  	}
   892  	return fmt.Sprintf("%*s%sMethodWithQualifiers:%s\n%s", indent, "", field,
   893  		q, mwq.Method.goString(indent+2, "Method: "))
   894  }
   895  
   896  // BuiltinType is a builtin type, like "int".
   897  type BuiltinType struct {
   898  	Name string
   899  }
   900  
   901  func (bt *BuiltinType) print(ps *printState) {
   902  	name := bt.Name
   903  	if ps.llvmStyle && name == "decltype(nullptr)" {
   904  		name = "std::nullptr_t"
   905  	}
   906  	ps.writeString(name)
   907  }
   908  
   909  func (bt *BuiltinType) Traverse(fn func(AST) bool) {
   910  	fn(bt)
   911  }
   912  
   913  func (bt *BuiltinType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   914  	if skip(bt) {
   915  		return nil
   916  	}
   917  	return fn(bt)
   918  }
   919  
   920  func (bt *BuiltinType) GoString() string {
   921  	return bt.goString(0, "")
   922  }
   923  
   924  func (bt *BuiltinType) goString(indent int, field string) string {
   925  	return fmt.Sprintf("%*s%sBuiltinType: %s", indent, "", field, bt.Name)
   926  }
   927  
   928  func (bt *BuiltinType) prec() precedence {
   929  	return precPrimary
   930  }
   931  
   932  // printBase is common print code for types that are printed with a
   933  // simple suffix.
   934  func printBase(ps *printState, qual, base AST) {
   935  	ps.inner = append(ps.inner, qual)
   936  	ps.print(base)
   937  	if len(ps.inner) > 0 {
   938  		qual.(innerPrinter).printInner(ps)
   939  		ps.inner = ps.inner[:len(ps.inner)-1]
   940  	}
   941  }
   942  
   943  // PointerType is a pointer type.
   944  type PointerType struct {
   945  	Base AST
   946  }
   947  
   948  func (pt *PointerType) print(ps *printState) {
   949  	printBase(ps, pt, pt.Base)
   950  }
   951  
   952  func (pt *PointerType) printInner(ps *printState) {
   953  	ps.writeString("*")
   954  }
   955  
   956  func (pt *PointerType) Traverse(fn func(AST) bool) {
   957  	if fn(pt) {
   958  		pt.Base.Traverse(fn)
   959  	}
   960  }
   961  
   962  func (pt *PointerType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   963  	if skip(pt) {
   964  		return nil
   965  	}
   966  	base := pt.Base.Copy(fn, skip)
   967  	if base == nil {
   968  		return fn(pt)
   969  	}
   970  	pt = &PointerType{Base: base}
   971  	if r := fn(pt); r != nil {
   972  		return r
   973  	}
   974  	return pt
   975  }
   976  
   977  func (pt *PointerType) GoString() string {
   978  	return pt.goString(0, "")
   979  }
   980  
   981  func (pt *PointerType) goString(indent int, field string) string {
   982  	return fmt.Sprintf("%*s%sPointerType:\n%s", indent, "", field,
   983  		pt.Base.goString(indent+2, ""))
   984  }
   985  
   986  // ReferenceType is a reference type.
   987  type ReferenceType struct {
   988  	Base AST
   989  }
   990  
   991  func (rt *ReferenceType) print(ps *printState) {
   992  	printBase(ps, rt, rt.Base)
   993  }
   994  
   995  func (rt *ReferenceType) printInner(ps *printState) {
   996  	ps.writeString("&")
   997  }
   998  
   999  func (rt *ReferenceType) Traverse(fn func(AST) bool) {
  1000  	if fn(rt) {
  1001  		rt.Base.Traverse(fn)
  1002  	}
  1003  }
  1004  
  1005  func (rt *ReferenceType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1006  	if skip(rt) {
  1007  		return nil
  1008  	}
  1009  	base := rt.Base.Copy(fn, skip)
  1010  	if base == nil {
  1011  		return fn(rt)
  1012  	}
  1013  	rt = &ReferenceType{Base: base}
  1014  	if r := fn(rt); r != nil {
  1015  		return r
  1016  	}
  1017  	return rt
  1018  }
  1019  
  1020  func (rt *ReferenceType) GoString() string {
  1021  	return rt.goString(0, "")
  1022  }
  1023  
  1024  func (rt *ReferenceType) goString(indent int, field string) string {
  1025  	return fmt.Sprintf("%*s%sReferenceType:\n%s", indent, "", field,
  1026  		rt.Base.goString(indent+2, ""))
  1027  }
  1028  
  1029  // RvalueReferenceType is an rvalue reference type.
  1030  type RvalueReferenceType struct {
  1031  	Base AST
  1032  }
  1033  
  1034  func (rt *RvalueReferenceType) print(ps *printState) {
  1035  	printBase(ps, rt, rt.Base)
  1036  }
  1037  
  1038  func (rt *RvalueReferenceType) printInner(ps *printState) {
  1039  	ps.writeString("&&")
  1040  }
  1041  
  1042  func (rt *RvalueReferenceType) Traverse(fn func(AST) bool) {
  1043  	if fn(rt) {
  1044  		rt.Base.Traverse(fn)
  1045  	}
  1046  }
  1047  
  1048  func (rt *RvalueReferenceType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1049  	if skip(rt) {
  1050  		return nil
  1051  	}
  1052  	base := rt.Base.Copy(fn, skip)
  1053  	if base == nil {
  1054  		return fn(rt)
  1055  	}
  1056  	rt = &RvalueReferenceType{Base: base}
  1057  	if r := fn(rt); r != nil {
  1058  		return r
  1059  	}
  1060  	return rt
  1061  }
  1062  
  1063  func (rt *RvalueReferenceType) GoString() string {
  1064  	return rt.goString(0, "")
  1065  }
  1066  
  1067  func (rt *RvalueReferenceType) goString(indent int, field string) string {
  1068  	return fmt.Sprintf("%*s%sRvalueReferenceType:\n%s", indent, "", field,
  1069  		rt.Base.goString(indent+2, ""))
  1070  }
  1071  
  1072  // ComplexType is a complex type.
  1073  type ComplexType struct {
  1074  	Base AST
  1075  }
  1076  
  1077  func (ct *ComplexType) print(ps *printState) {
  1078  	printBase(ps, ct, ct.Base)
  1079  }
  1080  
  1081  func (ct *ComplexType) printInner(ps *printState) {
  1082  	ps.writeString(" _Complex")
  1083  }
  1084  
  1085  func (ct *ComplexType) Traverse(fn func(AST) bool) {
  1086  	if fn(ct) {
  1087  		ct.Base.Traverse(fn)
  1088  	}
  1089  }
  1090  
  1091  func (ct *ComplexType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1092  	if skip(ct) {
  1093  		return nil
  1094  	}
  1095  	base := ct.Base.Copy(fn, skip)
  1096  	if base == nil {
  1097  		return fn(ct)
  1098  	}
  1099  	ct = &ComplexType{Base: base}
  1100  	if r := fn(ct); r != nil {
  1101  		return r
  1102  	}
  1103  	return ct
  1104  }
  1105  
  1106  func (ct *ComplexType) GoString() string {
  1107  	return ct.goString(0, "")
  1108  }
  1109  
  1110  func (ct *ComplexType) goString(indent int, field string) string {
  1111  	return fmt.Sprintf("%*s%sComplexType:\n%s", indent, "", field,
  1112  		ct.Base.goString(indent+2, ""))
  1113  }
  1114  
  1115  // ImaginaryType is an imaginary type.
  1116  type ImaginaryType struct {
  1117  	Base AST
  1118  }
  1119  
  1120  func (it *ImaginaryType) print(ps *printState) {
  1121  	printBase(ps, it, it.Base)
  1122  }
  1123  
  1124  func (it *ImaginaryType) printInner(ps *printState) {
  1125  	ps.writeString(" _Imaginary")
  1126  }
  1127  
  1128  func (it *ImaginaryType) Traverse(fn func(AST) bool) {
  1129  	if fn(it) {
  1130  		it.Base.Traverse(fn)
  1131  	}
  1132  }
  1133  
  1134  func (it *ImaginaryType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1135  	if skip(it) {
  1136  		return nil
  1137  	}
  1138  	base := it.Base.Copy(fn, skip)
  1139  	if base == nil {
  1140  		return fn(it)
  1141  	}
  1142  	it = &ImaginaryType{Base: base}
  1143  	if r := fn(it); r != nil {
  1144  		return r
  1145  	}
  1146  	return it
  1147  }
  1148  
  1149  func (it *ImaginaryType) GoString() string {
  1150  	return it.goString(0, "")
  1151  }
  1152  
  1153  func (it *ImaginaryType) goString(indent int, field string) string {
  1154  	return fmt.Sprintf("%*s%sImaginaryType:\n%s", indent, "", field,
  1155  		it.Base.goString(indent+2, ""))
  1156  }
  1157  
  1158  // SuffixType is an type with an arbitrary suffix.
  1159  type SuffixType struct {
  1160  	Base   AST
  1161  	Suffix string
  1162  }
  1163  
  1164  func (st *SuffixType) print(ps *printState) {
  1165  	printBase(ps, st, st.Base)
  1166  }
  1167  
  1168  func (st *SuffixType) printInner(ps *printState) {
  1169  	ps.writeByte(' ')
  1170  	ps.writeString(st.Suffix)
  1171  }
  1172  
  1173  func (st *SuffixType) Traverse(fn func(AST) bool) {
  1174  	if fn(st) {
  1175  		st.Base.Traverse(fn)
  1176  	}
  1177  }
  1178  
  1179  func (st *SuffixType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1180  	if skip(st) {
  1181  		return nil
  1182  	}
  1183  	base := st.Base.Copy(fn, skip)
  1184  	if base == nil {
  1185  		return fn(st)
  1186  	}
  1187  	st = &SuffixType{Base: base, Suffix: st.Suffix}
  1188  	if r := fn(st); r != nil {
  1189  		return r
  1190  	}
  1191  	return st
  1192  }
  1193  
  1194  func (st *SuffixType) GoString() string {
  1195  	return st.goString(0, "")
  1196  }
  1197  
  1198  func (st *SuffixType) goString(indent int, field string) string {
  1199  	return fmt.Sprintf("%*s%sSuffixType: %s\n%s", indent, "", field,
  1200  		st.Suffix, st.Base.goString(indent+2, "Base: "))
  1201  }
  1202  
  1203  // TransformedType is a builtin type with a template argument.
  1204  type TransformedType struct {
  1205  	Name string
  1206  	Base AST
  1207  }
  1208  
  1209  func (tt *TransformedType) print(ps *printState) {
  1210  	ps.writeString(tt.Name)
  1211  	ps.startScope('(')
  1212  	ps.print(tt.Base)
  1213  	ps.endScope(')')
  1214  }
  1215  
  1216  func (tt *TransformedType) Traverse(fn func(AST) bool) {
  1217  	if fn(tt) {
  1218  		tt.Base.Traverse(fn)
  1219  	}
  1220  }
  1221  
  1222  func (tt *TransformedType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1223  	if skip(tt) {
  1224  		return nil
  1225  	}
  1226  	base := tt.Base.Copy(fn, skip)
  1227  	if base == nil {
  1228  		return fn(tt)
  1229  	}
  1230  	tt = &TransformedType{Name: tt.Name, Base: base}
  1231  	if r := fn(tt); r != nil {
  1232  		return r
  1233  	}
  1234  	return tt
  1235  }
  1236  
  1237  func (tt *TransformedType) GoString() string {
  1238  	return tt.goString(0, "")
  1239  }
  1240  
  1241  func (tt *TransformedType) goString(indent int, field string) string {
  1242  	return fmt.Sprintf("%*s%sTransformedType: %s\n%s", indent, "", field,
  1243  		tt.Name, tt.Base.goString(indent+2, "Base: "))
  1244  }
  1245  
  1246  // VendorQualifier is a type qualified by a vendor-specific qualifier.
  1247  type VendorQualifier struct {
  1248  	Qualifier AST
  1249  	Type      AST
  1250  }
  1251  
  1252  func (vq *VendorQualifier) print(ps *printState) {
  1253  	if ps.llvmStyle {
  1254  		ps.print(vq.Type)
  1255  		vq.printInner(ps)
  1256  	} else {
  1257  		ps.inner = append(ps.inner, vq)
  1258  		ps.print(vq.Type)
  1259  		if len(ps.inner) > 0 {
  1260  			ps.printOneInner(nil)
  1261  		}
  1262  	}
  1263  }
  1264  
  1265  func (vq *VendorQualifier) printInner(ps *printState) {
  1266  	ps.writeByte(' ')
  1267  	ps.print(vq.Qualifier)
  1268  }
  1269  
  1270  func (vq *VendorQualifier) Traverse(fn func(AST) bool) {
  1271  	if fn(vq) {
  1272  		vq.Qualifier.Traverse(fn)
  1273  		vq.Type.Traverse(fn)
  1274  	}
  1275  }
  1276  
  1277  func (vq *VendorQualifier) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1278  	if skip(vq) {
  1279  		return nil
  1280  	}
  1281  	qualifier := vq.Qualifier.Copy(fn, skip)
  1282  	typ := vq.Type.Copy(fn, skip)
  1283  	if qualifier == nil && typ == nil {
  1284  		return fn(vq)
  1285  	}
  1286  	if qualifier == nil {
  1287  		qualifier = vq.Qualifier
  1288  	}
  1289  	if typ == nil {
  1290  		typ = vq.Type
  1291  	}
  1292  	vq = &VendorQualifier{Qualifier: qualifier, Type: vq.Type}
  1293  	if r := fn(vq); r != nil {
  1294  		return r
  1295  	}
  1296  	return vq
  1297  }
  1298  
  1299  func (vq *VendorQualifier) GoString() string {
  1300  	return vq.goString(0, "")
  1301  }
  1302  
  1303  func (vq *VendorQualifier) goString(indent int, field string) string {
  1304  	return fmt.Sprintf("%*s%sVendorQualifier:\n%s\n%s", indent, "", field,
  1305  		vq.Qualifier.goString(indent+2, "Qualifier: "),
  1306  		vq.Type.goString(indent+2, "Type: "))
  1307  }
  1308  
  1309  // ArrayType is an array type.
  1310  type ArrayType struct {
  1311  	Dimension AST
  1312  	Element   AST
  1313  }
  1314  
  1315  func (at *ArrayType) print(ps *printState) {
  1316  	// Pass the array type down as an inner type so that we print
  1317  	// multi-dimensional arrays correctly.
  1318  	ps.inner = append(ps.inner, at)
  1319  	ps.print(at.Element)
  1320  	if ln := len(ps.inner); ln > 0 {
  1321  		ps.inner = ps.inner[:ln-1]
  1322  		at.printDimension(ps)
  1323  	}
  1324  }
  1325  
  1326  func (at *ArrayType) printInner(ps *printState) {
  1327  	at.printDimension(ps)
  1328  }
  1329  
  1330  // Print the array dimension.
  1331  func (at *ArrayType) printDimension(ps *printState) {
  1332  	space := " "
  1333  	for len(ps.inner) > 0 {
  1334  		// We haven't gotten to the real type yet.  Use
  1335  		// parentheses around that type, except that if it is
  1336  		// an array type we print it as a multi-dimensional
  1337  		// array
  1338  		in := ps.inner[len(ps.inner)-1]
  1339  		if twq, ok := in.(*TypeWithQualifiers); ok {
  1340  			in = twq.Base
  1341  		}
  1342  		if _, ok := in.(*ArrayType); ok {
  1343  			if in == ps.inner[len(ps.inner)-1] {
  1344  				space = ""
  1345  			}
  1346  			ps.printOneInner(nil)
  1347  		} else {
  1348  			ps.writeByte(' ')
  1349  			ps.startScope('(')
  1350  			ps.printInner(false)
  1351  			ps.endScope(')')
  1352  		}
  1353  	}
  1354  	ps.writeString(space)
  1355  	ps.writeByte('[')
  1356  	ps.print(at.Dimension)
  1357  	ps.writeByte(']')
  1358  }
  1359  
  1360  func (at *ArrayType) Traverse(fn func(AST) bool) {
  1361  	if fn(at) {
  1362  		at.Dimension.Traverse(fn)
  1363  		at.Element.Traverse(fn)
  1364  	}
  1365  }
  1366  
  1367  func (at *ArrayType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1368  	if skip(at) {
  1369  		return nil
  1370  	}
  1371  	dimension := at.Dimension.Copy(fn, skip)
  1372  	element := at.Element.Copy(fn, skip)
  1373  	if dimension == nil && element == nil {
  1374  		return fn(at)
  1375  	}
  1376  	if dimension == nil {
  1377  		dimension = at.Dimension
  1378  	}
  1379  	if element == nil {
  1380  		element = at.Element
  1381  	}
  1382  	at = &ArrayType{Dimension: dimension, Element: element}
  1383  	if r := fn(at); r != nil {
  1384  		return r
  1385  	}
  1386  	return at
  1387  }
  1388  
  1389  func (at *ArrayType) GoString() string {
  1390  	return at.goString(0, "")
  1391  }
  1392  
  1393  func (at *ArrayType) goString(indent int, field string) string {
  1394  	return fmt.Sprintf("%*s%sArrayType:\n%s\n%s", indent, "", field,
  1395  		at.Dimension.goString(indent+2, "Dimension: "),
  1396  		at.Element.goString(indent+2, "Element: "))
  1397  }
  1398  
  1399  // FunctionType is a function type.
  1400  type FunctionType struct {
  1401  	Return AST
  1402  	Args   []AST
  1403  
  1404  	// The forLocalName field reports whether this FunctionType
  1405  	// was created for a local name. With the default GNU demangling
  1406  	// output we don't print the return type in that case.
  1407  	ForLocalName bool
  1408  }
  1409  
  1410  func (ft *FunctionType) print(ps *printState) {
  1411  	retType := ft.Return
  1412  	if ft.ForLocalName && (!ps.enclosingParams || !ps.llvmStyle) {
  1413  		retType = nil
  1414  	}
  1415  	if retType != nil {
  1416  		// Pass the return type as an inner type in order to
  1417  		// print the arguments in the right location.
  1418  		ps.inner = append(ps.inner, ft)
  1419  		ps.print(retType)
  1420  		if len(ps.inner) == 0 {
  1421  			// Everything was printed.
  1422  			return
  1423  		}
  1424  		ps.inner = ps.inner[:len(ps.inner)-1]
  1425  		ps.writeByte(' ')
  1426  	}
  1427  	ft.printArgs(ps)
  1428  }
  1429  
  1430  func (ft *FunctionType) printInner(ps *printState) {
  1431  	ft.printArgs(ps)
  1432  }
  1433  
  1434  // printArgs prints the arguments of a function type.  It looks at the
  1435  // inner types for spacing.
  1436  func (ft *FunctionType) printArgs(ps *printState) {
  1437  	paren := false
  1438  	space := false
  1439  	for i := len(ps.inner) - 1; i >= 0; i-- {
  1440  		switch ps.inner[i].(type) {
  1441  		case *PointerType, *ReferenceType, *RvalueReferenceType:
  1442  			paren = true
  1443  		case *TypeWithQualifiers, *ComplexType, *ImaginaryType, *PtrMem:
  1444  			space = true
  1445  			paren = true
  1446  		}
  1447  		if paren {
  1448  			break
  1449  		}
  1450  	}
  1451  
  1452  	if paren {
  1453  		if !space && (ps.last != '(' && ps.last != '*') {
  1454  			space = true
  1455  		}
  1456  		if space && ps.last != ' ' {
  1457  			ps.writeByte(' ')
  1458  		}
  1459  		ps.startScope('(')
  1460  	}
  1461  
  1462  	save := ps.printInner(true)
  1463  
  1464  	if paren {
  1465  		ps.endScope(')')
  1466  	}
  1467  
  1468  	ps.startScope('(')
  1469  	if !ft.ForLocalName || ps.enclosingParams {
  1470  		first := true
  1471  		for _, a := range ft.Args {
  1472  			if ps.isEmpty(a) {
  1473  				continue
  1474  			}
  1475  			if !first {
  1476  				ps.writeString(", ")
  1477  			}
  1478  			ps.print(a)
  1479  			first = false
  1480  		}
  1481  	}
  1482  	ps.endScope(')')
  1483  
  1484  	ps.inner = save
  1485  	ps.printInner(false)
  1486  }
  1487  
  1488  func (ft *FunctionType) Traverse(fn func(AST) bool) {
  1489  	if fn(ft) {
  1490  		if ft.Return != nil {
  1491  			ft.Return.Traverse(fn)
  1492  		}
  1493  		for _, a := range ft.Args {
  1494  			a.Traverse(fn)
  1495  		}
  1496  	}
  1497  }
  1498  
  1499  func (ft *FunctionType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1500  	if skip(ft) {
  1501  		return nil
  1502  	}
  1503  	changed := false
  1504  	var ret AST
  1505  	if ft.Return != nil {
  1506  		ret = ft.Return.Copy(fn, skip)
  1507  		if ret == nil {
  1508  			ret = ft.Return
  1509  		} else {
  1510  			changed = true
  1511  		}
  1512  	}
  1513  	args := make([]AST, len(ft.Args))
  1514  	for i, a := range ft.Args {
  1515  		ac := a.Copy(fn, skip)
  1516  		if ac == nil {
  1517  			args[i] = a
  1518  		} else {
  1519  			args[i] = ac
  1520  			changed = true
  1521  		}
  1522  	}
  1523  	if !changed {
  1524  		return fn(ft)
  1525  	}
  1526  	ft = &FunctionType{
  1527  		Return:       ret,
  1528  		Args:         args,
  1529  		ForLocalName: ft.ForLocalName,
  1530  	}
  1531  	if r := fn(ft); r != nil {
  1532  		return r
  1533  	}
  1534  	return ft
  1535  }
  1536  
  1537  func (ft *FunctionType) GoString() string {
  1538  	return ft.goString(0, "")
  1539  }
  1540  
  1541  func (ft *FunctionType) goString(indent int, field string) string {
  1542  	var forLocalName string
  1543  	if ft.ForLocalName {
  1544  		forLocalName = " ForLocalName: true"
  1545  	}
  1546  	var r string
  1547  	if ft.Return == nil {
  1548  		r = fmt.Sprintf("%*sReturn: nil", indent+2, "")
  1549  	} else {
  1550  		r = ft.Return.goString(indent+2, "Return: ")
  1551  	}
  1552  	var args string
  1553  	if len(ft.Args) == 0 {
  1554  		args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
  1555  	} else {
  1556  		args = fmt.Sprintf("%*sArgs:", indent+2, "")
  1557  		for i, a := range ft.Args {
  1558  			args += "\n"
  1559  			args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
  1560  		}
  1561  	}
  1562  	return fmt.Sprintf("%*s%sFunctionType:%s\n%s\n%s", indent, "", field,
  1563  		forLocalName, r, args)
  1564  }
  1565  
  1566  // FunctionParam is a parameter of a function, used for last-specified
  1567  // return type in a closure.
  1568  type FunctionParam struct {
  1569  	Index int
  1570  }
  1571  
  1572  func (fp *FunctionParam) print(ps *printState) {
  1573  	if fp.Index == 0 {
  1574  		ps.writeString("this")
  1575  	} else if ps.llvmStyle {
  1576  		if fp.Index == 1 {
  1577  			ps.writeString("fp")
  1578  		} else {
  1579  			fmt.Fprintf(&ps.buf, "fp%d", fp.Index-2)
  1580  		}
  1581  	} else {
  1582  		fmt.Fprintf(&ps.buf, "{parm#%d}", fp.Index)
  1583  	}
  1584  }
  1585  
  1586  func (fp *FunctionParam) Traverse(fn func(AST) bool) {
  1587  	fn(fp)
  1588  }
  1589  
  1590  func (fp *FunctionParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1591  	if skip(fp) {
  1592  		return nil
  1593  	}
  1594  	return fn(fp)
  1595  }
  1596  
  1597  func (fp *FunctionParam) GoString() string {
  1598  	return fp.goString(0, "")
  1599  }
  1600  
  1601  func (fp *FunctionParam) goString(indent int, field string) string {
  1602  	return fmt.Sprintf("%*s%sFunctionParam: %d", indent, "", field, fp.Index)
  1603  }
  1604  
  1605  func (fp *FunctionParam) prec() precedence {
  1606  	return precPrimary
  1607  }
  1608  
  1609  // PtrMem is a pointer-to-member expression.
  1610  type PtrMem struct {
  1611  	Class  AST
  1612  	Member AST
  1613  }
  1614  
  1615  func (pm *PtrMem) print(ps *printState) {
  1616  	ps.inner = append(ps.inner, pm)
  1617  	ps.print(pm.Member)
  1618  	if len(ps.inner) > 0 {
  1619  		ps.printOneInner(nil)
  1620  	}
  1621  }
  1622  
  1623  func (pm *PtrMem) printInner(ps *printState) {
  1624  	if ps.last != '(' {
  1625  		ps.writeByte(' ')
  1626  	}
  1627  	ps.print(pm.Class)
  1628  	ps.writeString("::*")
  1629  }
  1630  
  1631  func (pm *PtrMem) Traverse(fn func(AST) bool) {
  1632  	if fn(pm) {
  1633  		pm.Class.Traverse(fn)
  1634  		pm.Member.Traverse(fn)
  1635  	}
  1636  }
  1637  
  1638  func (pm *PtrMem) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1639  	if skip(pm) {
  1640  		return nil
  1641  	}
  1642  	class := pm.Class.Copy(fn, skip)
  1643  	member := pm.Member.Copy(fn, skip)
  1644  	if class == nil && member == nil {
  1645  		return fn(pm)
  1646  	}
  1647  	if class == nil {
  1648  		class = pm.Class
  1649  	}
  1650  	if member == nil {
  1651  		member = pm.Member
  1652  	}
  1653  	pm = &PtrMem{Class: class, Member: member}
  1654  	if r := fn(pm); r != nil {
  1655  		return r
  1656  	}
  1657  	return pm
  1658  }
  1659  
  1660  func (pm *PtrMem) GoString() string {
  1661  	return pm.goString(0, "")
  1662  }
  1663  
  1664  func (pm *PtrMem) goString(indent int, field string) string {
  1665  	return fmt.Sprintf("%*s%sPtrMem:\n%s\n%s", indent, "", field,
  1666  		pm.Class.goString(indent+2, "Class: "),
  1667  		pm.Member.goString(indent+2, "Member: "))
  1668  }
  1669  
  1670  // FixedType is a fixed numeric type of unknown size.
  1671  type FixedType struct {
  1672  	Base  AST
  1673  	Accum bool
  1674  	Sat   bool
  1675  }
  1676  
  1677  func (ft *FixedType) print(ps *printState) {
  1678  	if ft.Sat {
  1679  		ps.writeString("_Sat ")
  1680  	}
  1681  	if bt, ok := ft.Base.(*BuiltinType); ok && bt.Name == "int" {
  1682  		// The standard demangler skips printing "int".
  1683  	} else {
  1684  		ps.print(ft.Base)
  1685  		ps.writeByte(' ')
  1686  	}
  1687  	if ft.Accum {
  1688  		ps.writeString("_Accum")
  1689  	} else {
  1690  		ps.writeString("_Fract")
  1691  	}
  1692  }
  1693  
  1694  func (ft *FixedType) Traverse(fn func(AST) bool) {
  1695  	if fn(ft) {
  1696  		ft.Base.Traverse(fn)
  1697  	}
  1698  }
  1699  
  1700  func (ft *FixedType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1701  	if skip(ft) {
  1702  		return nil
  1703  	}
  1704  	base := ft.Base.Copy(fn, skip)
  1705  	if base == nil {
  1706  		return fn(ft)
  1707  	}
  1708  	ft = &FixedType{Base: base, Accum: ft.Accum, Sat: ft.Sat}
  1709  	if r := fn(ft); r != nil {
  1710  		return r
  1711  	}
  1712  	return ft
  1713  }
  1714  
  1715  func (ft *FixedType) GoString() string {
  1716  	return ft.goString(0, "")
  1717  }
  1718  
  1719  func (ft *FixedType) goString(indent int, field string) string {
  1720  	return fmt.Sprintf("%*s%sFixedType: Accum: %t; Sat: %t\n%s", indent, "", field,
  1721  		ft.Accum, ft.Sat,
  1722  		ft.Base.goString(indent+2, "Base: "))
  1723  }
  1724  
  1725  // BinaryFP is a binary floating-point type.
  1726  type BinaryFP struct {
  1727  	Bits int
  1728  }
  1729  
  1730  func (bfp *BinaryFP) print(ps *printState) {
  1731  	fmt.Fprintf(&ps.buf, "_Float%d", bfp.Bits)
  1732  }
  1733  
  1734  func (bfp *BinaryFP) Traverse(fn func(AST) bool) {
  1735  	fn(bfp)
  1736  }
  1737  
  1738  func (bfp *BinaryFP) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1739  	if skip(bfp) {
  1740  		return nil
  1741  	}
  1742  	return fn(bfp)
  1743  }
  1744  
  1745  func (bfp *BinaryFP) GoString() string {
  1746  	return bfp.goString(0, "")
  1747  }
  1748  
  1749  func (bfp *BinaryFP) goString(indent int, field string) string {
  1750  	return fmt.Sprintf("%*s%sBinaryFP: %d", indent, "", field, bfp.Bits)
  1751  }
  1752  
  1753  // BitIntType is the C++23 _BitInt(N) type.
  1754  type BitIntType struct {
  1755  	Size   AST
  1756  	Signed bool
  1757  }
  1758  
  1759  func (bt *BitIntType) print(ps *printState) {
  1760  	if !bt.Signed {
  1761  		ps.writeString("unsigned ")
  1762  	}
  1763  	ps.writeString("_BitInt")
  1764  	ps.startScope('(')
  1765  	ps.print(bt.Size)
  1766  	ps.endScope(')')
  1767  }
  1768  
  1769  func (bt *BitIntType) Traverse(fn func(AST) bool) {
  1770  	if fn(bt) {
  1771  		bt.Size.Traverse(fn)
  1772  	}
  1773  }
  1774  
  1775  func (bt *BitIntType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1776  	if skip(bt) {
  1777  		return nil
  1778  	}
  1779  	size := bt.Size.Copy(fn, skip)
  1780  	if size == nil {
  1781  		return fn(bt)
  1782  	}
  1783  	bt = &BitIntType{Size: size, Signed: bt.Signed}
  1784  	if r := fn(bt); r != nil {
  1785  		return r
  1786  	}
  1787  	return bt
  1788  }
  1789  
  1790  func (bt *BitIntType) GoString() string {
  1791  	return bt.goString(0, "")
  1792  }
  1793  
  1794  func (bt *BitIntType) goString(indent int, field string) string {
  1795  	return fmt.Sprintf("%*s%sBitIntType: Signed: %t\n%s", indent, "", field,
  1796  		bt.Signed,
  1797  		bt.Size.goString(indent+2, "Size: "))
  1798  }
  1799  
  1800  // VectorType is a vector type.
  1801  type VectorType struct {
  1802  	Dimension AST
  1803  	Base      AST
  1804  }
  1805  
  1806  func (vt *VectorType) print(ps *printState) {
  1807  	ps.inner = append(ps.inner, vt)
  1808  	ps.print(vt.Base)
  1809  	if len(ps.inner) > 0 {
  1810  		ps.printOneInner(nil)
  1811  	}
  1812  }
  1813  
  1814  func (vt *VectorType) printInner(ps *printState) {
  1815  	end := byte(')')
  1816  	if ps.llvmStyle {
  1817  		ps.writeString(" vector[")
  1818  		end = ']'
  1819  	} else {
  1820  		ps.writeString(" __vector(")
  1821  	}
  1822  	ps.print(vt.Dimension)
  1823  	ps.writeByte(end)
  1824  }
  1825  
  1826  func (vt *VectorType) Traverse(fn func(AST) bool) {
  1827  	if fn(vt) {
  1828  		vt.Dimension.Traverse(fn)
  1829  		vt.Base.Traverse(fn)
  1830  	}
  1831  }
  1832  
  1833  func (vt *VectorType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1834  	if skip(vt) {
  1835  		return nil
  1836  	}
  1837  	dimension := vt.Dimension.Copy(fn, skip)
  1838  	base := vt.Base.Copy(fn, skip)
  1839  	if dimension == nil && base == nil {
  1840  		return fn(vt)
  1841  	}
  1842  	if dimension == nil {
  1843  		dimension = vt.Dimension
  1844  	}
  1845  	if base == nil {
  1846  		base = vt.Base
  1847  	}
  1848  	vt = &VectorType{Dimension: dimension, Base: base}
  1849  	if r := fn(vt); r != nil {
  1850  		return r
  1851  	}
  1852  	return vt
  1853  }
  1854  
  1855  func (vt *VectorType) GoString() string {
  1856  	return vt.goString(0, "")
  1857  }
  1858  
  1859  func (vt *VectorType) goString(indent int, field string) string {
  1860  	return fmt.Sprintf("%*s%sVectorType:\n%s\n%s", indent, "", field,
  1861  		vt.Dimension.goString(indent+2, "Dimension: "),
  1862  		vt.Base.goString(indent+2, "Base: "))
  1863  }
  1864  
  1865  // ElaboratedType is an elaborated struct/union/enum type.
  1866  type ElaboratedType struct {
  1867  	Kind string
  1868  	Type AST
  1869  }
  1870  
  1871  func (et *ElaboratedType) print(ps *printState) {
  1872  	ps.writeString(et.Kind)
  1873  	ps.writeString(" ")
  1874  	et.Type.print(ps)
  1875  }
  1876  
  1877  func (et *ElaboratedType) Traverse(fn func(AST) bool) {
  1878  	if fn(et) {
  1879  		et.Type.Traverse(fn)
  1880  	}
  1881  }
  1882  
  1883  func (et *ElaboratedType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1884  	if skip(et) {
  1885  		return nil
  1886  	}
  1887  	typ := et.Type.Copy(fn, skip)
  1888  	if typ == nil {
  1889  		return fn(et)
  1890  	}
  1891  	et = &ElaboratedType{Kind: et.Kind, Type: typ}
  1892  	if r := fn(et); r != nil {
  1893  		return r
  1894  	}
  1895  	return et
  1896  }
  1897  
  1898  func (et *ElaboratedType) GoString() string {
  1899  	return et.goString(0, "")
  1900  }
  1901  
  1902  func (et *ElaboratedType) goString(indent int, field string) string {
  1903  	return fmt.Sprintf("%*s%sElaboratedtype: Kind: %s\n%s", indent, "", field,
  1904  		et.Kind, et.Type.goString(indent+2, "Expr: "))
  1905  }
  1906  
  1907  // Decltype is the decltype operator.
  1908  type Decltype struct {
  1909  	Expr AST
  1910  }
  1911  
  1912  func (dt *Decltype) print(ps *printState) {
  1913  	ps.writeString("decltype")
  1914  	if !ps.llvmStyle {
  1915  		ps.writeString(" ")
  1916  	}
  1917  	ps.startScope('(')
  1918  	ps.print(dt.Expr)
  1919  	ps.endScope(')')
  1920  }
  1921  
  1922  func (dt *Decltype) Traverse(fn func(AST) bool) {
  1923  	if fn(dt) {
  1924  		dt.Expr.Traverse(fn)
  1925  	}
  1926  }
  1927  
  1928  func (dt *Decltype) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1929  	if skip(dt) {
  1930  		return nil
  1931  	}
  1932  	expr := dt.Expr.Copy(fn, skip)
  1933  	if expr == nil {
  1934  		return fn(dt)
  1935  	}
  1936  	dt = &Decltype{Expr: expr}
  1937  	if r := fn(dt); r != nil {
  1938  		return r
  1939  	}
  1940  	return dt
  1941  }
  1942  
  1943  func (dt *Decltype) GoString() string {
  1944  	return dt.goString(0, "")
  1945  }
  1946  
  1947  func (dt *Decltype) goString(indent int, field string) string {
  1948  	return fmt.Sprintf("%*s%sDecltype:\n%s", indent, "", field,
  1949  		dt.Expr.goString(indent+2, "Expr: "))
  1950  }
  1951  
  1952  // Operator is an operator.
  1953  type Operator struct {
  1954  	Name       string
  1955  	precedence precedence
  1956  }
  1957  
  1958  func (op *Operator) print(ps *printState) {
  1959  	ps.writeString("operator")
  1960  	if isLower(op.Name[0]) {
  1961  		ps.writeByte(' ')
  1962  	}
  1963  	n := op.Name
  1964  	n = strings.TrimSuffix(n, " ")
  1965  	ps.writeString(n)
  1966  }
  1967  
  1968  func (op *Operator) Traverse(fn func(AST) bool) {
  1969  	fn(op)
  1970  }
  1971  
  1972  func (op *Operator) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1973  	if skip(op) {
  1974  		return nil
  1975  	}
  1976  	return fn(op)
  1977  }
  1978  
  1979  func (op *Operator) GoString() string {
  1980  	return op.goString(0, "")
  1981  }
  1982  
  1983  func (op *Operator) goString(indent int, field string) string {
  1984  	return fmt.Sprintf("%*s%sOperator: %s", indent, "", field, op.Name)
  1985  }
  1986  
  1987  func (op *Operator) prec() precedence {
  1988  	return op.precedence
  1989  }
  1990  
  1991  // Constructor is a constructor.
  1992  type Constructor struct {
  1993  	Name AST
  1994  	Base AST // base class of inheriting constructor
  1995  }
  1996  
  1997  func (c *Constructor) print(ps *printState) {
  1998  	ps.print(c.Name)
  1999  	// We don't include the base class in the demangled string.
  2000  }
  2001  
  2002  func (c *Constructor) Traverse(fn func(AST) bool) {
  2003  	if fn(c) {
  2004  		c.Name.Traverse(fn)
  2005  		if c.Base != nil {
  2006  			c.Base.Traverse(fn)
  2007  		}
  2008  	}
  2009  }
  2010  
  2011  func (c *Constructor) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2012  	if skip(c) {
  2013  		return nil
  2014  	}
  2015  	name := c.Name.Copy(fn, skip)
  2016  	var base AST
  2017  	if c.Base != nil {
  2018  		base = c.Base.Copy(fn, skip)
  2019  	}
  2020  	if name == nil && base == nil {
  2021  		return fn(c)
  2022  	}
  2023  	if name == nil {
  2024  		name = c.Name
  2025  	}
  2026  	if base == nil {
  2027  		base = c.Base
  2028  	}
  2029  	c = &Constructor{Name: name, Base: base}
  2030  	if r := fn(c); r != nil {
  2031  		return r
  2032  	}
  2033  	return c
  2034  }
  2035  
  2036  func (c *Constructor) GoString() string {
  2037  	return c.goString(0, "")
  2038  }
  2039  
  2040  func (c *Constructor) goString(indent int, field string) string {
  2041  	var sb strings.Builder
  2042  	fmt.Fprintf(&sb, "%*s%sConstructor:\n", indent, "", field)
  2043  	if c.Base != nil {
  2044  		fmt.Fprintf(&sb, "%s\n", c.Base.goString(indent+2, "Base: "))
  2045  	}
  2046  	fmt.Fprintf(&sb, "%s", c.Name.goString(indent+2, "Name: "))
  2047  	return sb.String()
  2048  }
  2049  
  2050  // Destructor is a destructor.
  2051  type Destructor struct {
  2052  	Name AST
  2053  }
  2054  
  2055  func (d *Destructor) print(ps *printState) {
  2056  	ps.writeByte('~')
  2057  	ps.print(d.Name)
  2058  }
  2059  
  2060  func (d *Destructor) Traverse(fn func(AST) bool) {
  2061  	if fn(d) {
  2062  		d.Name.Traverse(fn)
  2063  	}
  2064  }
  2065  
  2066  func (d *Destructor) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2067  	if skip(d) {
  2068  		return nil
  2069  	}
  2070  	name := d.Name.Copy(fn, skip)
  2071  	if name == nil {
  2072  		return fn(d)
  2073  	}
  2074  	d = &Destructor{Name: name}
  2075  	if r := fn(d); r != nil {
  2076  		return r
  2077  	}
  2078  	return d
  2079  }
  2080  
  2081  func (d *Destructor) GoString() string {
  2082  	return d.goString(0, "")
  2083  }
  2084  
  2085  func (d *Destructor) goString(indent int, field string) string {
  2086  	return fmt.Sprintf("%*s%sDestructor:\n%s", indent, "", field, d.Name.goString(indent+2, "Name: "))
  2087  }
  2088  
  2089  // GlobalCDtor is a global constructor or destructor.
  2090  type GlobalCDtor struct {
  2091  	Ctor bool
  2092  	Key  AST
  2093  }
  2094  
  2095  func (gcd *GlobalCDtor) print(ps *printState) {
  2096  	ps.writeString("global ")
  2097  	if gcd.Ctor {
  2098  		ps.writeString("constructors")
  2099  	} else {
  2100  		ps.writeString("destructors")
  2101  	}
  2102  	ps.writeString(" keyed to ")
  2103  	ps.print(gcd.Key)
  2104  }
  2105  
  2106  func (gcd *GlobalCDtor) Traverse(fn func(AST) bool) {
  2107  	if fn(gcd) {
  2108  		gcd.Key.Traverse(fn)
  2109  	}
  2110  }
  2111  
  2112  func (gcd *GlobalCDtor) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2113  	if skip(gcd) {
  2114  		return nil
  2115  	}
  2116  	key := gcd.Key.Copy(fn, skip)
  2117  	if key == nil {
  2118  		return fn(gcd)
  2119  	}
  2120  	gcd = &GlobalCDtor{Ctor: gcd.Ctor, Key: key}
  2121  	if r := fn(gcd); r != nil {
  2122  		return r
  2123  	}
  2124  	return gcd
  2125  }
  2126  
  2127  func (gcd *GlobalCDtor) GoString() string {
  2128  	return gcd.goString(0, "")
  2129  }
  2130  
  2131  func (gcd *GlobalCDtor) goString(indent int, field string) string {
  2132  	return fmt.Sprintf("%*s%sGlobalCDtor: Ctor: %t\n%s", indent, "", field,
  2133  		gcd.Ctor, gcd.Key.goString(indent+2, "Key: "))
  2134  }
  2135  
  2136  // TaggedName is a name with an ABI tag.
  2137  type TaggedName struct {
  2138  	Name AST
  2139  	Tag  AST
  2140  }
  2141  
  2142  func (t *TaggedName) print(ps *printState) {
  2143  	ps.print(t.Name)
  2144  	ps.writeString("[abi:")
  2145  	ps.print(t.Tag)
  2146  	ps.writeByte(']')
  2147  }
  2148  
  2149  func (t *TaggedName) Traverse(fn func(AST) bool) {
  2150  	if fn(t) {
  2151  		t.Name.Traverse(fn)
  2152  		t.Tag.Traverse(fn)
  2153  	}
  2154  }
  2155  
  2156  func (t *TaggedName) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2157  	if skip(t) {
  2158  		return nil
  2159  	}
  2160  	name := t.Name.Copy(fn, skip)
  2161  	tag := t.Tag.Copy(fn, skip)
  2162  	if name == nil && tag == nil {
  2163  		return fn(t)
  2164  	}
  2165  	if name == nil {
  2166  		name = t.Name
  2167  	}
  2168  	if tag == nil {
  2169  		tag = t.Tag
  2170  	}
  2171  	t = &TaggedName{Name: name, Tag: tag}
  2172  	if r := fn(t); r != nil {
  2173  		return r
  2174  	}
  2175  	return t
  2176  }
  2177  
  2178  func (t *TaggedName) GoString() string {
  2179  	return t.goString(0, "")
  2180  }
  2181  
  2182  func (t *TaggedName) goString(indent int, field string) string {
  2183  	return fmt.Sprintf("%*s%sTaggedName:\n%s\n%s", indent, "", field,
  2184  		t.Name.goString(indent+2, "Name: "),
  2185  		t.Tag.goString(indent+2, "Tag: "))
  2186  }
  2187  
  2188  // PackExpansion is a pack expansion.  The Pack field may be nil.
  2189  type PackExpansion struct {
  2190  	Base AST
  2191  	Pack *ArgumentPack
  2192  }
  2193  
  2194  func (pe *PackExpansion) print(ps *printState) {
  2195  	// We normally only get here if the simplify function was
  2196  	// unable to locate and expand the pack.
  2197  	if pe.Pack == nil {
  2198  		if ps.llvmStyle {
  2199  			ps.print(pe.Base)
  2200  		} else {
  2201  			parenthesize(ps, pe.Base)
  2202  			ps.writeString("...")
  2203  		}
  2204  	} else {
  2205  		ps.print(pe.Base)
  2206  	}
  2207  }
  2208  
  2209  func (pe *PackExpansion) Traverse(fn func(AST) bool) {
  2210  	if fn(pe) {
  2211  		pe.Base.Traverse(fn)
  2212  		// Don't traverse Template--it points elsewhere in the AST.
  2213  	}
  2214  }
  2215  
  2216  func (pe *PackExpansion) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2217  	if skip(pe) {
  2218  		return nil
  2219  	}
  2220  	base := pe.Base.Copy(fn, skip)
  2221  	if base == nil {
  2222  		return fn(pe)
  2223  	}
  2224  	pe = &PackExpansion{Base: base, Pack: pe.Pack}
  2225  	if r := fn(pe); r != nil {
  2226  		return r
  2227  	}
  2228  	return pe
  2229  }
  2230  
  2231  func (pe *PackExpansion) GoString() string {
  2232  	return pe.goString(0, "")
  2233  }
  2234  
  2235  func (pe *PackExpansion) goString(indent int, field string) string {
  2236  	return fmt.Sprintf("%*s%sPackExpansion: Pack: %p\n%s", indent, "", field,
  2237  		pe.Pack, pe.Base.goString(indent+2, "Base: "))
  2238  }
  2239  
  2240  // ArgumentPack is an argument pack.
  2241  type ArgumentPack struct {
  2242  	Args []AST
  2243  }
  2244  
  2245  func (ap *ArgumentPack) print(ps *printState) {
  2246  	for i, a := range ap.Args {
  2247  		if i > 0 {
  2248  			ps.writeString(", ")
  2249  		}
  2250  		ps.print(a)
  2251  	}
  2252  }
  2253  
  2254  func (ap *ArgumentPack) Traverse(fn func(AST) bool) {
  2255  	if fn(ap) {
  2256  		for _, a := range ap.Args {
  2257  			a.Traverse(fn)
  2258  		}
  2259  	}
  2260  }
  2261  
  2262  func (ap *ArgumentPack) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2263  	if skip(ap) {
  2264  		return nil
  2265  	}
  2266  	args := make([]AST, len(ap.Args))
  2267  	changed := false
  2268  	for i, a := range ap.Args {
  2269  		ac := a.Copy(fn, skip)
  2270  		if ac == nil {
  2271  			args[i] = a
  2272  		} else {
  2273  			args[i] = ac
  2274  			changed = true
  2275  		}
  2276  	}
  2277  	if !changed {
  2278  		return fn(ap)
  2279  	}
  2280  	ap = &ArgumentPack{Args: args}
  2281  	if r := fn(ap); r != nil {
  2282  		return r
  2283  	}
  2284  	return ap
  2285  }
  2286  
  2287  func (ap *ArgumentPack) GoString() string {
  2288  	return ap.goString(0, "")
  2289  }
  2290  
  2291  func (ap *ArgumentPack) goString(indent int, field string) string {
  2292  	if len(ap.Args) == 0 {
  2293  		return fmt.Sprintf("%*s%sArgumentPack: nil", indent, "", field)
  2294  	}
  2295  	s := fmt.Sprintf("%*s%sArgumentPack:", indent, "", field)
  2296  	for i, a := range ap.Args {
  2297  		s += "\n"
  2298  		s += a.goString(indent+2, fmt.Sprintf("%d: ", i))
  2299  	}
  2300  	return s
  2301  }
  2302  
  2303  // SizeofPack is the sizeof operator applied to an argument pack.
  2304  type SizeofPack struct {
  2305  	Pack *ArgumentPack
  2306  }
  2307  
  2308  func (sp *SizeofPack) print(ps *printState) {
  2309  	if ps.llvmStyle {
  2310  		ps.writeString("sizeof...")
  2311  		ps.startScope('(')
  2312  		ps.print(sp.Pack)
  2313  		ps.endScope(')')
  2314  	} else {
  2315  		ps.writeString(fmt.Sprintf("%d", len(sp.Pack.Args)))
  2316  	}
  2317  }
  2318  
  2319  func (sp *SizeofPack) Traverse(fn func(AST) bool) {
  2320  	fn(sp)
  2321  	// Don't traverse the pack--it points elsewhere in the AST.
  2322  }
  2323  
  2324  func (sp *SizeofPack) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2325  	if skip(sp) {
  2326  		return nil
  2327  	}
  2328  	sp = &SizeofPack{Pack: sp.Pack}
  2329  	if r := fn(sp); r != nil {
  2330  		return r
  2331  	}
  2332  	return sp
  2333  }
  2334  
  2335  func (sp *SizeofPack) GoString() string {
  2336  	return sp.goString(0, "")
  2337  }
  2338  
  2339  func (sp *SizeofPack) goString(indent int, field string) string {
  2340  	return fmt.Sprintf("%*s%sSizeofPack: Pack: %p", indent, "", field, sp.Pack)
  2341  }
  2342  
  2343  // SizeofArgs is the size of a captured template parameter pack from
  2344  // an alias template.
  2345  type SizeofArgs struct {
  2346  	Args []AST
  2347  }
  2348  
  2349  func (sa *SizeofArgs) print(ps *printState) {
  2350  	c := 0
  2351  	for _, a := range sa.Args {
  2352  		if ap, ok := a.(*ArgumentPack); ok {
  2353  			c += len(ap.Args)
  2354  		} else if el, ok := a.(*ExprList); ok {
  2355  			c += len(el.Exprs)
  2356  		} else {
  2357  			c++
  2358  		}
  2359  	}
  2360  	ps.writeString(fmt.Sprintf("%d", c))
  2361  }
  2362  
  2363  func (sa *SizeofArgs) Traverse(fn func(AST) bool) {
  2364  	if fn(sa) {
  2365  		for _, a := range sa.Args {
  2366  			a.Traverse(fn)
  2367  		}
  2368  	}
  2369  }
  2370  
  2371  func (sa *SizeofArgs) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2372  	if skip(sa) {
  2373  		return nil
  2374  	}
  2375  	changed := false
  2376  	args := make([]AST, len(sa.Args))
  2377  	for i, a := range sa.Args {
  2378  		ac := a.Copy(fn, skip)
  2379  		if ac == nil {
  2380  			args[i] = a
  2381  		} else {
  2382  			args[i] = ac
  2383  			changed = true
  2384  		}
  2385  	}
  2386  	if !changed {
  2387  		return fn(sa)
  2388  	}
  2389  	sa = &SizeofArgs{Args: args}
  2390  	if r := fn(sa); r != nil {
  2391  		return r
  2392  	}
  2393  	return sa
  2394  }
  2395  
  2396  func (sa *SizeofArgs) GoString() string {
  2397  	return sa.goString(0, "")
  2398  }
  2399  
  2400  func (sa *SizeofArgs) goString(indent int, field string) string {
  2401  	var args string
  2402  	if len(sa.Args) == 0 {
  2403  		args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
  2404  	} else {
  2405  		args = fmt.Sprintf("%*sArgs:", indent+2, "")
  2406  		for i, a := range sa.Args {
  2407  			args += "\n"
  2408  			args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
  2409  		}
  2410  	}
  2411  	return fmt.Sprintf("%*s%sSizeofArgs:\n%s", indent, "", field, args)
  2412  }
  2413  
  2414  // TemplateParamName is the name of a template parameter that the
  2415  // demangler introduced for a lambda that has explicit template
  2416  // parameters.  This is a prefix with an index.
  2417  type TemplateParamName struct {
  2418  	Prefix string
  2419  	Index  int
  2420  }
  2421  
  2422  func (tpn *TemplateParamName) print(ps *printState) {
  2423  	ps.writeString(tpn.Prefix)
  2424  	if tpn.Index > 0 {
  2425  		ps.writeString(fmt.Sprintf("%d", tpn.Index-1))
  2426  	}
  2427  }
  2428  
  2429  func (tpn *TemplateParamName) Traverse(fn func(AST) bool) {
  2430  	fn(tpn)
  2431  }
  2432  
  2433  func (tpn *TemplateParamName) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2434  	if skip(tpn) {
  2435  		return nil
  2436  	}
  2437  	return fn(tpn)
  2438  }
  2439  
  2440  func (tpn *TemplateParamName) GoString() string {
  2441  	return tpn.goString(0, "")
  2442  }
  2443  
  2444  func (tpn *TemplateParamName) goString(indent int, field string) string {
  2445  	name := tpn.Prefix
  2446  	if tpn.Index > 0 {
  2447  		name += fmt.Sprintf("%d", tpn.Index-1)
  2448  	}
  2449  	return fmt.Sprintf("%*s%sTemplateParamName: %s", indent, "", field, name)
  2450  }
  2451  
  2452  // TypeTemplateParam is a type template parameter that appears in a
  2453  // lambda with explicit template parameters.
  2454  type TypeTemplateParam struct {
  2455  	Name AST
  2456  }
  2457  
  2458  func (ttp *TypeTemplateParam) print(ps *printState) {
  2459  	ps.writeString("typename ")
  2460  	ps.printInner(false)
  2461  	ps.print(ttp.Name)
  2462  }
  2463  
  2464  func (ttp *TypeTemplateParam) Traverse(fn func(AST) bool) {
  2465  	if fn(ttp) {
  2466  		ttp.Name.Traverse(fn)
  2467  	}
  2468  }
  2469  
  2470  func (ttp *TypeTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2471  	if skip(ttp) {
  2472  		return nil
  2473  	}
  2474  	name := ttp.Name.Copy(fn, skip)
  2475  	if name == nil {
  2476  		return fn(ttp)
  2477  	}
  2478  	ttp = &TypeTemplateParam{Name: name}
  2479  	if r := fn(ttp); r != nil {
  2480  		return r
  2481  	}
  2482  	return ttp
  2483  }
  2484  
  2485  func (ttp *TypeTemplateParam) GoString() string {
  2486  	return ttp.goString(0, "")
  2487  }
  2488  
  2489  func (ttp *TypeTemplateParam) goString(indent int, field string) string {
  2490  	return fmt.Sprintf("%*s%sTypeTemplateParam:\n%s", indent, "", field,
  2491  		ttp.Name.goString(indent+2, "Name"))
  2492  }
  2493  
  2494  // NonTypeTemplateParam is a non-type template parameter that appears
  2495  // in a lambda with explicit template parameters.
  2496  type NonTypeTemplateParam struct {
  2497  	Name AST
  2498  	Type AST
  2499  }
  2500  
  2501  func (nttp *NonTypeTemplateParam) print(ps *printState) {
  2502  	ps.inner = append(ps.inner, nttp)
  2503  	ps.print(nttp.Type)
  2504  	if len(ps.inner) > 0 {
  2505  		ps.writeByte(' ')
  2506  		ps.print(nttp.Name)
  2507  		ps.inner = ps.inner[:len(ps.inner)-1]
  2508  	}
  2509  }
  2510  
  2511  func (nttp *NonTypeTemplateParam) printInner(ps *printState) {
  2512  	ps.print(nttp.Name)
  2513  }
  2514  
  2515  func (nttp *NonTypeTemplateParam) Traverse(fn func(AST) bool) {
  2516  	if fn(nttp) {
  2517  		nttp.Name.Traverse(fn)
  2518  		nttp.Type.Traverse(fn)
  2519  	}
  2520  }
  2521  
  2522  func (nttp *NonTypeTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2523  	if skip(nttp) {
  2524  		return nil
  2525  	}
  2526  	name := nttp.Name.Copy(fn, skip)
  2527  	typ := nttp.Type.Copy(fn, skip)
  2528  	if name == nil && typ == nil {
  2529  		return fn(nttp)
  2530  	}
  2531  	if name == nil {
  2532  		name = nttp.Name
  2533  	}
  2534  	if typ == nil {
  2535  		typ = nttp.Type
  2536  	}
  2537  	nttp = &NonTypeTemplateParam{Name: name, Type: typ}
  2538  	if r := fn(nttp); r != nil {
  2539  		return r
  2540  	}
  2541  	return nttp
  2542  }
  2543  
  2544  func (nttp *NonTypeTemplateParam) GoString() string {
  2545  	return nttp.goString(0, "")
  2546  }
  2547  
  2548  func (nttp *NonTypeTemplateParam) goString(indent int, field string) string {
  2549  	return fmt.Sprintf("%*s%sNonTypeTemplateParam:\n%s\n%s", indent, "", field,
  2550  		nttp.Name.goString(indent+2, "Name: "),
  2551  		nttp.Type.goString(indent+2, "Type: "))
  2552  }
  2553  
  2554  // TemplateTemplateParam is a template template parameter that appears
  2555  // in a lambda with explicit template parameters.
  2556  type TemplateTemplateParam struct {
  2557  	Name       AST
  2558  	Params     []AST
  2559  	Constraint AST
  2560  }
  2561  
  2562  func (ttp *TemplateTemplateParam) print(ps *printState) {
  2563  	scopes := ps.scopes
  2564  	ps.scopes = 0
  2565  
  2566  	ps.writeString("template<")
  2567  	ps.printList(ttp.Params, nil)
  2568  	ps.writeString("> typename ")
  2569  
  2570  	ps.scopes = scopes
  2571  
  2572  	ps.print(ttp.Name)
  2573  
  2574  	if ttp.Constraint != nil {
  2575  		ps.writeString(" requires ")
  2576  		ps.print(ttp.Constraint)
  2577  	}
  2578  }
  2579  
  2580  func (ttp *TemplateTemplateParam) Traverse(fn func(AST) bool) {
  2581  	if fn(ttp) {
  2582  		ttp.Name.Traverse(fn)
  2583  		for _, param := range ttp.Params {
  2584  			param.Traverse(fn)
  2585  		}
  2586  		if ttp.Constraint != nil {
  2587  			ttp.Constraint.Traverse(fn)
  2588  		}
  2589  	}
  2590  }
  2591  
  2592  func (ttp *TemplateTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2593  	if skip(ttp) {
  2594  		return nil
  2595  	}
  2596  
  2597  	changed := false
  2598  
  2599  	name := ttp.Name.Copy(fn, skip)
  2600  	if name == nil {
  2601  		name = ttp.Name
  2602  	} else {
  2603  		changed = true
  2604  	}
  2605  
  2606  	params := make([]AST, len(ttp.Params))
  2607  	for i, p := range ttp.Params {
  2608  		pc := p.Copy(fn, skip)
  2609  		if pc == nil {
  2610  			params[i] = p
  2611  		} else {
  2612  			params[i] = pc
  2613  			changed = true
  2614  		}
  2615  	}
  2616  
  2617  	var constraint AST
  2618  	if ttp.Constraint != nil {
  2619  		constraint = ttp.Constraint.Copy(fn, skip)
  2620  		if constraint == nil {
  2621  			constraint = ttp.Constraint
  2622  		} else {
  2623  			changed = true
  2624  		}
  2625  	}
  2626  
  2627  	if !changed {
  2628  		return fn(ttp)
  2629  	}
  2630  
  2631  	ttp = &TemplateTemplateParam{
  2632  		Name:       name,
  2633  		Params:     params,
  2634  		Constraint: constraint,
  2635  	}
  2636  	if r := fn(ttp); r != nil {
  2637  		return r
  2638  	}
  2639  	return ttp
  2640  }
  2641  
  2642  func (ttp *TemplateTemplateParam) GoString() string {
  2643  	return ttp.goString(0, "")
  2644  }
  2645  
  2646  func (ttp *TemplateTemplateParam) goString(indent int, field string) string {
  2647  	var params strings.Builder
  2648  	fmt.Fprintf(&params, "%*sParams:", indent+2, "")
  2649  	for i, p := range ttp.Params {
  2650  		params.WriteByte('\n')
  2651  		params.WriteString(p.goString(indent+4, fmt.Sprintf("%d: ", i)))
  2652  	}
  2653  	var constraint string
  2654  	if ttp.Constraint == nil {
  2655  		constraint = fmt.Sprintf("%*sConstraint: nil", indent+2, "")
  2656  	} else {
  2657  		constraint = ttp.Constraint.goString(indent+2, "Constraint: ")
  2658  	}
  2659  	return fmt.Sprintf("%*s%sTemplateTemplateParam:\n%s\n%s\n%s", indent, "", field,
  2660  		ttp.Name.goString(indent+2, "Name: "),
  2661  		params.String(),
  2662  		constraint)
  2663  }
  2664  
  2665  // ConstrainedTypeTemplateParam is a constrained template type
  2666  // parameter declaration.
  2667  type ConstrainedTypeTemplateParam struct {
  2668  	Name       AST
  2669  	Constraint AST
  2670  }
  2671  
  2672  func (cttp *ConstrainedTypeTemplateParam) print(ps *printState) {
  2673  	ps.inner = append(ps.inner, cttp)
  2674  	ps.print(cttp.Constraint)
  2675  	if len(ps.inner) > 0 {
  2676  		ps.writeByte(' ')
  2677  		ps.print(cttp.Name)
  2678  		ps.inner = ps.inner[:len(ps.inner)-1]
  2679  	}
  2680  }
  2681  
  2682  func (cttp *ConstrainedTypeTemplateParam) printInner(ps *printState) {
  2683  	ps.print(cttp.Name)
  2684  }
  2685  
  2686  func (cttp *ConstrainedTypeTemplateParam) Traverse(fn func(AST) bool) {
  2687  	if fn(cttp) {
  2688  		cttp.Name.Traverse(fn)
  2689  		cttp.Constraint.Traverse(fn)
  2690  	}
  2691  }
  2692  
  2693  func (cttp *ConstrainedTypeTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2694  	if skip(cttp) {
  2695  		return nil
  2696  	}
  2697  	name := cttp.Name.Copy(fn, skip)
  2698  	constraint := cttp.Constraint.Copy(fn, skip)
  2699  	if name == nil && constraint == nil {
  2700  		return fn(cttp)
  2701  	}
  2702  	if name == nil {
  2703  		name = cttp.Name
  2704  	}
  2705  	if constraint == nil {
  2706  		constraint = cttp.Constraint
  2707  	}
  2708  	cttp = &ConstrainedTypeTemplateParam{Name: name, Constraint: constraint}
  2709  	if r := fn(cttp); r != nil {
  2710  		return r
  2711  	}
  2712  	return cttp
  2713  }
  2714  
  2715  func (cttp *ConstrainedTypeTemplateParam) GoString() string {
  2716  	return cttp.goString(0, "")
  2717  }
  2718  
  2719  func (cttp *ConstrainedTypeTemplateParam) goString(indent int, field string) string {
  2720  	return fmt.Sprintf("%*s%sConstrainedTypeTemplateParam\n%s\n%s", indent, "", field,
  2721  		cttp.Name.goString(indent+2, "Name: "),
  2722  		cttp.Constraint.goString(indent+2, "Constraint: "))
  2723  }
  2724  
  2725  // TemplateParamPack is a template parameter pack that appears in a
  2726  // lambda with explicit template parameters.
  2727  type TemplateParamPack struct {
  2728  	Param AST
  2729  }
  2730  
  2731  func (tpp *TemplateParamPack) print(ps *printState) {
  2732  	holdInner := ps.inner
  2733  	defer func() { ps.inner = holdInner }()
  2734  
  2735  	ps.inner = []AST{tpp}
  2736  	if nttp, ok := tpp.Param.(*NonTypeTemplateParam); ok {
  2737  		ps.print(nttp.Type)
  2738  	} else {
  2739  		ps.print(tpp.Param)
  2740  	}
  2741  	if len(ps.inner) > 0 {
  2742  		ps.writeString("...")
  2743  	}
  2744  }
  2745  
  2746  func (tpp *TemplateParamPack) printInner(ps *printState) {
  2747  	ps.writeString("...")
  2748  	if nttp, ok := tpp.Param.(*NonTypeTemplateParam); ok {
  2749  		ps.print(nttp.Name)
  2750  	}
  2751  }
  2752  
  2753  func (tpp *TemplateParamPack) Traverse(fn func(AST) bool) {
  2754  	if fn(tpp) {
  2755  		tpp.Param.Traverse(fn)
  2756  	}
  2757  }
  2758  
  2759  func (tpp *TemplateParamPack) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2760  	if skip(tpp) {
  2761  		return nil
  2762  	}
  2763  	param := tpp.Param.Copy(fn, skip)
  2764  	if param == nil {
  2765  		return fn(tpp)
  2766  	}
  2767  	tpp = &TemplateParamPack{Param: param}
  2768  	if r := fn(tpp); r != nil {
  2769  		return r
  2770  	}
  2771  	return tpp
  2772  }
  2773  
  2774  func (tpp *TemplateParamPack) GoString() string {
  2775  	return tpp.goString(0, "")
  2776  }
  2777  
  2778  func (tpp *TemplateParamPack) goString(indent int, field string) string {
  2779  	return fmt.Sprintf("%*s%sTemplateParamPack:\n%s", indent, "", field,
  2780  		tpp.Param.goString(indent+2, "Param: "))
  2781  }
  2782  
  2783  // Cast is a type cast.
  2784  type Cast struct {
  2785  	To AST
  2786  }
  2787  
  2788  func (c *Cast) print(ps *printState) {
  2789  	ps.writeString("operator ")
  2790  	ps.print(c.To)
  2791  }
  2792  
  2793  func (c *Cast) Traverse(fn func(AST) bool) {
  2794  	if fn(c) {
  2795  		c.To.Traverse(fn)
  2796  	}
  2797  }
  2798  
  2799  func (c *Cast) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2800  	if skip(c) {
  2801  		return nil
  2802  	}
  2803  	to := c.To.Copy(fn, skip)
  2804  	if to == nil {
  2805  		return fn(c)
  2806  	}
  2807  	c = &Cast{To: to}
  2808  	if r := fn(c); r != nil {
  2809  		return r
  2810  	}
  2811  	return c
  2812  }
  2813  
  2814  func (c *Cast) GoString() string {
  2815  	return c.goString(0, "")
  2816  }
  2817  
  2818  func (c *Cast) goString(indent int, field string) string {
  2819  	return fmt.Sprintf("%*s%sCast\n%s", indent, "", field,
  2820  		c.To.goString(indent+2, "To: "))
  2821  }
  2822  
  2823  func (c *Cast) prec() precedence {
  2824  	return precCast
  2825  }
  2826  
  2827  // The parenthesize function prints the string for val, wrapped in
  2828  // parentheses if necessary.
  2829  func parenthesize(ps *printState, val AST) {
  2830  	paren := false
  2831  	switch v := val.(type) {
  2832  	case *Name, *InitializerList:
  2833  	case *FunctionParam:
  2834  		if ps.llvmStyle {
  2835  			paren = true
  2836  		}
  2837  	case *Qualified:
  2838  		if v.LocalName {
  2839  			paren = true
  2840  		}
  2841  	default:
  2842  		paren = true
  2843  	}
  2844  	if paren {
  2845  		ps.startScope('(')
  2846  	}
  2847  	ps.print(val)
  2848  	if paren {
  2849  		ps.endScope(')')
  2850  	}
  2851  }
  2852  
  2853  // Nullary is an operator in an expression with no arguments, such as
  2854  // throw.
  2855  type Nullary struct {
  2856  	Op AST
  2857  }
  2858  
  2859  func (n *Nullary) print(ps *printState) {
  2860  	if op, ok := n.Op.(*Operator); ok {
  2861  		ps.writeString(op.Name)
  2862  	} else {
  2863  		ps.print(n.Op)
  2864  	}
  2865  }
  2866  
  2867  func (n *Nullary) Traverse(fn func(AST) bool) {
  2868  	if fn(n) {
  2869  		n.Op.Traverse(fn)
  2870  	}
  2871  }
  2872  
  2873  func (n *Nullary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2874  	if skip(n) {
  2875  		return nil
  2876  	}
  2877  	op := n.Op.Copy(fn, skip)
  2878  	if op == nil {
  2879  		return fn(n)
  2880  	}
  2881  	n = &Nullary{Op: op}
  2882  	if r := fn(n); r != nil {
  2883  		return r
  2884  	}
  2885  	return n
  2886  }
  2887  
  2888  func (n *Nullary) GoString() string {
  2889  	return n.goString(0, "")
  2890  }
  2891  
  2892  func (n *Nullary) goString(indent int, field string) string {
  2893  	return fmt.Sprintf("%*s%sNullary:\n%s", indent, "", field,
  2894  		n.Op.goString(indent+2, "Op: "))
  2895  }
  2896  
  2897  // Unary is a unary operation in an expression.
  2898  type Unary struct {
  2899  	Op         AST
  2900  	Expr       AST
  2901  	Suffix     bool // true for ++ -- when used as postfix
  2902  	SizeofType bool // true for sizeof (type)
  2903  }
  2904  
  2905  func (u *Unary) print(ps *printState) {
  2906  	op, _ := u.Op.(*Operator)
  2907  	expr := u.Expr
  2908  
  2909  	// Don't print the argument list when taking the address of a
  2910  	// function.
  2911  	if !ps.llvmStyle {
  2912  		if op != nil && op.Name == "&" {
  2913  			if t, ok := expr.(*Typed); ok {
  2914  				if _, ok := t.Type.(*FunctionType); ok {
  2915  					expr = t.Name
  2916  				}
  2917  			}
  2918  		}
  2919  	}
  2920  
  2921  	if u.Suffix {
  2922  		if ps.llvmStyle {
  2923  			wantParens := true
  2924  			opPrec := precUnary
  2925  			if op != nil {
  2926  				opPrec = op.precedence
  2927  			}
  2928  			if p, ok := expr.(hasPrec); ok {
  2929  				if p.prec() < opPrec {
  2930  					wantParens = false
  2931  				}
  2932  			}
  2933  			if wantParens {
  2934  				ps.startScope('(')
  2935  			}
  2936  			ps.print(expr)
  2937  			if wantParens {
  2938  				ps.endScope(')')
  2939  			}
  2940  		} else {
  2941  			parenthesize(ps, expr)
  2942  		}
  2943  	}
  2944  
  2945  	if op != nil {
  2946  		ps.writeString(op.Name)
  2947  		if ps.llvmStyle && op.Name == "noexcept" {
  2948  			ps.writeByte(' ')
  2949  		}
  2950  	} else if c, ok := u.Op.(*Cast); ok {
  2951  		ps.startScope('(')
  2952  		ps.print(c.To)
  2953  		ps.endScope(')')
  2954  	} else {
  2955  		ps.print(u.Op)
  2956  	}
  2957  
  2958  	if !u.Suffix {
  2959  		isDelete := op != nil && (op.Name == "delete " || op.Name == "delete[] ")
  2960  		if op != nil && op.Name == "::" {
  2961  			// Don't use parentheses after ::.
  2962  			ps.print(expr)
  2963  		} else if u.SizeofType {
  2964  			// Always use parentheses for sizeof argument.
  2965  			ps.startScope('(')
  2966  			ps.print(expr)
  2967  			ps.endScope(')')
  2968  		} else if op != nil && op.Name == "__alignof__" {
  2969  			// Always use parentheses for __alignof__ argument.
  2970  			ps.startScope('(')
  2971  			ps.print(expr)
  2972  			ps.endScope(')')
  2973  		} else if ps.llvmStyle {
  2974  			var wantParens bool
  2975  			switch {
  2976  			case op == nil:
  2977  				wantParens = true
  2978  			case op.Name == `operator"" `:
  2979  				wantParens = false
  2980  			case op.Name == "&":
  2981  				wantParens = false
  2982  			case isDelete:
  2983  				wantParens = false
  2984  			case op.Name == "alignof ":
  2985  				wantParens = true
  2986  			case op.Name == "sizeof ":
  2987  				wantParens = true
  2988  			case op.Name == "typeid ":
  2989  				wantParens = true
  2990  			default:
  2991  				wantParens = true
  2992  				if p, ok := expr.(hasPrec); ok {
  2993  					if p.prec() < op.precedence {
  2994  						wantParens = false
  2995  					}
  2996  				}
  2997  			}
  2998  			if wantParens {
  2999  				ps.startScope('(')
  3000  			}
  3001  			ps.print(expr)
  3002  			if wantParens {
  3003  				ps.endScope(')')
  3004  			}
  3005  		} else {
  3006  			parenthesize(ps, expr)
  3007  		}
  3008  	}
  3009  }
  3010  
  3011  func (u *Unary) Traverse(fn func(AST) bool) {
  3012  	if fn(u) {
  3013  		u.Op.Traverse(fn)
  3014  		u.Expr.Traverse(fn)
  3015  	}
  3016  }
  3017  
  3018  func (u *Unary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3019  	if skip(u) {
  3020  		return nil
  3021  	}
  3022  	op := u.Op.Copy(fn, skip)
  3023  	expr := u.Expr.Copy(fn, skip)
  3024  	if op == nil && expr == nil {
  3025  		return fn(u)
  3026  	}
  3027  	if op == nil {
  3028  		op = u.Op
  3029  	}
  3030  	if expr == nil {
  3031  		expr = u.Expr
  3032  	}
  3033  	u = &Unary{Op: op, Expr: expr, Suffix: u.Suffix, SizeofType: u.SizeofType}
  3034  	if r := fn(u); r != nil {
  3035  		return r
  3036  	}
  3037  	return u
  3038  }
  3039  
  3040  func (u *Unary) GoString() string {
  3041  	return u.goString(0, "")
  3042  }
  3043  
  3044  func (u *Unary) goString(indent int, field string) string {
  3045  	var s string
  3046  	if u.Suffix {
  3047  		s = " Suffix: true"
  3048  	}
  3049  	if u.SizeofType {
  3050  		s += " SizeofType: true"
  3051  	}
  3052  	return fmt.Sprintf("%*s%sUnary:%s\n%s\n%s", indent, "", field,
  3053  		s, u.Op.goString(indent+2, "Op: "),
  3054  		u.Expr.goString(indent+2, "Expr: "))
  3055  }
  3056  
  3057  func (u *Unary) prec() precedence {
  3058  	if p, ok := u.Op.(hasPrec); ok {
  3059  		return p.prec()
  3060  	}
  3061  	return precDefault
  3062  }
  3063  
  3064  // isDesignatedInitializer reports whether x is a designated
  3065  // initializer.
  3066  func isDesignatedInitializer(x AST) bool {
  3067  	switch x := x.(type) {
  3068  	case *Binary:
  3069  		if op, ok := x.Op.(*Operator); ok {
  3070  			if op.Name == "]=" {
  3071  				return true
  3072  			}
  3073  			if op.Name != "=" {
  3074  				return false
  3075  			}
  3076  			if _, ok := x.Left.(*Literal); ok {
  3077  				return false
  3078  			}
  3079  			return true
  3080  		}
  3081  	case *Trinary:
  3082  		if op, ok := x.Op.(*Operator); ok {
  3083  			return op.Name == "[...]="
  3084  		}
  3085  	}
  3086  	return false
  3087  }
  3088  
  3089  // Binary is a binary operation in an expression.
  3090  type Binary struct {
  3091  	Op    AST
  3092  	Left  AST
  3093  	Right AST
  3094  }
  3095  
  3096  func (b *Binary) print(ps *printState) {
  3097  	op, _ := b.Op.(*Operator)
  3098  
  3099  	if op != nil && strings.Contains(op.Name, "cast") {
  3100  		ps.writeString(op.Name)
  3101  
  3102  		scopes := ps.scopes
  3103  		ps.scopes = 0
  3104  
  3105  		ps.writeByte('<')
  3106  		ps.print(b.Left)
  3107  		ps.writeString(">")
  3108  
  3109  		ps.scopes = scopes
  3110  
  3111  		ps.startScope('(')
  3112  		ps.print(b.Right)
  3113  		ps.endScope(')')
  3114  		return
  3115  	}
  3116  
  3117  	if isDesignatedInitializer(b) {
  3118  		if op.Name == "=" {
  3119  			ps.writeByte('.')
  3120  		} else {
  3121  			ps.writeByte('[')
  3122  		}
  3123  		ps.print(b.Left)
  3124  		if op.Name == "]=" {
  3125  			ps.writeByte(']')
  3126  		}
  3127  		if isDesignatedInitializer(b.Right) {
  3128  			// Don't add anything between designated
  3129  			// initializer chains.
  3130  			ps.print(b.Right)
  3131  		} else {
  3132  			if ps.llvmStyle {
  3133  				ps.writeString(" = ")
  3134  				ps.print(b.Right)
  3135  			} else {
  3136  				ps.writeByte('=')
  3137  				parenthesize(ps, b.Right)
  3138  			}
  3139  		}
  3140  		return
  3141  	}
  3142  
  3143  	// Use an extra set of parentheses around an expression that
  3144  	// uses the greater-than operator, so that it does not get
  3145  	// confused with the '>' that ends template parameters.
  3146  	needsOuterParen := op != nil && (op.Name == ">" || op.Name == ">>")
  3147  	if ps.llvmStyle && ps.scopes > 0 {
  3148  		needsOuterParen = false
  3149  	}
  3150  	if needsOuterParen {
  3151  		ps.startScope('(')
  3152  	}
  3153  
  3154  	left := b.Left
  3155  
  3156  	skipParens := false
  3157  	addSpaces := ps.llvmStyle
  3158  	if ps.llvmStyle && op != nil {
  3159  		switch op.Name {
  3160  		case ".", "->", "->*":
  3161  			addSpaces = false
  3162  		}
  3163  	}
  3164  
  3165  	// For a function call in an expression, don't print the types
  3166  	// of the arguments unless there is a return type.
  3167  	if op != nil && op.Name == "()" {
  3168  		if ty, ok := b.Left.(*Typed); ok {
  3169  			if ft, ok := ty.Type.(*FunctionType); ok {
  3170  				if ft.Return == nil {
  3171  					left = ty.Name
  3172  				} else {
  3173  					skipParens = true
  3174  				}
  3175  			} else {
  3176  				left = ty.Name
  3177  			}
  3178  		}
  3179  		if ps.llvmStyle {
  3180  			skipParens = true
  3181  		}
  3182  	}
  3183  
  3184  	if skipParens {
  3185  		ps.print(left)
  3186  	} else if ps.llvmStyle {
  3187  		prec := precPrimary
  3188  		if p, ok := left.(hasPrec); ok {
  3189  			prec = p.prec()
  3190  		}
  3191  		needsParen := false
  3192  		if prec > b.prec() {
  3193  			needsParen = true
  3194  		}
  3195  		if needsParen {
  3196  			ps.startScope('(')
  3197  		}
  3198  
  3199  		ps.print(left)
  3200  
  3201  		if needsParen {
  3202  			ps.endScope(')')
  3203  		}
  3204  	} else {
  3205  		parenthesize(ps, left)
  3206  	}
  3207  
  3208  	if op != nil && op.Name == "[]" {
  3209  		ps.writeByte('[')
  3210  		ps.print(b.Right)
  3211  		ps.writeByte(']')
  3212  		return
  3213  	}
  3214  
  3215  	if op != nil {
  3216  		if op.Name != "()" {
  3217  			if addSpaces && op.Name != "," {
  3218  				ps.writeByte(' ')
  3219  			}
  3220  			ps.writeString(op.Name)
  3221  			if addSpaces {
  3222  				ps.writeByte(' ')
  3223  			}
  3224  		}
  3225  	} else {
  3226  		ps.print(b.Op)
  3227  	}
  3228  
  3229  	if ps.llvmStyle {
  3230  		prec := precPrimary
  3231  		if p, ok := b.Right.(hasPrec); ok {
  3232  			prec = p.prec()
  3233  		}
  3234  		needsParen := false
  3235  		if prec >= b.prec() {
  3236  			needsParen = true
  3237  		}
  3238  		if needsParen {
  3239  			ps.startScope('(')
  3240  		}
  3241  
  3242  		ps.print(b.Right)
  3243  
  3244  		if needsParen {
  3245  			ps.endScope(')')
  3246  		}
  3247  	} else {
  3248  		parenthesize(ps, b.Right)
  3249  	}
  3250  
  3251  	if needsOuterParen {
  3252  		ps.endScope(')')
  3253  	}
  3254  }
  3255  
  3256  func (b *Binary) Traverse(fn func(AST) bool) {
  3257  	if fn(b) {
  3258  		b.Op.Traverse(fn)
  3259  		b.Left.Traverse(fn)
  3260  		b.Right.Traverse(fn)
  3261  	}
  3262  }
  3263  
  3264  func (b *Binary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3265  	if skip(b) {
  3266  		return nil
  3267  	}
  3268  	op := b.Op.Copy(fn, skip)
  3269  	left := b.Left.Copy(fn, skip)
  3270  	right := b.Right.Copy(fn, skip)
  3271  	if op == nil && left == nil && right == nil {
  3272  		return fn(b)
  3273  	}
  3274  	if op == nil {
  3275  		op = b.Op
  3276  	}
  3277  	if left == nil {
  3278  		left = b.Left
  3279  	}
  3280  	if right == nil {
  3281  		right = b.Right
  3282  	}
  3283  	b = &Binary{Op: op, Left: left, Right: right}
  3284  	if r := fn(b); r != nil {
  3285  		return r
  3286  	}
  3287  	return b
  3288  }
  3289  
  3290  func (b *Binary) GoString() string {
  3291  	return b.goString(0, "")
  3292  }
  3293  
  3294  func (b *Binary) goString(indent int, field string) string {
  3295  	return fmt.Sprintf("%*s%sBinary:\n%s\n%s\n%s", indent, "", field,
  3296  		b.Op.goString(indent+2, "Op: "),
  3297  		b.Left.goString(indent+2, "Left: "),
  3298  		b.Right.goString(indent+2, "Right: "))
  3299  }
  3300  
  3301  func (b *Binary) prec() precedence {
  3302  	if p, ok := b.Op.(hasPrec); ok {
  3303  		return p.prec()
  3304  	}
  3305  	return precDefault
  3306  }
  3307  
  3308  // Trinary is the ?: trinary operation in an expression.
  3309  type Trinary struct {
  3310  	Op     AST
  3311  	First  AST
  3312  	Second AST
  3313  	Third  AST
  3314  }
  3315  
  3316  func (t *Trinary) print(ps *printState) {
  3317  	if isDesignatedInitializer(t) {
  3318  		ps.writeByte('[')
  3319  		ps.print(t.First)
  3320  		ps.writeString(" ... ")
  3321  		ps.print(t.Second)
  3322  		ps.writeByte(']')
  3323  		if isDesignatedInitializer(t.Third) {
  3324  			// Don't add anything between designated
  3325  			// initializer chains.
  3326  			ps.print(t.Third)
  3327  		} else {
  3328  			if ps.llvmStyle {
  3329  				ps.writeString(" = ")
  3330  				ps.print(t.Third)
  3331  			} else {
  3332  				ps.writeByte('=')
  3333  				parenthesize(ps, t.Third)
  3334  			}
  3335  		}
  3336  		return
  3337  	}
  3338  
  3339  	if ps.llvmStyle {
  3340  		wantParens := true
  3341  		opPrec := precPrimary
  3342  		if op, ok := t.Op.(*Operator); ok {
  3343  			opPrec = op.precedence
  3344  		}
  3345  		if p, ok := t.First.(hasPrec); ok {
  3346  			if p.prec() < opPrec {
  3347  				wantParens = false
  3348  			}
  3349  		}
  3350  		if wantParens {
  3351  			ps.startScope('(')
  3352  		}
  3353  		ps.print(t.First)
  3354  		if wantParens {
  3355  			ps.endScope(')')
  3356  		}
  3357  	} else {
  3358  		parenthesize(ps, t.First)
  3359  	}
  3360  
  3361  	if ps.llvmStyle {
  3362  		ps.writeString(" ? ")
  3363  	} else {
  3364  		ps.writeByte('?')
  3365  	}
  3366  
  3367  	if ps.llvmStyle {
  3368  		wantParens := true
  3369  		if p, ok := t.Second.(hasPrec); ok {
  3370  			if p.prec() < precDefault {
  3371  				wantParens = false
  3372  			}
  3373  		}
  3374  		if wantParens {
  3375  			ps.startScope('(')
  3376  		}
  3377  		ps.print(t.Second)
  3378  		if wantParens {
  3379  			ps.endScope(')')
  3380  		}
  3381  	} else {
  3382  		parenthesize(ps, t.Second)
  3383  	}
  3384  
  3385  	ps.writeString(" : ")
  3386  
  3387  	if ps.llvmStyle {
  3388  		wantParens := true
  3389  		if p, ok := t.Third.(hasPrec); ok {
  3390  			if p.prec() < precAssign {
  3391  				wantParens = false
  3392  			}
  3393  		}
  3394  		if wantParens {
  3395  			ps.startScope('(')
  3396  		}
  3397  		ps.print(t.Third)
  3398  		if wantParens {
  3399  			ps.endScope(')')
  3400  		}
  3401  	} else {
  3402  		parenthesize(ps, t.Third)
  3403  	}
  3404  }
  3405  
  3406  func (t *Trinary) Traverse(fn func(AST) bool) {
  3407  	if fn(t) {
  3408  		t.Op.Traverse(fn)
  3409  		t.First.Traverse(fn)
  3410  		t.Second.Traverse(fn)
  3411  		t.Third.Traverse(fn)
  3412  	}
  3413  }
  3414  
  3415  func (t *Trinary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3416  	if skip(t) {
  3417  		return nil
  3418  	}
  3419  	op := t.Op.Copy(fn, skip)
  3420  	first := t.First.Copy(fn, skip)
  3421  	second := t.Second.Copy(fn, skip)
  3422  	third := t.Third.Copy(fn, skip)
  3423  	if op == nil && first == nil && second == nil && third == nil {
  3424  		return fn(t)
  3425  	}
  3426  	if op == nil {
  3427  		op = t.Op
  3428  	}
  3429  	if first == nil {
  3430  		first = t.First
  3431  	}
  3432  	if second == nil {
  3433  		second = t.Second
  3434  	}
  3435  	if third == nil {
  3436  		third = t.Third
  3437  	}
  3438  	t = &Trinary{Op: op, First: first, Second: second, Third: third}
  3439  	if r := fn(t); r != nil {
  3440  		return r
  3441  	}
  3442  	return t
  3443  }
  3444  
  3445  func (t *Trinary) GoString() string {
  3446  	return t.goString(0, "")
  3447  }
  3448  
  3449  func (t *Trinary) goString(indent int, field string) string {
  3450  	return fmt.Sprintf("%*s%sTrinary:\n%s\n%s\n%s\n%s", indent, "", field,
  3451  		t.Op.goString(indent+2, "Op: "),
  3452  		t.First.goString(indent+2, "First: "),
  3453  		t.Second.goString(indent+2, "Second: "),
  3454  		t.Third.goString(indent+2, "Third: "))
  3455  }
  3456  
  3457  // Fold is a C++17 fold-expression.  Arg2 is nil for a unary operator.
  3458  type Fold struct {
  3459  	Left bool
  3460  	Op   AST
  3461  	Arg1 AST
  3462  	Arg2 AST
  3463  }
  3464  
  3465  func (f *Fold) print(ps *printState) {
  3466  	op, _ := f.Op.(*Operator)
  3467  	printOp := func() {
  3468  		if op != nil {
  3469  			if ps.llvmStyle {
  3470  				ps.writeByte(' ')
  3471  			}
  3472  			ps.writeString(op.Name)
  3473  			if ps.llvmStyle {
  3474  				ps.writeByte(' ')
  3475  			}
  3476  		} else {
  3477  			ps.print(f.Op)
  3478  		}
  3479  	}
  3480  	foldParenthesize := func(a AST) {
  3481  		if ps.llvmStyle {
  3482  			prec := precDefault
  3483  			if p, ok := a.(hasPrec); ok {
  3484  				prec = p.prec()
  3485  			}
  3486  			needsParen := false
  3487  			if prec > precCast {
  3488  				needsParen = true
  3489  			}
  3490  			if needsParen {
  3491  				ps.startScope('(')
  3492  			}
  3493  			ps.print(a)
  3494  			if needsParen {
  3495  				ps.endScope(')')
  3496  			}
  3497  		} else {
  3498  			parenthesize(ps, a)
  3499  		}
  3500  	}
  3501  
  3502  	if f.Arg2 == nil {
  3503  		if f.Left {
  3504  			ps.startScope('(')
  3505  			ps.writeString("...")
  3506  			printOp()
  3507  			foldParenthesize(f.Arg1)
  3508  			ps.endScope(')')
  3509  		} else {
  3510  			ps.startScope('(')
  3511  			foldParenthesize(f.Arg1)
  3512  			printOp()
  3513  			ps.writeString("...")
  3514  			ps.endScope(')')
  3515  		}
  3516  	} else {
  3517  		ps.startScope('(')
  3518  		foldParenthesize(f.Arg1)
  3519  		printOp()
  3520  		ps.writeString("...")
  3521  		printOp()
  3522  		foldParenthesize(f.Arg2)
  3523  		ps.endScope(')')
  3524  	}
  3525  }
  3526  
  3527  func (f *Fold) Traverse(fn func(AST) bool) {
  3528  	if fn(f) {
  3529  		f.Op.Traverse(fn)
  3530  		f.Arg1.Traverse(fn)
  3531  		if f.Arg2 != nil {
  3532  			f.Arg2.Traverse(fn)
  3533  		}
  3534  	}
  3535  }
  3536  
  3537  func (f *Fold) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3538  	if skip(f) {
  3539  		return nil
  3540  	}
  3541  	op := f.Op.Copy(fn, skip)
  3542  	arg1 := f.Arg1.Copy(fn, skip)
  3543  	var arg2 AST
  3544  	if f.Arg2 != nil {
  3545  		arg2 = f.Arg2.Copy(fn, skip)
  3546  	}
  3547  	if op == nil && arg1 == nil && arg2 == nil {
  3548  		return fn(f)
  3549  	}
  3550  	if op == nil {
  3551  		op = f.Op
  3552  	}
  3553  	if arg1 == nil {
  3554  		arg1 = f.Arg1
  3555  	}
  3556  	if arg2 == nil {
  3557  		arg2 = f.Arg2
  3558  	}
  3559  	f = &Fold{Left: f.Left, Op: op, Arg1: arg1, Arg2: arg2}
  3560  	if r := fn(f); r != nil {
  3561  		return r
  3562  	}
  3563  	return f
  3564  }
  3565  
  3566  func (f *Fold) GoString() string {
  3567  	return f.goString(0, "")
  3568  }
  3569  
  3570  func (f *Fold) goString(indent int, field string) string {
  3571  	if f.Arg2 == nil {
  3572  		return fmt.Sprintf("%*s%sFold: Left: %t\n%s\n%s", indent, "", field,
  3573  			f.Left, f.Op.goString(indent+2, "Op: "),
  3574  			f.Arg1.goString(indent+2, "Arg1: "))
  3575  	} else {
  3576  		return fmt.Sprintf("%*s%sFold: Left: %t\n%s\n%s\n%s", indent, "", field,
  3577  			f.Left, f.Op.goString(indent+2, "Op: "),
  3578  			f.Arg1.goString(indent+2, "Arg1: "),
  3579  			f.Arg2.goString(indent+2, "Arg2: "))
  3580  	}
  3581  }
  3582  
  3583  // Subobject is a a reference to an offset in an expression.  This is
  3584  // used for C++20 manglings of class types used as the type of
  3585  // non-type template arguments.
  3586  //
  3587  // See https://github.com/itanium-cxx-abi/cxx-abi/issues/47.
  3588  type Subobject struct {
  3589  	Type      AST
  3590  	SubExpr   AST
  3591  	Offset    int
  3592  	Selectors []int
  3593  	PastEnd   bool
  3594  }
  3595  
  3596  func (so *Subobject) print(ps *printState) {
  3597  	ps.print(so.SubExpr)
  3598  	ps.writeString(".<")
  3599  	ps.print(so.Type)
  3600  	ps.writeString(fmt.Sprintf(" at offset %d>", so.Offset))
  3601  }
  3602  
  3603  func (so *Subobject) Traverse(fn func(AST) bool) {
  3604  	if fn(so) {
  3605  		so.Type.Traverse(fn)
  3606  		so.SubExpr.Traverse(fn)
  3607  	}
  3608  }
  3609  
  3610  func (so *Subobject) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3611  	if skip(so) {
  3612  		return nil
  3613  	}
  3614  	typ := so.Type.Copy(fn, skip)
  3615  	subExpr := so.SubExpr.Copy(fn, skip)
  3616  	if typ == nil && subExpr == nil {
  3617  		return nil
  3618  	}
  3619  	if typ == nil {
  3620  		typ = so.Type
  3621  	}
  3622  	if subExpr == nil {
  3623  		subExpr = so.SubExpr
  3624  	}
  3625  	so = &Subobject{
  3626  		Type:      typ,
  3627  		SubExpr:   subExpr,
  3628  		Offset:    so.Offset,
  3629  		Selectors: so.Selectors,
  3630  		PastEnd:   so.PastEnd,
  3631  	}
  3632  	if r := fn(so); r != nil {
  3633  		return r
  3634  	}
  3635  	return so
  3636  }
  3637  
  3638  func (so *Subobject) GoString() string {
  3639  	return so.goString(0, "")
  3640  }
  3641  
  3642  func (so *Subobject) goString(indent int, field string) string {
  3643  	var selectors string
  3644  	for _, s := range so.Selectors {
  3645  		selectors += fmt.Sprintf(" %d", s)
  3646  	}
  3647  	return fmt.Sprintf("%*s%sSubobject:\n%s\n%s\n%*sOffset: %d\n%*sSelectors:%s\n%*sPastEnd: %t",
  3648  		indent, "", field,
  3649  		so.Type.goString(indent+2, "Type: "),
  3650  		so.SubExpr.goString(indent+2, "SubExpr: "),
  3651  		indent+2, "", so.Offset,
  3652  		indent+2, "", selectors,
  3653  		indent+2, "", so.PastEnd)
  3654  }
  3655  
  3656  // PtrMemCast is a conversion of an expression to a pointer-to-member
  3657  // type.  This is used for C++20 manglings of class types used as the
  3658  // type of non-type template arguments.
  3659  //
  3660  // See https://github.com/itanium-cxx-abi/cxx-abi/issues/47.
  3661  type PtrMemCast struct {
  3662  	Type   AST
  3663  	Expr   AST
  3664  	Offset int
  3665  }
  3666  
  3667  func (pmc *PtrMemCast) print(ps *printState) {
  3668  	ps.startScope('(')
  3669  	ps.print(pmc.Type)
  3670  	ps.writeString(")(")
  3671  	ps.print(pmc.Expr)
  3672  	ps.endScope(')')
  3673  }
  3674  
  3675  func (pmc *PtrMemCast) Traverse(fn func(AST) bool) {
  3676  	if fn(pmc) {
  3677  		pmc.Type.Traverse(fn)
  3678  		pmc.Expr.Traverse(fn)
  3679  	}
  3680  }
  3681  
  3682  func (pmc *PtrMemCast) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3683  	if skip(pmc) {
  3684  		return nil
  3685  	}
  3686  	typ := pmc.Type.Copy(fn, skip)
  3687  	expr := pmc.Expr.Copy(fn, skip)
  3688  	if typ == nil && expr == nil {
  3689  		return nil
  3690  	}
  3691  	if typ == nil {
  3692  		typ = pmc.Type
  3693  	}
  3694  	if expr == nil {
  3695  		expr = pmc.Expr
  3696  	}
  3697  	pmc = &PtrMemCast{
  3698  		Type:   typ,
  3699  		Expr:   expr,
  3700  		Offset: pmc.Offset,
  3701  	}
  3702  	if r := fn(pmc); r != nil {
  3703  		return r
  3704  	}
  3705  	return pmc
  3706  }
  3707  
  3708  func (pmc *PtrMemCast) GoString() string {
  3709  	return pmc.goString(0, "")
  3710  }
  3711  
  3712  func (pmc *PtrMemCast) goString(indent int, field string) string {
  3713  	return fmt.Sprintf("%*s%sPtrMemCast:\n%s\n%s\n%*sOffset: %d",
  3714  		indent, "", field,
  3715  		pmc.Type.goString(indent+2, "Type: "),
  3716  		pmc.Expr.goString(indent+2, "Expr: "),
  3717  		indent+2, "", pmc.Offset)
  3718  }
  3719  
  3720  // New is a use of operator new in an expression.
  3721  type New struct {
  3722  	Op    AST
  3723  	Place AST
  3724  	Type  AST
  3725  	Init  AST
  3726  }
  3727  
  3728  func (n *New) print(ps *printState) {
  3729  	if !ps.llvmStyle {
  3730  		// Op doesn't really matter for printing--we always print "new".
  3731  		ps.writeString("new ")
  3732  	} else {
  3733  		op, _ := n.Op.(*Operator)
  3734  		if op != nil {
  3735  			ps.writeString(op.Name)
  3736  			if n.Place == nil {
  3737  				ps.writeByte(' ')
  3738  			}
  3739  		} else {
  3740  			ps.print(n.Op)
  3741  		}
  3742  	}
  3743  	if n.Place != nil {
  3744  		parenthesize(ps, n.Place)
  3745  		ps.writeByte(' ')
  3746  	}
  3747  	ps.print(n.Type)
  3748  	if n.Init != nil {
  3749  		parenthesize(ps, n.Init)
  3750  	}
  3751  }
  3752  
  3753  func (n *New) Traverse(fn func(AST) bool) {
  3754  	if fn(n) {
  3755  		n.Op.Traverse(fn)
  3756  		if n.Place != nil {
  3757  			n.Place.Traverse(fn)
  3758  		}
  3759  		n.Type.Traverse(fn)
  3760  		if n.Init != nil {
  3761  			n.Init.Traverse(fn)
  3762  		}
  3763  	}
  3764  }
  3765  
  3766  func (n *New) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3767  	if skip(n) {
  3768  		return nil
  3769  	}
  3770  	op := n.Op.Copy(fn, skip)
  3771  	var place AST
  3772  	if n.Place != nil {
  3773  		place = n.Place.Copy(fn, skip)
  3774  	}
  3775  	typ := n.Type.Copy(fn, skip)
  3776  	var ini AST
  3777  	if n.Init != nil {
  3778  		ini = n.Init.Copy(fn, skip)
  3779  	}
  3780  	if op == nil && place == nil && typ == nil && ini == nil {
  3781  		return fn(n)
  3782  	}
  3783  	if op == nil {
  3784  		op = n.Op
  3785  	}
  3786  	if place == nil {
  3787  		place = n.Place
  3788  	}
  3789  	if typ == nil {
  3790  		typ = n.Type
  3791  	}
  3792  	if ini == nil {
  3793  		ini = n.Init
  3794  	}
  3795  	n = &New{Op: op, Place: place, Type: typ, Init: ini}
  3796  	if r := fn(n); r != nil {
  3797  		return r
  3798  	}
  3799  	return n
  3800  }
  3801  
  3802  func (n *New) GoString() string {
  3803  	return n.goString(0, "")
  3804  }
  3805  
  3806  func (n *New) goString(indent int, field string) string {
  3807  	var place string
  3808  	if n.Place == nil {
  3809  		place = fmt.Sprintf("%*sPlace: nil", indent, "")
  3810  	} else {
  3811  		place = n.Place.goString(indent+2, "Place: ")
  3812  	}
  3813  	var ini string
  3814  	if n.Init == nil {
  3815  		ini = fmt.Sprintf("%*sInit: nil", indent, "")
  3816  	} else {
  3817  		ini = n.Init.goString(indent+2, "Init: ")
  3818  	}
  3819  	return fmt.Sprintf("%*s%sNew:\n%s\n%s\n%s\n%s", indent, "", field,
  3820  		n.Op.goString(indent+2, "Op: "), place,
  3821  		n.Type.goString(indent+2, "Type: "), ini)
  3822  }
  3823  
  3824  // Literal is a literal in an expression.
  3825  type Literal struct {
  3826  	Type AST
  3827  	Val  string
  3828  	Neg  bool
  3829  }
  3830  
  3831  // Suffixes to use for constants of the given integer type.
  3832  var builtinTypeSuffix = map[string]string{
  3833  	"int":                "",
  3834  	"unsigned int":       "u",
  3835  	"long":               "l",
  3836  	"unsigned long":      "ul",
  3837  	"long long":          "ll",
  3838  	"unsigned long long": "ull",
  3839  }
  3840  
  3841  // Builtin float types.
  3842  var builtinTypeFloat = map[string]bool{
  3843  	"double":      true,
  3844  	"long double": true,
  3845  	"float":       true,
  3846  	"__float128":  true,
  3847  	"half":        true,
  3848  }
  3849  
  3850  func (l *Literal) print(ps *printState) {
  3851  	isFloat := false
  3852  	if b, ok := l.Type.(*BuiltinType); ok {
  3853  		if suffix, ok := builtinTypeSuffix[b.Name]; ok {
  3854  			if l.Neg {
  3855  				ps.writeByte('-')
  3856  			}
  3857  			ps.writeString(l.Val)
  3858  			ps.writeString(suffix)
  3859  			return
  3860  		} else if b.Name == "bool" && !l.Neg {
  3861  			switch l.Val {
  3862  			case "0":
  3863  				ps.writeString("false")
  3864  				return
  3865  			case "1":
  3866  				ps.writeString("true")
  3867  				return
  3868  			}
  3869  		} else if b.Name == "decltype(nullptr)" && (l.Val == "" || l.Val == "0") {
  3870  			if ps.llvmStyle {
  3871  				ps.writeString("nullptr")
  3872  			} else {
  3873  				ps.print(l.Type)
  3874  			}
  3875  			return
  3876  		} else {
  3877  			isFloat = builtinTypeFloat[b.Name]
  3878  		}
  3879  	}
  3880  
  3881  	ps.startScope('(')
  3882  	ps.print(l.Type)
  3883  	ps.endScope(')')
  3884  
  3885  	if isFloat {
  3886  		ps.writeByte('[')
  3887  	}
  3888  	if l.Neg {
  3889  		ps.writeByte('-')
  3890  	}
  3891  	ps.writeString(l.Val)
  3892  	if isFloat {
  3893  		ps.writeByte(']')
  3894  	}
  3895  }
  3896  
  3897  func (l *Literal) Traverse(fn func(AST) bool) {
  3898  	if fn(l) {
  3899  		l.Type.Traverse(fn)
  3900  	}
  3901  }
  3902  
  3903  func (l *Literal) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3904  	if skip(l) {
  3905  		return nil
  3906  	}
  3907  	typ := l.Type.Copy(fn, skip)
  3908  	if typ == nil {
  3909  		return fn(l)
  3910  	}
  3911  	l = &Literal{Type: typ, Val: l.Val, Neg: l.Neg}
  3912  	if r := fn(l); r != nil {
  3913  		return r
  3914  	}
  3915  	return l
  3916  }
  3917  
  3918  func (l *Literal) GoString() string {
  3919  	return l.goString(0, "")
  3920  }
  3921  
  3922  func (l *Literal) goString(indent int, field string) string {
  3923  	var neg string
  3924  	if l.Neg {
  3925  		neg = " Neg: true"
  3926  	}
  3927  	return fmt.Sprintf("%*s%sLiteral:%s\n%s\n%*sVal: %s", indent, "", field,
  3928  		neg, l.Type.goString(indent+2, "Type: "),
  3929  		indent+2, "", l.Val)
  3930  }
  3931  
  3932  func (l *Literal) prec() precedence {
  3933  	return precPrimary
  3934  }
  3935  
  3936  // StringLiteral is a string literal.
  3937  type StringLiteral struct {
  3938  	Type AST
  3939  }
  3940  
  3941  func (sl *StringLiteral) print(ps *printState) {
  3942  	ps.writeString(`"<`)
  3943  	sl.Type.print(ps)
  3944  	ps.writeString(`>"`)
  3945  }
  3946  
  3947  func (sl *StringLiteral) Traverse(fn func(AST) bool) {
  3948  	if fn(sl) {
  3949  		sl.Type.Traverse(fn)
  3950  	}
  3951  }
  3952  
  3953  func (sl *StringLiteral) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3954  	if skip(sl) {
  3955  		return nil
  3956  	}
  3957  	typ := sl.Type.Copy(fn, skip)
  3958  	if typ == nil {
  3959  		return fn(sl)
  3960  	}
  3961  	sl = &StringLiteral{Type: typ}
  3962  	if r := fn(sl); r != nil {
  3963  		return r
  3964  	}
  3965  	return sl
  3966  }
  3967  
  3968  func (sl *StringLiteral) GoString() string {
  3969  	return sl.goString(0, "")
  3970  }
  3971  
  3972  func (sl *StringLiteral) goString(indent int, field string) string {
  3973  	return fmt.Sprintf("%*s%sStringLiteral:\n%s", indent, "", field,
  3974  		sl.Type.goString(indent+2, ""))
  3975  }
  3976  
  3977  // LambdaExpr is a literal that is a lambda expression.
  3978  type LambdaExpr struct {
  3979  	Type AST
  3980  }
  3981  
  3982  func (le *LambdaExpr) print(ps *printState) {
  3983  	ps.writeString("[]")
  3984  	if cl, ok := le.Type.(*Closure); ok {
  3985  		cl.printTypes(ps)
  3986  	}
  3987  	ps.writeString("{...}")
  3988  }
  3989  
  3990  func (le *LambdaExpr) Traverse(fn func(AST) bool) {
  3991  	if fn(le) {
  3992  		le.Type.Traverse(fn)
  3993  	}
  3994  }
  3995  
  3996  func (le *LambdaExpr) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3997  	if skip(le) {
  3998  		return nil
  3999  	}
  4000  	typ := le.Type.Copy(fn, skip)
  4001  	if typ == nil {
  4002  		return fn(le)
  4003  	}
  4004  	le = &LambdaExpr{Type: typ}
  4005  	if r := fn(le); r != nil {
  4006  		return r
  4007  	}
  4008  	return le
  4009  }
  4010  
  4011  func (le *LambdaExpr) GoString() string {
  4012  	return le.goString(0, "")
  4013  }
  4014  
  4015  func (le *LambdaExpr) goString(indent int, field string) string {
  4016  	return fmt.Sprintf("%*s%sLambdaExpr:\n%s", indent, "", field,
  4017  		le.Type.goString(indent+2, ""))
  4018  }
  4019  
  4020  // ExprList is a list of expressions, typically arguments to a
  4021  // function call in an expression.
  4022  type ExprList struct {
  4023  	Exprs []AST
  4024  }
  4025  
  4026  func (el *ExprList) print(ps *printState) {
  4027  	ps.printList(el.Exprs, nil)
  4028  }
  4029  
  4030  func (el *ExprList) Traverse(fn func(AST) bool) {
  4031  	if fn(el) {
  4032  		for _, e := range el.Exprs {
  4033  			e.Traverse(fn)
  4034  		}
  4035  	}
  4036  }
  4037  
  4038  func (el *ExprList) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4039  	if skip(el) {
  4040  		return nil
  4041  	}
  4042  	exprs := make([]AST, len(el.Exprs))
  4043  	changed := false
  4044  	for i, e := range el.Exprs {
  4045  		ec := e.Copy(fn, skip)
  4046  		if ec == nil {
  4047  			exprs[i] = e
  4048  		} else {
  4049  			exprs[i] = ec
  4050  			changed = true
  4051  		}
  4052  	}
  4053  	if !changed {
  4054  		return fn(el)
  4055  	}
  4056  	el = &ExprList{Exprs: exprs}
  4057  	if r := fn(el); r != nil {
  4058  		return r
  4059  	}
  4060  	return el
  4061  }
  4062  
  4063  func (el *ExprList) GoString() string {
  4064  	return el.goString(0, "")
  4065  }
  4066  
  4067  func (el *ExprList) goString(indent int, field string) string {
  4068  	if len(el.Exprs) == 0 {
  4069  		return fmt.Sprintf("%*s%sExprList: nil", indent, "", field)
  4070  	}
  4071  	s := fmt.Sprintf("%*s%sExprList:", indent, "", field)
  4072  	for i, e := range el.Exprs {
  4073  		s += "\n"
  4074  		s += e.goString(indent+2, fmt.Sprintf("%d: ", i))
  4075  	}
  4076  	return s
  4077  }
  4078  
  4079  func (el *ExprList) prec() precedence {
  4080  	return precComma
  4081  }
  4082  
  4083  // InitializerList is an initializer list: an optional type with a
  4084  // list of expressions.
  4085  type InitializerList struct {
  4086  	Type  AST
  4087  	Exprs AST
  4088  }
  4089  
  4090  func (il *InitializerList) print(ps *printState) {
  4091  	if il.Type != nil {
  4092  		ps.print(il.Type)
  4093  	}
  4094  	ps.writeByte('{')
  4095  	ps.print(il.Exprs)
  4096  	ps.writeByte('}')
  4097  }
  4098  
  4099  func (il *InitializerList) Traverse(fn func(AST) bool) {
  4100  	if fn(il) {
  4101  		if il.Type != nil {
  4102  			il.Type.Traverse(fn)
  4103  		}
  4104  		il.Exprs.Traverse(fn)
  4105  	}
  4106  }
  4107  
  4108  func (il *InitializerList) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4109  	if skip(il) {
  4110  		return nil
  4111  	}
  4112  	var typ AST
  4113  	if il.Type != nil {
  4114  		typ = il.Type.Copy(fn, skip)
  4115  	}
  4116  	exprs := il.Exprs.Copy(fn, skip)
  4117  	if typ == nil && exprs == nil {
  4118  		return fn(il)
  4119  	}
  4120  	if typ == nil {
  4121  		typ = il.Type
  4122  	}
  4123  	if exprs == nil {
  4124  		exprs = il.Exprs
  4125  	}
  4126  	il = &InitializerList{Type: typ, Exprs: exprs}
  4127  	if r := fn(il); r != nil {
  4128  		return r
  4129  	}
  4130  	return il
  4131  }
  4132  
  4133  func (il *InitializerList) GoString() string {
  4134  	return il.goString(0, "")
  4135  }
  4136  
  4137  func (il *InitializerList) goString(indent int, field string) string {
  4138  	var t string
  4139  	if il.Type == nil {
  4140  		t = fmt.Sprintf("%*sType: nil", indent+2, "")
  4141  	} else {
  4142  		t = il.Type.goString(indent+2, "Type: ")
  4143  	}
  4144  	return fmt.Sprintf("%*s%sInitializerList:\n%s\n%s", indent, "", field,
  4145  		t, il.Exprs.goString(indent+2, "Exprs: "))
  4146  }
  4147  
  4148  // DefaultArg holds a default argument for a local name.
  4149  type DefaultArg struct {
  4150  	Num int
  4151  	Arg AST
  4152  }
  4153  
  4154  func (da *DefaultArg) print(ps *printState) {
  4155  	if !ps.llvmStyle {
  4156  		fmt.Fprintf(&ps.buf, "{default arg#%d}::", da.Num+1)
  4157  	}
  4158  	ps.print(da.Arg)
  4159  }
  4160  
  4161  func (da *DefaultArg) Traverse(fn func(AST) bool) {
  4162  	if fn(da) {
  4163  		da.Arg.Traverse(fn)
  4164  	}
  4165  }
  4166  
  4167  func (da *DefaultArg) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4168  	if skip(da) {
  4169  		return nil
  4170  	}
  4171  	arg := da.Arg.Copy(fn, skip)
  4172  	if arg == nil {
  4173  		return fn(da)
  4174  	}
  4175  	da = &DefaultArg{Num: da.Num, Arg: arg}
  4176  	if r := fn(da); r != nil {
  4177  		return r
  4178  	}
  4179  	return da
  4180  }
  4181  
  4182  func (da *DefaultArg) GoString() string {
  4183  	return da.goString(0, "")
  4184  }
  4185  
  4186  func (da *DefaultArg) goString(indent int, field string) string {
  4187  	return fmt.Sprintf("%*s%sDefaultArg: Num: %d\n%s", indent, "", field, da.Num,
  4188  		da.Arg.goString(indent+2, "Arg: "))
  4189  }
  4190  
  4191  // Closure is a closure, or lambda expression.
  4192  type Closure struct {
  4193  	TemplateArgs           []AST
  4194  	TemplateArgsConstraint AST
  4195  	Types                  []AST
  4196  	Num                    int
  4197  	CallConstraint         AST
  4198  }
  4199  
  4200  func (cl *Closure) print(ps *printState) {
  4201  	if ps.llvmStyle {
  4202  		if cl.Num == 0 {
  4203  			ps.writeString("'lambda'")
  4204  		} else {
  4205  			ps.writeString(fmt.Sprintf("'lambda%d'", cl.Num-1))
  4206  		}
  4207  	} else {
  4208  		ps.writeString("{lambda")
  4209  	}
  4210  	cl.printTypes(ps)
  4211  	if !ps.llvmStyle {
  4212  		ps.writeString(fmt.Sprintf("#%d}", cl.Num+1))
  4213  	}
  4214  }
  4215  
  4216  func (cl *Closure) printTypes(ps *printState) {
  4217  	if len(cl.TemplateArgs) > 0 {
  4218  		scopes := ps.scopes
  4219  		ps.scopes = 0
  4220  
  4221  		ps.writeString("<")
  4222  		ps.printList(cl.TemplateArgs, nil)
  4223  		ps.writeString(">")
  4224  
  4225  		ps.scopes = scopes
  4226  	}
  4227  
  4228  	if cl.TemplateArgsConstraint != nil {
  4229  		ps.writeString(" requires ")
  4230  		ps.print(cl.TemplateArgsConstraint)
  4231  		ps.writeByte(' ')
  4232  	}
  4233  
  4234  	ps.startScope('(')
  4235  	ps.printList(cl.Types, nil)
  4236  	ps.endScope(')')
  4237  
  4238  	if cl.CallConstraint != nil {
  4239  		ps.writeString(" requires ")
  4240  		ps.print(cl.CallConstraint)
  4241  	}
  4242  }
  4243  
  4244  func (cl *Closure) Traverse(fn func(AST) bool) {
  4245  	if fn(cl) {
  4246  		for _, a := range cl.TemplateArgs {
  4247  			a.Traverse(fn)
  4248  		}
  4249  		if cl.TemplateArgsConstraint != nil {
  4250  			cl.TemplateArgsConstraint.Traverse(fn)
  4251  		}
  4252  		for _, t := range cl.Types {
  4253  			t.Traverse(fn)
  4254  		}
  4255  		if cl.CallConstraint != nil {
  4256  			cl.CallConstraint.Traverse(fn)
  4257  		}
  4258  	}
  4259  }
  4260  
  4261  func (cl *Closure) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4262  	if skip(cl) {
  4263  		return nil
  4264  	}
  4265  	changed := false
  4266  
  4267  	args := make([]AST, len(cl.TemplateArgs))
  4268  	for i, a := range cl.TemplateArgs {
  4269  		ac := a.Copy(fn, skip)
  4270  		if ac == nil {
  4271  			args[i] = a
  4272  		} else {
  4273  			args[i] = ac
  4274  			changed = true
  4275  		}
  4276  	}
  4277  
  4278  	var templateArgsConstraint AST
  4279  	if cl.TemplateArgsConstraint != nil {
  4280  		templateArgsConstraint = cl.TemplateArgsConstraint.Copy(fn, skip)
  4281  		if templateArgsConstraint == nil {
  4282  			templateArgsConstraint = cl.TemplateArgsConstraint
  4283  		} else {
  4284  			changed = true
  4285  		}
  4286  	}
  4287  
  4288  	types := make([]AST, len(cl.Types))
  4289  	for i, t := range cl.Types {
  4290  		tc := t.Copy(fn, skip)
  4291  		if tc == nil {
  4292  			types[i] = t
  4293  		} else {
  4294  			types[i] = tc
  4295  			changed = true
  4296  		}
  4297  	}
  4298  
  4299  	var callConstraint AST
  4300  	if cl.CallConstraint != nil {
  4301  		callConstraint = cl.CallConstraint.Copy(fn, skip)
  4302  		if callConstraint == nil {
  4303  			callConstraint = cl.CallConstraint
  4304  		} else {
  4305  			changed = true
  4306  		}
  4307  	}
  4308  
  4309  	if !changed {
  4310  		return fn(cl)
  4311  	}
  4312  	cl = &Closure{
  4313  		TemplateArgs:           args,
  4314  		TemplateArgsConstraint: templateArgsConstraint,
  4315  		Types:                  types,
  4316  		Num:                    cl.Num,
  4317  		CallConstraint:         callConstraint,
  4318  	}
  4319  	if r := fn(cl); r != nil {
  4320  		return r
  4321  	}
  4322  	return cl
  4323  }
  4324  
  4325  func (cl *Closure) GoString() string {
  4326  	return cl.goString(0, "")
  4327  }
  4328  
  4329  func (cl *Closure) goString(indent int, field string) string {
  4330  	var args strings.Builder
  4331  	if len(cl.TemplateArgs) == 0 {
  4332  		fmt.Fprintf(&args, "%*sTemplateArgs: nil", indent+2, "")
  4333  	} else {
  4334  		fmt.Fprintf(&args, "%*sTemplateArgs:", indent+2, "")
  4335  		for i, a := range cl.TemplateArgs {
  4336  			args.WriteByte('\n')
  4337  			args.WriteString(a.goString(indent+4, fmt.Sprintf("%d: ", i)))
  4338  		}
  4339  	}
  4340  
  4341  	var templateArgsConstraint string
  4342  	if cl.TemplateArgsConstraint != nil {
  4343  		templateArgsConstraint = "\n" + cl.TemplateArgsConstraint.goString(indent+2, "TemplateArgsConstraint: ")
  4344  	}
  4345  
  4346  	var types strings.Builder
  4347  	if len(cl.Types) == 0 {
  4348  		fmt.Fprintf(&types, "%*sTypes: nil", indent+2, "")
  4349  	} else {
  4350  		fmt.Fprintf(&types, "%*sTypes:", indent+2, "")
  4351  		for i, t := range cl.Types {
  4352  			types.WriteByte('\n')
  4353  			types.WriteString(t.goString(indent+4, fmt.Sprintf("%d: ", i)))
  4354  		}
  4355  	}
  4356  
  4357  	var callConstraint string
  4358  	if cl.CallConstraint != nil {
  4359  		callConstraint = "\n" + cl.CallConstraint.goString(indent+2, "CallConstraint: ")
  4360  	}
  4361  
  4362  	return fmt.Sprintf("%*s%sClosure: Num: %d\n%s\n%s%s%s", indent, "", field,
  4363  		cl.Num, args.String(), templateArgsConstraint, types.String(),
  4364  		callConstraint)
  4365  }
  4366  
  4367  // StructuredBindings is a structured binding declaration.
  4368  type StructuredBindings struct {
  4369  	Bindings []AST
  4370  }
  4371  
  4372  func (sb *StructuredBindings) print(ps *printState) {
  4373  	ps.writeString("[")
  4374  	ps.printList(sb.Bindings, nil)
  4375  	ps.writeString("]")
  4376  }
  4377  
  4378  func (sb *StructuredBindings) Traverse(fn func(AST) bool) {
  4379  	if fn(sb) {
  4380  		for _, b := range sb.Bindings {
  4381  			b.Traverse(fn)
  4382  		}
  4383  	}
  4384  }
  4385  
  4386  func (sb *StructuredBindings) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4387  	if skip(sb) {
  4388  		return nil
  4389  	}
  4390  	changed := false
  4391  	bindings := make([]AST, len(sb.Bindings))
  4392  	for i, b := range sb.Bindings {
  4393  		bc := b.Copy(fn, skip)
  4394  		if bc == nil {
  4395  			bindings[i] = b
  4396  		} else {
  4397  			bindings[i] = bc
  4398  			changed = true
  4399  		}
  4400  	}
  4401  	if !changed {
  4402  		return fn(sb)
  4403  	}
  4404  	sb = &StructuredBindings{Bindings: bindings}
  4405  	if r := fn(sb); r != nil {
  4406  		return r
  4407  	}
  4408  	return sb
  4409  }
  4410  
  4411  func (sb *StructuredBindings) GoString() string {
  4412  	return sb.goString(0, "")
  4413  }
  4414  
  4415  func (sb *StructuredBindings) goString(indent int, field string) string {
  4416  	var strb strings.Builder
  4417  	fmt.Fprintf(&strb, "%*s%sStructuredBinding:", indent, "", field)
  4418  	for _, b := range sb.Bindings {
  4419  		strb.WriteByte('\n')
  4420  		strb.WriteString(b.goString(indent+2, ""))
  4421  	}
  4422  	return strb.String()
  4423  }
  4424  
  4425  // UnnamedType is an unnamed type, that just has an index.
  4426  type UnnamedType struct {
  4427  	Num int
  4428  }
  4429  
  4430  func (ut *UnnamedType) print(ps *printState) {
  4431  	if ps.llvmStyle {
  4432  		if ut.Num == 0 {
  4433  			ps.writeString("'unnamed'")
  4434  		} else {
  4435  			ps.writeString(fmt.Sprintf("'unnamed%d'", ut.Num-1))
  4436  		}
  4437  	} else {
  4438  		ps.writeString(fmt.Sprintf("{unnamed type#%d}", ut.Num+1))
  4439  	}
  4440  }
  4441  
  4442  func (ut *UnnamedType) Traverse(fn func(AST) bool) {
  4443  	fn(ut)
  4444  }
  4445  
  4446  func (ut *UnnamedType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4447  	if skip(ut) {
  4448  		return nil
  4449  	}
  4450  	return fn(ut)
  4451  }
  4452  
  4453  func (ut *UnnamedType) GoString() string {
  4454  	return ut.goString(0, "")
  4455  }
  4456  
  4457  func (ut *UnnamedType) goString(indent int, field string) string {
  4458  	return fmt.Sprintf("%*s%sUnnamedType: Num: %d", indent, "", field, ut.Num)
  4459  }
  4460  
  4461  // Clone is a clone of a function, with a distinguishing suffix.
  4462  type Clone struct {
  4463  	Base   AST
  4464  	Suffix string
  4465  }
  4466  
  4467  func (c *Clone) print(ps *printState) {
  4468  	ps.print(c.Base)
  4469  	if ps.llvmStyle {
  4470  		ps.writeByte(' ')
  4471  		ps.startScope('(')
  4472  		ps.writeString(c.Suffix)
  4473  		ps.endScope(')')
  4474  	} else {
  4475  		ps.writeString(fmt.Sprintf(" [clone %s]", c.Suffix))
  4476  	}
  4477  }
  4478  
  4479  func (c *Clone) Traverse(fn func(AST) bool) {
  4480  	if fn(c) {
  4481  		c.Base.Traverse(fn)
  4482  	}
  4483  }
  4484  
  4485  func (c *Clone) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4486  	if skip(c) {
  4487  		return nil
  4488  	}
  4489  	base := c.Base.Copy(fn, skip)
  4490  	if base == nil {
  4491  		return fn(c)
  4492  	}
  4493  	c = &Clone{Base: base, Suffix: c.Suffix}
  4494  	if r := fn(c); r != nil {
  4495  		return r
  4496  	}
  4497  	return c
  4498  }
  4499  
  4500  func (c *Clone) GoString() string {
  4501  	return c.goString(0, "")
  4502  }
  4503  
  4504  func (c *Clone) goString(indent int, field string) string {
  4505  	return fmt.Sprintf("%*s%sClone: Suffix: %s\n%s", indent, "", field,
  4506  		c.Suffix, c.Base.goString(indent+2, "Base: "))
  4507  }
  4508  
  4509  // Special is a special symbol, printed as a prefix plus another
  4510  // value.
  4511  type Special struct {
  4512  	Prefix string
  4513  	Val    AST
  4514  }
  4515  
  4516  func (s *Special) print(ps *printState) {
  4517  	prefix := s.Prefix
  4518  	if ps.llvmStyle {
  4519  		switch prefix {
  4520  		case "TLS wrapper function for ":
  4521  			prefix = "thread-local wrapper routine for "
  4522  		case "TLS init function for ":
  4523  			prefix = "thread-local initialization routine for "
  4524  		}
  4525  	}
  4526  	ps.writeString(prefix)
  4527  	ps.print(s.Val)
  4528  }
  4529  
  4530  func (s *Special) Traverse(fn func(AST) bool) {
  4531  	if fn(s) {
  4532  		s.Val.Traverse(fn)
  4533  	}
  4534  }
  4535  
  4536  func (s *Special) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4537  	if skip(s) {
  4538  		return nil
  4539  	}
  4540  	val := s.Val.Copy(fn, skip)
  4541  	if val == nil {
  4542  		return fn(s)
  4543  	}
  4544  	s = &Special{Prefix: s.Prefix, Val: val}
  4545  	if r := fn(s); r != nil {
  4546  		return r
  4547  	}
  4548  	return s
  4549  }
  4550  
  4551  func (s *Special) GoString() string {
  4552  	return s.goString(0, "")
  4553  }
  4554  
  4555  func (s *Special) goString(indent int, field string) string {
  4556  	return fmt.Sprintf("%*s%sSpecial: Prefix: %s\n%s", indent, "", field,
  4557  		s.Prefix, s.Val.goString(indent+2, "Val: "))
  4558  }
  4559  
  4560  // Special2 is like special, but uses two values.
  4561  type Special2 struct {
  4562  	Prefix string
  4563  	Val1   AST
  4564  	Middle string
  4565  	Val2   AST
  4566  }
  4567  
  4568  func (s *Special2) print(ps *printState) {
  4569  	ps.writeString(s.Prefix)
  4570  	ps.print(s.Val1)
  4571  	ps.writeString(s.Middle)
  4572  	ps.print(s.Val2)
  4573  }
  4574  
  4575  func (s *Special2) Traverse(fn func(AST) bool) {
  4576  	if fn(s) {
  4577  		s.Val1.Traverse(fn)
  4578  		s.Val2.Traverse(fn)
  4579  	}
  4580  }
  4581  
  4582  func (s *Special2) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4583  	if skip(s) {
  4584  		return nil
  4585  	}
  4586  	val1 := s.Val1.Copy(fn, skip)
  4587  	val2 := s.Val2.Copy(fn, skip)
  4588  	if val1 == nil && val2 == nil {
  4589  		return fn(s)
  4590  	}
  4591  	if val1 == nil {
  4592  		val1 = s.Val1
  4593  	}
  4594  	if val2 == nil {
  4595  		val2 = s.Val2
  4596  	}
  4597  	s = &Special2{Prefix: s.Prefix, Val1: val1, Middle: s.Middle, Val2: val2}
  4598  	if r := fn(s); r != nil {
  4599  		return r
  4600  	}
  4601  	return s
  4602  }
  4603  
  4604  func (s *Special2) GoString() string {
  4605  	return s.goString(0, "")
  4606  }
  4607  
  4608  func (s *Special2) goString(indent int, field string) string {
  4609  	return fmt.Sprintf("%*s%sSpecial2: Prefix: %s\n%s\n%*sMiddle: %s\n%s", indent, "", field,
  4610  		s.Prefix, s.Val1.goString(indent+2, "Val1: "),
  4611  		indent+2, "", s.Middle, s.Val2.goString(indent+2, "Val2: "))
  4612  }
  4613  
  4614  // EnableIf is used by clang for an enable_if attribute.
  4615  type EnableIf struct {
  4616  	Type AST
  4617  	Args []AST
  4618  }
  4619  
  4620  func (ei *EnableIf) print(ps *printState) {
  4621  	ps.print(ei.Type)
  4622  	ps.writeString(" [enable_if:")
  4623  	ps.printList(ei.Args, nil)
  4624  	ps.writeString("]")
  4625  }
  4626  
  4627  func (ei *EnableIf) Traverse(fn func(AST) bool) {
  4628  	if fn(ei) {
  4629  		ei.Type.Traverse(fn)
  4630  		for _, a := range ei.Args {
  4631  			a.Traverse(fn)
  4632  		}
  4633  	}
  4634  }
  4635  
  4636  func (ei *EnableIf) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4637  	if skip(ei) {
  4638  		return nil
  4639  	}
  4640  	typ := ei.Type.Copy(fn, skip)
  4641  	argsChanged := false
  4642  	args := make([]AST, len(ei.Args))
  4643  	for i, a := range ei.Args {
  4644  		ac := a.Copy(fn, skip)
  4645  		if ac == nil {
  4646  			args[i] = a
  4647  		} else {
  4648  			args[i] = ac
  4649  			argsChanged = true
  4650  		}
  4651  	}
  4652  	if typ == nil && !argsChanged {
  4653  		return fn(ei)
  4654  	}
  4655  	if typ == nil {
  4656  		typ = ei.Type
  4657  	}
  4658  	ei = &EnableIf{Type: typ, Args: args}
  4659  	if r := fn(ei); r != nil {
  4660  		return r
  4661  	}
  4662  	return ei
  4663  }
  4664  
  4665  func (ei *EnableIf) GoString() string {
  4666  	return ei.goString(0, "")
  4667  }
  4668  
  4669  func (ei *EnableIf) goString(indent int, field string) string {
  4670  	var args string
  4671  	if len(ei.Args) == 0 {
  4672  		args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
  4673  	} else {
  4674  		args = fmt.Sprintf("%*sArgs:", indent+2, "")
  4675  		for i, a := range ei.Args {
  4676  			args += "\n"
  4677  			args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
  4678  		}
  4679  	}
  4680  	return fmt.Sprintf("%*s%sEnableIf:\n%s\n%s", indent, "", field,
  4681  		ei.Type.goString(indent+2, "Type: "), args)
  4682  }
  4683  
  4684  // ModuleName is a C++20 module.
  4685  type ModuleName struct {
  4686  	Parent      AST
  4687  	Name        AST
  4688  	IsPartition bool
  4689  }
  4690  
  4691  func (mn *ModuleName) print(ps *printState) {
  4692  	if mn.Parent != nil {
  4693  		ps.print(mn.Parent)
  4694  	}
  4695  	if mn.IsPartition {
  4696  		ps.writeByte(':')
  4697  	} else if mn.Parent != nil {
  4698  		ps.writeByte('.')
  4699  	}
  4700  	ps.print(mn.Name)
  4701  }
  4702  
  4703  func (mn *ModuleName) Traverse(fn func(AST) bool) {
  4704  	if fn(mn) {
  4705  		mn.Parent.Traverse(fn)
  4706  		mn.Name.Traverse(fn)
  4707  	}
  4708  }
  4709  
  4710  func (mn *ModuleName) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4711  	if skip(mn) {
  4712  		return nil
  4713  	}
  4714  	var parent AST
  4715  	if mn.Parent != nil {
  4716  		parent = mn.Parent.Copy(fn, skip)
  4717  	}
  4718  	name := mn.Name.Copy(fn, skip)
  4719  	if parent == nil && name == nil {
  4720  		return fn(mn)
  4721  	}
  4722  	if parent == nil {
  4723  		parent = mn.Parent
  4724  	}
  4725  	if name == nil {
  4726  		name = mn.Name
  4727  	}
  4728  	mn = &ModuleName{Parent: parent, Name: name, IsPartition: mn.IsPartition}
  4729  	if r := fn(mn); r != nil {
  4730  		return r
  4731  	}
  4732  	return mn
  4733  }
  4734  
  4735  func (mn *ModuleName) GoString() string {
  4736  	return mn.goString(0, "")
  4737  }
  4738  
  4739  func (mn *ModuleName) goString(indent int, field string) string {
  4740  	var parent string
  4741  	if mn.Parent == nil {
  4742  		parent = fmt.Sprintf("%*sParent: nil", indent+2, "")
  4743  	} else {
  4744  		parent = mn.Parent.goString(indent+2, "Parent: ")
  4745  	}
  4746  	return fmt.Sprintf("%*s%sModuleName: IsPartition: %t\n%s\n%s", indent, "", field,
  4747  		mn.IsPartition, parent,
  4748  		mn.Name.goString(indent+2, "Name: "))
  4749  }
  4750  
  4751  // ModuleEntity is a name inside a module.
  4752  type ModuleEntity struct {
  4753  	Module AST
  4754  	Name   AST
  4755  }
  4756  
  4757  func (me *ModuleEntity) print(ps *printState) {
  4758  	ps.print(me.Name)
  4759  	ps.writeByte('@')
  4760  	ps.print(me.Module)
  4761  }
  4762  
  4763  func (me *ModuleEntity) Traverse(fn func(AST) bool) {
  4764  	if fn(me) {
  4765  		me.Module.Traverse(fn)
  4766  		me.Name.Traverse(fn)
  4767  	}
  4768  }
  4769  
  4770  func (me *ModuleEntity) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4771  	if skip(me) {
  4772  		return nil
  4773  	}
  4774  	module := me.Module.Copy(fn, skip)
  4775  	name := me.Name.Copy(fn, skip)
  4776  	if module == nil && name == nil {
  4777  		return fn(me)
  4778  	}
  4779  	if module == nil {
  4780  		module = me.Module
  4781  	}
  4782  	if name == nil {
  4783  		name = me.Name
  4784  	}
  4785  	me = &ModuleEntity{Module: module, Name: name}
  4786  	if r := fn(me); r != nil {
  4787  		return r
  4788  	}
  4789  	return me
  4790  }
  4791  
  4792  func (me *ModuleEntity) GoString() string {
  4793  	return me.goString(0, "")
  4794  }
  4795  
  4796  func (me *ModuleEntity) goString(indent int, field string) string {
  4797  	return fmt.Sprintf("%*s%sModuleEntity:\n%s\n%s", indent, "", field,
  4798  		me.Module.goString(indent+2, "Module: "),
  4799  		me.Name.goString(indent+2, "Name: "))
  4800  }
  4801  
  4802  // Friend is a member like friend name.
  4803  type Friend struct {
  4804  	Name AST
  4805  }
  4806  
  4807  func (f *Friend) print(ps *printState) {
  4808  	ps.writeString("friend ")
  4809  	ps.print(f.Name)
  4810  }
  4811  
  4812  func (f *Friend) Traverse(fn func(AST) bool) {
  4813  	if fn(f) {
  4814  		f.Name.Traverse(fn)
  4815  	}
  4816  }
  4817  
  4818  func (f *Friend) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4819  	if skip(f) {
  4820  		return nil
  4821  	}
  4822  	name := f.Name.Copy(fn, skip)
  4823  	if name == nil {
  4824  		return fn(f)
  4825  	}
  4826  	f = &Friend{Name: name}
  4827  	if r := fn(f); r != nil {
  4828  		return r
  4829  	}
  4830  	return f
  4831  }
  4832  
  4833  func (f *Friend) GoString() string {
  4834  	return f.goString(0, "")
  4835  }
  4836  
  4837  func (f *Friend) goString(indent int, field string) string {
  4838  	return fmt.Sprintf("%*s%sFriend:\n%s", indent, "", field,
  4839  		f.Name.goString(indent+2, "Name: "))
  4840  }
  4841  
  4842  // Constraint represents an AST with a constraint.
  4843  type Constraint struct {
  4844  	Name     AST
  4845  	Requires AST
  4846  }
  4847  
  4848  func (c *Constraint) print(ps *printState) {
  4849  	ps.print(c.Name)
  4850  	ps.writeString(" requires ")
  4851  	ps.print(c.Requires)
  4852  }
  4853  
  4854  func (c *Constraint) Traverse(fn func(AST) bool) {
  4855  	if fn(c) {
  4856  		c.Name.Traverse(fn)
  4857  		c.Requires.Traverse(fn)
  4858  	}
  4859  }
  4860  
  4861  func (c *Constraint) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4862  	if skip(c) {
  4863  		return nil
  4864  	}
  4865  	name := c.Name.Copy(fn, skip)
  4866  	requires := c.Requires.Copy(fn, skip)
  4867  	if name == nil && requires == nil {
  4868  		return fn(c)
  4869  	}
  4870  	if name == nil {
  4871  		name = c.Name
  4872  	}
  4873  	if requires == nil {
  4874  		requires = c.Requires
  4875  	}
  4876  	c = &Constraint{Name: name, Requires: requires}
  4877  	if r := fn(c); r != nil {
  4878  		return r
  4879  	}
  4880  	return c
  4881  }
  4882  
  4883  func (c *Constraint) GoString() string {
  4884  	return c.goString(0, "")
  4885  }
  4886  
  4887  func (c *Constraint) goString(indent int, field string) string {
  4888  	return fmt.Sprintf("%*s%sConstraint:\n%s\n%s", indent, "", field,
  4889  		c.Name.goString(indent+2, "Name: "),
  4890  		c.Requires.goString(indent+2, "Requires: "))
  4891  }
  4892  
  4893  // RequiresExpr is a C++20 requires expression.
  4894  type RequiresExpr struct {
  4895  	Params       []AST
  4896  	Requirements []AST
  4897  }
  4898  
  4899  func (re *RequiresExpr) print(ps *printState) {
  4900  	ps.writeString("requires")
  4901  	if len(re.Params) > 0 {
  4902  		ps.writeByte(' ')
  4903  		ps.startScope('(')
  4904  		ps.printList(re.Params, nil)
  4905  		ps.endScope(')')
  4906  	}
  4907  	ps.writeByte(' ')
  4908  	ps.startScope('{')
  4909  	for _, req := range re.Requirements {
  4910  		ps.print(req)
  4911  	}
  4912  	ps.writeByte(' ')
  4913  	ps.endScope('}')
  4914  }
  4915  
  4916  func (re *RequiresExpr) Traverse(fn func(AST) bool) {
  4917  	if fn(re) {
  4918  		for _, p := range re.Params {
  4919  			p.Traverse(fn)
  4920  		}
  4921  		for _, r := range re.Requirements {
  4922  			r.Traverse(fn)
  4923  		}
  4924  	}
  4925  }
  4926  
  4927  func (re *RequiresExpr) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  4928  	if skip(re) {
  4929  		return nil
  4930  	}
  4931  
  4932  	changed := false
  4933  
  4934  	var params []AST
  4935  	if len(re.Params) > 0 {
  4936  		params = make([]AST, len(re.Params))
  4937  		for i, p := range re.Params {
  4938  			pc := p.Copy(fn, skip)
  4939  			if pc == nil {
  4940  				params[i] = p
  4941  			} else {
  4942  				params[i] = pc
  4943  				changed = true
  4944  			}
  4945  		}
  4946  	}
  4947  
  4948  	requirements := make([]AST, len(re.Requirements))
  4949  	for i, r := range re.Requirements {
  4950  		rc := r.Copy(fn, skip)
  4951  		if rc == nil {
  4952  			requirements[i] = r
  4953  		} else {
  4954  			requirements[i] = rc
  4955  			changed = true
  4956  		}
  4957  	}
  4958  
  4959  	if !changed {
  4960  		return fn(re)
  4961  	}
  4962  
  4963  	re = &RequiresExpr{Params: params, Requirements: requirements}
  4964  	if r := fn(re); r != nil {
  4965  		return r
  4966  	}
  4967  	return re
  4968  }
  4969  
  4970  func (re *RequiresExpr) GoString() string {
  4971  	return re.goString(0, "")
  4972  }
  4973  
  4974  func (re *RequiresExpr) goString(indent int, field string) string {
  4975  	var params strings.Builder
  4976  	if len(re.Params) == 0 {
  4977  		fmt.Fprintf(&params, "%*sParams: nil", indent+2, "")
  4978  	} else {
  4979  		fmt.Fprintf(&params, "%*sParams:", indent+2, "")
  4980  		for i, p := range re.Params {
  4981  			params.WriteByte('\n')
  4982  			params.WriteString(p.goString(indent+4, fmt.Sprintf("%d: ", i)))
  4983  		}
  4984  	}
  4985  
  4986  	var requirements strings.Builder
  4987  	fmt.Fprintf(&requirements, "%*sRequirements:", indent+2, "")
  4988  	for i, r := range re.Requirements {
  4989  		requirements.WriteByte('\n')
  4990  		requirements.WriteString(r.goString(indent+4, fmt.Sprintf("%d: ", i)))
  4991  	}
  4992  
  4993  	return fmt.Sprintf("%*s%sRequirements:\n%s\n%s", indent, "", field,
  4994  		params.String(), requirements.String())
  4995  }
  4996  
  4997  // ExprRequirement is a simple requirement in a requires expression.
  4998  // This is an arbitrary expression.
  4999  type ExprRequirement struct {
  5000  	Expr     AST
  5001  	Noexcept bool
  5002  	TypeReq  AST
  5003  }
  5004  
  5005  func (er *ExprRequirement) print(ps *printState) {
  5006  	ps.writeByte(' ')
  5007  	if er.Noexcept || er.TypeReq != nil {
  5008  		ps.startScope('{')
  5009  	}
  5010  	ps.print(er.Expr)
  5011  	if er.Noexcept || er.TypeReq != nil {
  5012  		ps.endScope('}')
  5013  	}
  5014  	if er.Noexcept {
  5015  		ps.writeString(" noexcept")
  5016  	}
  5017  	if er.TypeReq != nil {
  5018  		ps.writeString(" -> ")
  5019  		ps.print(er.TypeReq)
  5020  	}
  5021  	ps.writeByte(';')
  5022  }
  5023  
  5024  func (er *ExprRequirement) Traverse(fn func(AST) bool) {
  5025  	if fn(er) {
  5026  		er.Expr.Traverse(fn)
  5027  		if er.TypeReq != nil {
  5028  			er.TypeReq.Traverse(fn)
  5029  		}
  5030  	}
  5031  }
  5032  
  5033  func (er *ExprRequirement) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  5034  	if skip(er) {
  5035  		return nil
  5036  	}
  5037  	expr := er.Expr.Copy(fn, skip)
  5038  	var typeReq AST
  5039  	if er.TypeReq != nil {
  5040  		typeReq = er.TypeReq.Copy(fn, skip)
  5041  	}
  5042  	if expr == nil && typeReq == nil {
  5043  		return fn(er)
  5044  	}
  5045  	if expr == nil {
  5046  		expr = er.Expr
  5047  	}
  5048  	if typeReq == nil {
  5049  		typeReq = er.TypeReq
  5050  	}
  5051  	er = &ExprRequirement{Expr: expr, TypeReq: typeReq}
  5052  	if r := fn(er); r != nil {
  5053  		return r
  5054  	}
  5055  	return er
  5056  }
  5057  
  5058  func (er *ExprRequirement) GoString() string {
  5059  	return er.goString(0, "")
  5060  }
  5061  
  5062  func (er *ExprRequirement) goString(indent int, field string) string {
  5063  	var typeReq string
  5064  	if er.TypeReq != nil {
  5065  		typeReq = "\n" + er.TypeReq.goString(indent+2, "TypeReq: ")
  5066  	}
  5067  
  5068  	return fmt.Sprintf("%*s%sExprRequirement: Noexcept: %t\n%s%s", indent, "", field,
  5069  		er.Noexcept,
  5070  		er.Expr.goString(indent+2, "Expr: "),
  5071  		typeReq)
  5072  }
  5073  
  5074  // TypeRequirement is a type requirement in a requires expression.
  5075  type TypeRequirement struct {
  5076  	Type AST
  5077  }
  5078  
  5079  func (tr *TypeRequirement) print(ps *printState) {
  5080  	ps.writeString(" typename ")
  5081  	ps.print(tr.Type)
  5082  	ps.writeByte(';')
  5083  }
  5084  
  5085  func (tr *TypeRequirement) Traverse(fn func(AST) bool) {
  5086  	if fn(tr) {
  5087  		tr.Type.Traverse(fn)
  5088  	}
  5089  }
  5090  
  5091  func (tr *TypeRequirement) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  5092  	if skip(tr) {
  5093  		return nil
  5094  	}
  5095  	typ := tr.Type.Copy(fn, skip)
  5096  	if typ == nil {
  5097  		return fn(tr)
  5098  	}
  5099  	tr = &TypeRequirement{Type: typ}
  5100  	if r := fn(tr); r != nil {
  5101  		return r
  5102  	}
  5103  	return tr
  5104  }
  5105  
  5106  func (tr *TypeRequirement) GoString() string {
  5107  	return tr.goString(0, "")
  5108  }
  5109  
  5110  func (tr *TypeRequirement) goString(indent int, field string) string {
  5111  	return fmt.Sprintf("%*s%sTypeRequirement:\n%s", indent, "", field,
  5112  		tr.Type.goString(indent+2, ""))
  5113  }
  5114  
  5115  // NestedRequirement is a nested requirement in a requires expression.
  5116  type NestedRequirement struct {
  5117  	Constraint AST
  5118  }
  5119  
  5120  func (nr *NestedRequirement) print(ps *printState) {
  5121  	ps.writeString(" requires ")
  5122  	ps.print(nr.Constraint)
  5123  	ps.writeByte(';')
  5124  }
  5125  
  5126  func (nr *NestedRequirement) Traverse(fn func(AST) bool) {
  5127  	if fn(nr) {
  5128  		nr.Constraint.Traverse(fn)
  5129  	}
  5130  }
  5131  
  5132  func (nr *NestedRequirement) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  5133  	if skip(nr) {
  5134  		return nil
  5135  	}
  5136  	constraint := nr.Constraint.Copy(fn, skip)
  5137  	if constraint == nil {
  5138  		return fn(nr)
  5139  	}
  5140  	nr = &NestedRequirement{Constraint: constraint}
  5141  	if r := fn(nr); r != nil {
  5142  		return r
  5143  	}
  5144  	return nr
  5145  }
  5146  
  5147  func (nr *NestedRequirement) GoString() string {
  5148  	return nr.goString(0, "")
  5149  }
  5150  
  5151  func (nr *NestedRequirement) goString(indent int, field string) string {
  5152  	return fmt.Sprintf("%*s%sNestedRequirement:\n%s", indent, "", field,
  5153  		nr.Constraint.goString(indent+2, ""))
  5154  }
  5155  
  5156  // ExplicitObjectParameter represents a C++23 explicit object parameter.
  5157  type ExplicitObjectParameter struct {
  5158  	Base AST
  5159  }
  5160  
  5161  func (eop *ExplicitObjectParameter) print(ps *printState) {
  5162  	ps.writeString("this ")
  5163  	ps.print(eop.Base)
  5164  }
  5165  
  5166  func (eop *ExplicitObjectParameter) Traverse(fn func(AST) bool) {
  5167  	if fn(eop) {
  5168  		eop.Base.Traverse(fn)
  5169  	}
  5170  }
  5171  
  5172  func (eop *ExplicitObjectParameter) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  5173  	if skip(eop) {
  5174  		return nil
  5175  	}
  5176  	base := eop.Base.Copy(fn, skip)
  5177  	if base == nil {
  5178  		return fn(eop)
  5179  	}
  5180  	eop = &ExplicitObjectParameter{Base: base}
  5181  	if r := fn(eop); r != nil {
  5182  		return r
  5183  	}
  5184  	return eop
  5185  }
  5186  
  5187  func (eop *ExplicitObjectParameter) GoString() string {
  5188  	return eop.goString(0, "")
  5189  }
  5190  
  5191  func (eop *ExplicitObjectParameter) goString(indent int, field string) string {
  5192  	return fmt.Sprintf("%*s%sExplicitObjectParameter:\n%s", indent, "", field,
  5193  		eop.Base.goString(indent+2, ""))
  5194  }
  5195  
  5196  // Print the inner types.
  5197  func (ps *printState) printInner(prefixOnly bool) []AST {
  5198  	var save []AST
  5199  	var psave *[]AST
  5200  	if prefixOnly {
  5201  		psave = &save
  5202  	}
  5203  	for len(ps.inner) > 0 {
  5204  		ps.printOneInner(psave)
  5205  	}
  5206  	return save
  5207  }
  5208  
  5209  // innerPrinter is an interface for types that can print themselves as
  5210  // inner types.
  5211  type innerPrinter interface {
  5212  	printInner(*printState)
  5213  }
  5214  
  5215  // Print the most recent inner type.  If save is not nil, only print
  5216  // prefixes.
  5217  func (ps *printState) printOneInner(save *[]AST) {
  5218  	if len(ps.inner) == 0 {
  5219  		panic("printOneInner called with no inner types")
  5220  	}
  5221  	ln := len(ps.inner)
  5222  	a := ps.inner[ln-1]
  5223  	ps.inner = ps.inner[:ln-1]
  5224  
  5225  	if save != nil {
  5226  		if _, ok := a.(*MethodWithQualifiers); ok {
  5227  			*save = append(*save, a)
  5228  			return
  5229  		}
  5230  	}
  5231  
  5232  	if ip, ok := a.(innerPrinter); ok {
  5233  		ip.printInner(ps)
  5234  	} else {
  5235  		ps.print(a)
  5236  	}
  5237  }
  5238  
  5239  // isEmpty returns whether printing a will not print anything.
  5240  func (ps *printState) isEmpty(a AST) bool {
  5241  	switch a := a.(type) {
  5242  	case *ArgumentPack:
  5243  		for _, a := range a.Args {
  5244  			if !ps.isEmpty(a) {
  5245  				return false
  5246  			}
  5247  		}
  5248  		return true
  5249  	case *ExprList:
  5250  		return len(a.Exprs) == 0
  5251  	case *PackExpansion:
  5252  		return a.Pack != nil && ps.isEmpty(a.Base)
  5253  	default:
  5254  		return false
  5255  	}
  5256  }
  5257  

View as plain text