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

     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  	llvmStyle := false
    42  	for _, o := range options {
    43  		switch o {
    44  		case NoTemplateParams:
    45  			tparams = false
    46  		case LLVMStyle:
    47  			llvmStyle = true
    48  		}
    49  	}
    50  
    51  	ps := printState{tparams: tparams, llvmStyle: llvmStyle}
    52  	a.print(&ps)
    53  	return ps.buf.String()
    54  }
    55  
    56  // The printState type holds information needed to print an AST.
    57  type printState struct {
    58  	tparams   bool // whether to print template parameters
    59  	llvmStyle bool
    60  
    61  	buf  strings.Builder
    62  	last byte // Last byte written to buffer.
    63  
    64  	// The inner field is a list of items to print for a type
    65  	// name.  This is used by types to implement the inside-out
    66  	// C++ declaration syntax.
    67  	inner []AST
    68  
    69  	// The printing field is a list of items we are currently
    70  	// printing.  This avoids endless recursion if a substitution
    71  	// reference creates a cycle in the graph.
    72  	printing []AST
    73  }
    74  
    75  // writeByte adds a byte to the string being printed.
    76  func (ps *printState) writeByte(b byte) {
    77  	ps.last = b
    78  	ps.buf.WriteByte(b)
    79  }
    80  
    81  // writeString adds a string to the string being printed.
    82  func (ps *printState) writeString(s string) {
    83  	if len(s) > 0 {
    84  		ps.last = s[len(s)-1]
    85  	}
    86  	ps.buf.WriteString(s)
    87  }
    88  
    89  // Print an AST.
    90  func (ps *printState) print(a AST) {
    91  	c := 0
    92  	for _, v := range ps.printing {
    93  		if v == a {
    94  			// We permit the type to appear once, and
    95  			// return without printing anything if we see
    96  			// it twice.  This is for a case like
    97  			// _Z6outer2IsEPFilES1_, where the
    98  			// substitution is printed differently the
    99  			// second time because the set of inner types
   100  			// is different.
   101  			c++
   102  			if c > 1 {
   103  				return
   104  			}
   105  		}
   106  	}
   107  	ps.printing = append(ps.printing, a)
   108  
   109  	a.print(ps)
   110  
   111  	ps.printing = ps.printing[:len(ps.printing)-1]
   112  }
   113  
   114  // Name is an unqualified name.
   115  type Name struct {
   116  	Name string
   117  }
   118  
   119  func (n *Name) print(ps *printState) {
   120  	ps.writeString(n.Name)
   121  }
   122  
   123  func (n *Name) Traverse(fn func(AST) bool) {
   124  	fn(n)
   125  }
   126  
   127  func (n *Name) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   128  	if skip(n) {
   129  		return nil
   130  	}
   131  	return fn(n)
   132  }
   133  
   134  func (n *Name) GoString() string {
   135  	return n.goString(0, "Name: ")
   136  }
   137  
   138  func (n *Name) goString(indent int, field string) string {
   139  	return fmt.Sprintf("%*s%s%s", indent, "", field, n.Name)
   140  }
   141  
   142  // Typed is a typed name.
   143  type Typed struct {
   144  	Name AST
   145  	Type AST
   146  }
   147  
   148  func (t *Typed) print(ps *printState) {
   149  	// We are printing a typed name, so ignore the current set of
   150  	// inner names to print.  Pass down our name as the one to use.
   151  	holdInner := ps.inner
   152  	defer func() { ps.inner = holdInner }()
   153  
   154  	ps.inner = []AST{t}
   155  	ps.print(t.Type)
   156  	if len(ps.inner) > 0 {
   157  		// The type did not print the name; print it now in
   158  		// the default location.
   159  		ps.writeByte(' ')
   160  		ps.print(t.Name)
   161  	}
   162  }
   163  
   164  func (t *Typed) printInner(ps *printState) {
   165  	ps.print(t.Name)
   166  }
   167  
   168  func (t *Typed) Traverse(fn func(AST) bool) {
   169  	if fn(t) {
   170  		t.Name.Traverse(fn)
   171  		t.Type.Traverse(fn)
   172  	}
   173  }
   174  
   175  func (t *Typed) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   176  	if skip(t) {
   177  		return nil
   178  	}
   179  	name := t.Name.Copy(fn, skip)
   180  	typ := t.Type.Copy(fn, skip)
   181  	if name == nil && typ == nil {
   182  		return fn(t)
   183  	}
   184  	if name == nil {
   185  		name = t.Name
   186  	}
   187  	if typ == nil {
   188  		typ = t.Type
   189  	}
   190  	t = &Typed{Name: name, Type: typ}
   191  	if r := fn(t); r != nil {
   192  		return r
   193  	}
   194  	return t
   195  }
   196  
   197  func (t *Typed) GoString() string {
   198  	return t.goString(0, "")
   199  }
   200  
   201  func (t *Typed) goString(indent int, field string) string {
   202  	return fmt.Sprintf("%*s%sTyped:\n%s\n%s", indent, "", field,
   203  		t.Name.goString(indent+2, "Name: "),
   204  		t.Type.goString(indent+2, "Type: "))
   205  }
   206  
   207  // Qualified is a name in a scope.
   208  type Qualified struct {
   209  	Scope AST
   210  	Name  AST
   211  
   212  	// The LocalName field is true if this is parsed as a
   213  	// <local-name>.  We shouldn't really need this, but in some
   214  	// cases (for the unary sizeof operator) the standard
   215  	// demangler prints a local name slightly differently.  We
   216  	// keep track of this for compatibility.
   217  	LocalName bool // A full local name encoding
   218  }
   219  
   220  func (q *Qualified) print(ps *printState) {
   221  	ps.print(q.Scope)
   222  	ps.writeString("::")
   223  	ps.print(q.Name)
   224  }
   225  
   226  func (q *Qualified) Traverse(fn func(AST) bool) {
   227  	if fn(q) {
   228  		q.Scope.Traverse(fn)
   229  		q.Name.Traverse(fn)
   230  	}
   231  }
   232  
   233  func (q *Qualified) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   234  	if skip(q) {
   235  		return nil
   236  	}
   237  	scope := q.Scope.Copy(fn, skip)
   238  	name := q.Name.Copy(fn, skip)
   239  	if scope == nil && name == nil {
   240  		return fn(q)
   241  	}
   242  	if scope == nil {
   243  		scope = q.Scope
   244  	}
   245  	if name == nil {
   246  		name = q.Name
   247  	}
   248  	q = &Qualified{Scope: scope, Name: name, LocalName: q.LocalName}
   249  	if r := fn(q); r != nil {
   250  		return r
   251  	}
   252  	return q
   253  }
   254  
   255  func (q *Qualified) GoString() string {
   256  	return q.goString(0, "")
   257  }
   258  
   259  func (q *Qualified) goString(indent int, field string) string {
   260  	s := ""
   261  	if q.LocalName {
   262  		s = " LocalName: true"
   263  	}
   264  	return fmt.Sprintf("%*s%sQualified:%s\n%s\n%s", indent, "", field,
   265  		s, q.Scope.goString(indent+2, "Scope: "),
   266  		q.Name.goString(indent+2, "Name: "))
   267  }
   268  
   269  // Template is a template with arguments.
   270  type Template struct {
   271  	Name AST
   272  	Args []AST
   273  }
   274  
   275  func (t *Template) print(ps *printState) {
   276  	// Inner types apply to the template as a whole, they don't
   277  	// cross over into the template.
   278  	holdInner := ps.inner
   279  	defer func() { ps.inner = holdInner }()
   280  
   281  	ps.inner = nil
   282  	ps.print(t.Name)
   283  
   284  	if !ps.tparams {
   285  		// Do not print template parameters.
   286  		return
   287  	}
   288  	// We need an extra space after operator<.
   289  	if ps.last == '<' {
   290  		ps.writeByte(' ')
   291  	}
   292  
   293  	ps.writeByte('<')
   294  	first := true
   295  	for _, a := range t.Args {
   296  		if ps.isEmpty(a) {
   297  			continue
   298  		}
   299  		if !first {
   300  			ps.writeString(", ")
   301  		}
   302  		ps.print(a)
   303  		first = false
   304  	}
   305  	if ps.last == '>' {
   306  		// Avoid syntactic ambiguity in old versions of C++.
   307  		ps.writeByte(' ')
   308  	}
   309  	ps.writeByte('>')
   310  }
   311  
   312  func (t *Template) Traverse(fn func(AST) bool) {
   313  	if fn(t) {
   314  		t.Name.Traverse(fn)
   315  		for _, a := range t.Args {
   316  			a.Traverse(fn)
   317  		}
   318  	}
   319  }
   320  
   321  func (t *Template) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   322  	if skip(t) {
   323  		return nil
   324  	}
   325  	name := t.Name.Copy(fn, skip)
   326  	changed := name != nil
   327  	args := make([]AST, len(t.Args))
   328  	for i, a := range t.Args {
   329  		ac := a.Copy(fn, skip)
   330  		if ac == nil {
   331  			args[i] = a
   332  		} else {
   333  			args[i] = ac
   334  			changed = true
   335  		}
   336  	}
   337  	if !changed {
   338  		return fn(t)
   339  	}
   340  	if name == nil {
   341  		name = t.Name
   342  	}
   343  	t = &Template{Name: name, Args: args}
   344  	if r := fn(t); r != nil {
   345  		return r
   346  	}
   347  	return t
   348  }
   349  
   350  func (t *Template) GoString() string {
   351  	return t.goString(0, "")
   352  }
   353  
   354  func (t *Template) goString(indent int, field string) string {
   355  	var args string
   356  	if len(t.Args) == 0 {
   357  		args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
   358  	} else {
   359  		args = fmt.Sprintf("%*sArgs:", indent+2, "")
   360  		for i, a := range t.Args {
   361  			args += "\n"
   362  			args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
   363  		}
   364  	}
   365  	return fmt.Sprintf("%*s%sTemplate (%p):\n%s\n%s", indent, "", field, t,
   366  		t.Name.goString(indent+2, "Name: "), args)
   367  }
   368  
   369  // TemplateParam is a template parameter.  The Template field is
   370  // filled in while parsing the demangled string.  We don't normally
   371  // see these while printing--they are replaced by the simplify
   372  // function.
   373  type TemplateParam struct {
   374  	Index    int
   375  	Template *Template
   376  }
   377  
   378  func (tp *TemplateParam) print(ps *printState) {
   379  	if tp.Template == nil {
   380  		panic("TemplateParam Template field is nil")
   381  	}
   382  	if tp.Index >= len(tp.Template.Args) {
   383  		panic("TemplateParam Index out of bounds")
   384  	}
   385  	ps.print(tp.Template.Args[tp.Index])
   386  }
   387  
   388  func (tp *TemplateParam) Traverse(fn func(AST) bool) {
   389  	fn(tp)
   390  	// Don't traverse Template--it points elsewhere in the AST.
   391  }
   392  
   393  func (tp *TemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   394  	if skip(tp) {
   395  		return nil
   396  	}
   397  	return fn(tp)
   398  }
   399  
   400  func (tp *TemplateParam) GoString() string {
   401  	return tp.goString(0, "")
   402  }
   403  
   404  func (tp *TemplateParam) goString(indent int, field string) string {
   405  	return fmt.Sprintf("%*s%sTemplateParam: Template: %p; Index %d", indent, "", field, tp.Template, tp.Index)
   406  }
   407  
   408  // LambdaAuto is a lambda auto parameter.
   409  type LambdaAuto struct {
   410  	Index int
   411  }
   412  
   413  func (la *LambdaAuto) print(ps *printState) {
   414  	// We print the index plus 1 because that is what the standard
   415  	// demangler does.
   416  	if ps.llvmStyle {
   417  		ps.writeString("auto")
   418  	} else {
   419  		fmt.Fprintf(&ps.buf, "auto:%d", la.Index+1)
   420  	}
   421  }
   422  
   423  func (la *LambdaAuto) Traverse(fn func(AST) bool) {
   424  	fn(la)
   425  }
   426  
   427  func (la *LambdaAuto) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   428  	if skip(la) {
   429  		return nil
   430  	}
   431  	return fn(la)
   432  }
   433  
   434  func (la *LambdaAuto) GoString() string {
   435  	return la.goString(0, "")
   436  }
   437  
   438  func (la *LambdaAuto) goString(indent int, field string) string {
   439  	return fmt.Sprintf("%*s%sLambdaAuto: Index %d", indent, "", field, la.Index)
   440  }
   441  
   442  // Qualifiers is an ordered list of type qualifiers.
   443  type Qualifiers struct {
   444  	Qualifiers []AST
   445  }
   446  
   447  func (qs *Qualifiers) print(ps *printState) {
   448  	first := true
   449  	for _, q := range qs.Qualifiers {
   450  		if !first {
   451  			ps.writeByte(' ')
   452  		}
   453  		q.print(ps)
   454  		first = false
   455  	}
   456  }
   457  
   458  func (qs *Qualifiers) Traverse(fn func(AST) bool) {
   459  	if fn(qs) {
   460  		for _, q := range qs.Qualifiers {
   461  			q.Traverse(fn)
   462  		}
   463  	}
   464  }
   465  
   466  func (qs *Qualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   467  	if skip(qs) {
   468  		return nil
   469  	}
   470  	changed := false
   471  	qualifiers := make([]AST, len(qs.Qualifiers))
   472  	for i, q := range qs.Qualifiers {
   473  		qc := q.Copy(fn, skip)
   474  		if qc == nil {
   475  			qualifiers[i] = q
   476  		} else {
   477  			qualifiers[i] = qc
   478  			changed = true
   479  		}
   480  	}
   481  	if !changed {
   482  		return fn(qs)
   483  	}
   484  	qs = &Qualifiers{Qualifiers: qualifiers}
   485  	if r := fn(qs); r != nil {
   486  		return r
   487  	}
   488  	return qs
   489  }
   490  
   491  func (qs *Qualifiers) GoString() string {
   492  	return qs.goString(0, "")
   493  }
   494  
   495  func (qs *Qualifiers) goString(indent int, field string) string {
   496  	quals := fmt.Sprintf("%*s%s", indent, "", field)
   497  	for _, q := range qs.Qualifiers {
   498  		quals += "\n"
   499  		quals += q.goString(indent+2, "")
   500  	}
   501  	return quals
   502  }
   503  
   504  // Qualifier is a single type qualifier.
   505  type Qualifier struct {
   506  	Name  string // qualifier name: const, volatile, etc.
   507  	Exprs []AST  // can be non-nil for noexcept and throw
   508  }
   509  
   510  func (q *Qualifier) print(ps *printState) {
   511  	ps.writeString(q.Name)
   512  	if len(q.Exprs) > 0 {
   513  		ps.writeByte('(')
   514  		first := true
   515  		for _, e := range q.Exprs {
   516  			if el, ok := e.(*ExprList); ok && len(el.Exprs) == 0 {
   517  				continue
   518  			}
   519  			if !first {
   520  				ps.writeString(", ")
   521  			}
   522  			ps.print(e)
   523  			first = false
   524  		}
   525  		ps.writeByte(')')
   526  	}
   527  }
   528  
   529  func (q *Qualifier) Traverse(fn func(AST) bool) {
   530  	if fn(q) {
   531  		for _, e := range q.Exprs {
   532  			e.Traverse(fn)
   533  		}
   534  	}
   535  }
   536  
   537  func (q *Qualifier) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   538  	if skip(q) {
   539  		return nil
   540  	}
   541  	exprs := make([]AST, len(q.Exprs))
   542  	changed := false
   543  	for i, e := range q.Exprs {
   544  		ec := e.Copy(fn, skip)
   545  		if ec == nil {
   546  			exprs[i] = e
   547  		} else {
   548  			exprs[i] = ec
   549  			changed = true
   550  		}
   551  	}
   552  	if !changed {
   553  		return fn(q)
   554  	}
   555  	q = &Qualifier{Name: q.Name, Exprs: exprs}
   556  	if r := fn(q); r != nil {
   557  		return r
   558  	}
   559  	return q
   560  }
   561  
   562  func (q *Qualifier) GoString() string {
   563  	return q.goString(0, "Qualifier: ")
   564  }
   565  
   566  func (q *Qualifier) goString(indent int, field string) string {
   567  	qs := fmt.Sprintf("%*s%s%s", indent, "", field, q.Name)
   568  	if len(q.Exprs) > 0 {
   569  		for i, e := range q.Exprs {
   570  			qs += "\n"
   571  			qs += e.goString(indent+2, fmt.Sprintf("%d: ", i))
   572  		}
   573  	}
   574  	return qs
   575  }
   576  
   577  // TypeWithQualifiers is a type with standard qualifiers.
   578  type TypeWithQualifiers struct {
   579  	Base       AST
   580  	Qualifiers AST
   581  }
   582  
   583  func (twq *TypeWithQualifiers) print(ps *printState) {
   584  	// Give the base type a chance to print the inner types.
   585  	ps.inner = append(ps.inner, twq)
   586  	ps.print(twq.Base)
   587  	if len(ps.inner) > 0 {
   588  		// The qualifier wasn't printed by Base.
   589  		ps.writeByte(' ')
   590  		ps.print(twq.Qualifiers)
   591  		ps.inner = ps.inner[:len(ps.inner)-1]
   592  	}
   593  }
   594  
   595  // Print qualifiers as an inner type by just printing the qualifiers.
   596  func (twq *TypeWithQualifiers) printInner(ps *printState) {
   597  	ps.writeByte(' ')
   598  	ps.print(twq.Qualifiers)
   599  }
   600  
   601  func (twq *TypeWithQualifiers) Traverse(fn func(AST) bool) {
   602  	if fn(twq) {
   603  		twq.Base.Traverse(fn)
   604  	}
   605  }
   606  
   607  func (twq *TypeWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   608  	if skip(twq) {
   609  		return nil
   610  	}
   611  	base := twq.Base.Copy(fn, skip)
   612  	quals := twq.Qualifiers.Copy(fn, skip)
   613  	if base == nil && quals == nil {
   614  		return fn(twq)
   615  	}
   616  	if base == nil {
   617  		base = twq.Base
   618  	}
   619  	if quals == nil {
   620  		quals = twq.Qualifiers
   621  	}
   622  	twq = &TypeWithQualifiers{Base: base, Qualifiers: quals}
   623  	if r := fn(twq); r != nil {
   624  		return r
   625  	}
   626  	return twq
   627  }
   628  
   629  func (twq *TypeWithQualifiers) GoString() string {
   630  	return twq.goString(0, "")
   631  }
   632  
   633  func (twq *TypeWithQualifiers) goString(indent int, field string) string {
   634  	return fmt.Sprintf("%*s%sTypeWithQualifiers:\n%s\n%s", indent, "", field,
   635  		twq.Qualifiers.goString(indent+2, "Qualifiers: "),
   636  		twq.Base.goString(indent+2, "Base: "))
   637  }
   638  
   639  // MethodWithQualifiers is a method with qualifiers.
   640  type MethodWithQualifiers struct {
   641  	Method       AST
   642  	Qualifiers   AST
   643  	RefQualifier string // "" or "&" or "&&"
   644  }
   645  
   646  func (mwq *MethodWithQualifiers) print(ps *printState) {
   647  	// Give the base type a chance to print the inner types.
   648  	ps.inner = append(ps.inner, mwq)
   649  	ps.print(mwq.Method)
   650  	if len(ps.inner) > 0 {
   651  		if mwq.Qualifiers != nil {
   652  			ps.writeByte(' ')
   653  			ps.print(mwq.Qualifiers)
   654  		}
   655  		if mwq.RefQualifier != "" {
   656  			ps.writeByte(' ')
   657  			ps.writeString(mwq.RefQualifier)
   658  		}
   659  		ps.inner = ps.inner[:len(ps.inner)-1]
   660  	}
   661  }
   662  
   663  func (mwq *MethodWithQualifiers) printInner(ps *printState) {
   664  	if mwq.Qualifiers != nil {
   665  		ps.writeByte(' ')
   666  		ps.print(mwq.Qualifiers)
   667  	}
   668  	if mwq.RefQualifier != "" {
   669  		ps.writeByte(' ')
   670  		ps.writeString(mwq.RefQualifier)
   671  	}
   672  }
   673  
   674  func (mwq *MethodWithQualifiers) Traverse(fn func(AST) bool) {
   675  	if fn(mwq) {
   676  		mwq.Method.Traverse(fn)
   677  	}
   678  }
   679  
   680  func (mwq *MethodWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   681  	if skip(mwq) {
   682  		return nil
   683  	}
   684  	method := mwq.Method.Copy(fn, skip)
   685  	var quals AST
   686  	if mwq.Qualifiers != nil {
   687  		quals = mwq.Qualifiers.Copy(fn, skip)
   688  	}
   689  	if method == nil && quals == nil {
   690  		return fn(mwq)
   691  	}
   692  	if method == nil {
   693  		method = mwq.Method
   694  	}
   695  	if quals == nil {
   696  		quals = mwq.Qualifiers
   697  	}
   698  	mwq = &MethodWithQualifiers{Method: method, Qualifiers: quals, RefQualifier: mwq.RefQualifier}
   699  	if r := fn(mwq); r != nil {
   700  		return r
   701  	}
   702  	return mwq
   703  }
   704  
   705  func (mwq *MethodWithQualifiers) GoString() string {
   706  	return mwq.goString(0, "")
   707  }
   708  
   709  func (mwq *MethodWithQualifiers) goString(indent int, field string) string {
   710  	var q string
   711  	if mwq.Qualifiers != nil {
   712  		q += "\n" + mwq.Qualifiers.goString(indent+2, "Qualifiers: ")
   713  	}
   714  	if mwq.RefQualifier != "" {
   715  		if q != "" {
   716  			q += "\n"
   717  		}
   718  		q += fmt.Sprintf("%*s%s%s", indent+2, "", "RefQualifier: ", mwq.RefQualifier)
   719  	}
   720  	return fmt.Sprintf("%*s%sMethodWithQualifiers:%s\n%s", indent, "", field,
   721  		q, mwq.Method.goString(indent+2, "Method: "))
   722  }
   723  
   724  // BuiltinType is a builtin type, like "int".
   725  type BuiltinType struct {
   726  	Name string
   727  }
   728  
   729  func (bt *BuiltinType) print(ps *printState) {
   730  	name := bt.Name
   731  	if ps.llvmStyle && name == "decltype(nullptr)" {
   732  		name = "std::nullptr_t"
   733  	}
   734  	ps.writeString(name)
   735  }
   736  
   737  func (bt *BuiltinType) Traverse(fn func(AST) bool) {
   738  	fn(bt)
   739  }
   740  
   741  func (bt *BuiltinType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   742  	if skip(bt) {
   743  		return nil
   744  	}
   745  	return fn(bt)
   746  }
   747  
   748  func (bt *BuiltinType) GoString() string {
   749  	return bt.goString(0, "")
   750  }
   751  
   752  func (bt *BuiltinType) goString(indent int, field string) string {
   753  	return fmt.Sprintf("%*s%sBuiltinType: %s", indent, "", field, bt.Name)
   754  }
   755  
   756  // printBase is common print code for types that are printed with a
   757  // simple suffix.
   758  func printBase(ps *printState, qual, base AST) {
   759  	ps.inner = append(ps.inner, qual)
   760  	ps.print(base)
   761  	if len(ps.inner) > 0 {
   762  		qual.(innerPrinter).printInner(ps)
   763  		ps.inner = ps.inner[:len(ps.inner)-1]
   764  	}
   765  }
   766  
   767  // PointerType is a pointer type.
   768  type PointerType struct {
   769  	Base AST
   770  }
   771  
   772  func (pt *PointerType) print(ps *printState) {
   773  	printBase(ps, pt, pt.Base)
   774  }
   775  
   776  func (pt *PointerType) printInner(ps *printState) {
   777  	ps.writeString("*")
   778  }
   779  
   780  func (pt *PointerType) Traverse(fn func(AST) bool) {
   781  	if fn(pt) {
   782  		pt.Base.Traverse(fn)
   783  	}
   784  }
   785  
   786  func (pt *PointerType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   787  	if skip(pt) {
   788  		return nil
   789  	}
   790  	base := pt.Base.Copy(fn, skip)
   791  	if base == nil {
   792  		return fn(pt)
   793  	}
   794  	pt = &PointerType{Base: base}
   795  	if r := fn(pt); r != nil {
   796  		return r
   797  	}
   798  	return pt
   799  }
   800  
   801  func (pt *PointerType) GoString() string {
   802  	return pt.goString(0, "")
   803  }
   804  
   805  func (pt *PointerType) goString(indent int, field string) string {
   806  	return fmt.Sprintf("%*s%sPointerType:\n%s", indent, "", field,
   807  		pt.Base.goString(indent+2, ""))
   808  }
   809  
   810  // ReferenceType is a reference type.
   811  type ReferenceType struct {
   812  	Base AST
   813  }
   814  
   815  func (rt *ReferenceType) print(ps *printState) {
   816  	printBase(ps, rt, rt.Base)
   817  }
   818  
   819  func (rt *ReferenceType) printInner(ps *printState) {
   820  	ps.writeString("&")
   821  }
   822  
   823  func (rt *ReferenceType) Traverse(fn func(AST) bool) {
   824  	if fn(rt) {
   825  		rt.Base.Traverse(fn)
   826  	}
   827  }
   828  
   829  func (rt *ReferenceType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   830  	if skip(rt) {
   831  		return nil
   832  	}
   833  	base := rt.Base.Copy(fn, skip)
   834  	if base == nil {
   835  		return fn(rt)
   836  	}
   837  	rt = &ReferenceType{Base: base}
   838  	if r := fn(rt); r != nil {
   839  		return r
   840  	}
   841  	return rt
   842  }
   843  
   844  func (rt *ReferenceType) GoString() string {
   845  	return rt.goString(0, "")
   846  }
   847  
   848  func (rt *ReferenceType) goString(indent int, field string) string {
   849  	return fmt.Sprintf("%*s%sReferenceType:\n%s", indent, "", field,
   850  		rt.Base.goString(indent+2, ""))
   851  }
   852  
   853  // RvalueReferenceType is an rvalue reference type.
   854  type RvalueReferenceType struct {
   855  	Base AST
   856  }
   857  
   858  func (rt *RvalueReferenceType) print(ps *printState) {
   859  	printBase(ps, rt, rt.Base)
   860  }
   861  
   862  func (rt *RvalueReferenceType) printInner(ps *printState) {
   863  	ps.writeString("&&")
   864  }
   865  
   866  func (rt *RvalueReferenceType) Traverse(fn func(AST) bool) {
   867  	if fn(rt) {
   868  		rt.Base.Traverse(fn)
   869  	}
   870  }
   871  
   872  func (rt *RvalueReferenceType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   873  	if skip(rt) {
   874  		return nil
   875  	}
   876  	base := rt.Base.Copy(fn, skip)
   877  	if base == nil {
   878  		return fn(rt)
   879  	}
   880  	rt = &RvalueReferenceType{Base: base}
   881  	if r := fn(rt); r != nil {
   882  		return r
   883  	}
   884  	return rt
   885  }
   886  
   887  func (rt *RvalueReferenceType) GoString() string {
   888  	return rt.goString(0, "")
   889  }
   890  
   891  func (rt *RvalueReferenceType) goString(indent int, field string) string {
   892  	return fmt.Sprintf("%*s%sRvalueReferenceType:\n%s", indent, "", field,
   893  		rt.Base.goString(indent+2, ""))
   894  }
   895  
   896  // ComplexType is a complex type.
   897  type ComplexType struct {
   898  	Base AST
   899  }
   900  
   901  func (ct *ComplexType) print(ps *printState) {
   902  	printBase(ps, ct, ct.Base)
   903  }
   904  
   905  func (ct *ComplexType) printInner(ps *printState) {
   906  	ps.writeString(" _Complex")
   907  }
   908  
   909  func (ct *ComplexType) Traverse(fn func(AST) bool) {
   910  	if fn(ct) {
   911  		ct.Base.Traverse(fn)
   912  	}
   913  }
   914  
   915  func (ct *ComplexType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   916  	if skip(ct) {
   917  		return nil
   918  	}
   919  	base := ct.Base.Copy(fn, skip)
   920  	if base == nil {
   921  		return fn(ct)
   922  	}
   923  	ct = &ComplexType{Base: base}
   924  	if r := fn(ct); r != nil {
   925  		return r
   926  	}
   927  	return ct
   928  }
   929  
   930  func (ct *ComplexType) GoString() string {
   931  	return ct.goString(0, "")
   932  }
   933  
   934  func (ct *ComplexType) goString(indent int, field string) string {
   935  	return fmt.Sprintf("%*s%sComplexType:\n%s", indent, "", field,
   936  		ct.Base.goString(indent+2, ""))
   937  }
   938  
   939  // ImaginaryType is an imaginary type.
   940  type ImaginaryType struct {
   941  	Base AST
   942  }
   943  
   944  func (it *ImaginaryType) print(ps *printState) {
   945  	printBase(ps, it, it.Base)
   946  }
   947  
   948  func (it *ImaginaryType) printInner(ps *printState) {
   949  	ps.writeString(" _Imaginary")
   950  }
   951  
   952  func (it *ImaginaryType) Traverse(fn func(AST) bool) {
   953  	if fn(it) {
   954  		it.Base.Traverse(fn)
   955  	}
   956  }
   957  
   958  func (it *ImaginaryType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
   959  	if skip(it) {
   960  		return nil
   961  	}
   962  	base := it.Base.Copy(fn, skip)
   963  	if base == nil {
   964  		return fn(it)
   965  	}
   966  	it = &ImaginaryType{Base: base}
   967  	if r := fn(it); r != nil {
   968  		return r
   969  	}
   970  	return it
   971  }
   972  
   973  func (it *ImaginaryType) GoString() string {
   974  	return it.goString(0, "")
   975  }
   976  
   977  func (it *ImaginaryType) goString(indent int, field string) string {
   978  	return fmt.Sprintf("%*s%sImaginaryType:\n%s", indent, "", field,
   979  		it.Base.goString(indent+2, ""))
   980  }
   981  
   982  // VendorQualifier is a type qualified by a vendor-specific qualifier.
   983  type VendorQualifier struct {
   984  	Qualifier AST
   985  	Type      AST
   986  }
   987  
   988  func (vq *VendorQualifier) print(ps *printState) {
   989  	if ps.llvmStyle {
   990  		ps.print(vq.Type)
   991  		vq.printInner(ps)
   992  	} else {
   993  		ps.inner = append(ps.inner, vq)
   994  		ps.print(vq.Type)
   995  		if len(ps.inner) > 0 {
   996  			ps.printOneInner(nil)
   997  		}
   998  	}
   999  }
  1000  
  1001  func (vq *VendorQualifier) printInner(ps *printState) {
  1002  	ps.writeByte(' ')
  1003  	ps.print(vq.Qualifier)
  1004  }
  1005  
  1006  func (vq *VendorQualifier) Traverse(fn func(AST) bool) {
  1007  	if fn(vq) {
  1008  		vq.Qualifier.Traverse(fn)
  1009  		vq.Type.Traverse(fn)
  1010  	}
  1011  }
  1012  
  1013  func (vq *VendorQualifier) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1014  	if skip(vq) {
  1015  		return nil
  1016  	}
  1017  	qualifier := vq.Qualifier.Copy(fn, skip)
  1018  	typ := vq.Type.Copy(fn, skip)
  1019  	if qualifier == nil && typ == nil {
  1020  		return fn(vq)
  1021  	}
  1022  	if qualifier == nil {
  1023  		qualifier = vq.Qualifier
  1024  	}
  1025  	if typ == nil {
  1026  		typ = vq.Type
  1027  	}
  1028  	vq = &VendorQualifier{Qualifier: qualifier, Type: vq.Type}
  1029  	if r := fn(vq); r != nil {
  1030  		return r
  1031  	}
  1032  	return vq
  1033  }
  1034  
  1035  func (vq *VendorQualifier) GoString() string {
  1036  	return vq.goString(0, "")
  1037  }
  1038  
  1039  func (vq *VendorQualifier) goString(indent int, field string) string {
  1040  	return fmt.Sprintf("%*s%sVendorQualifier:\n%s\n%s", indent, "", field,
  1041  		vq.Qualifier.goString(indent+2, "Qualifier: "),
  1042  		vq.Type.goString(indent+2, "Type: "))
  1043  }
  1044  
  1045  // ArrayType is an array type.
  1046  type ArrayType struct {
  1047  	Dimension AST
  1048  	Element   AST
  1049  }
  1050  
  1051  func (at *ArrayType) print(ps *printState) {
  1052  	// Pass the array type down as an inner type so that we print
  1053  	// multi-dimensional arrays correctly.
  1054  	ps.inner = append(ps.inner, at)
  1055  	ps.print(at.Element)
  1056  	if ln := len(ps.inner); ln > 0 {
  1057  		ps.inner = ps.inner[:ln-1]
  1058  		at.printDimension(ps)
  1059  	}
  1060  }
  1061  
  1062  func (at *ArrayType) printInner(ps *printState) {
  1063  	at.printDimension(ps)
  1064  }
  1065  
  1066  // Print the array dimension.
  1067  func (at *ArrayType) printDimension(ps *printState) {
  1068  	space := " "
  1069  	for len(ps.inner) > 0 {
  1070  		// We haven't gotten to the real type yet.  Use
  1071  		// parentheses around that type, except that if it is
  1072  		// an array type we print it as a multi-dimensional
  1073  		// array
  1074  		in := ps.inner[len(ps.inner)-1]
  1075  		if twq, ok := in.(*TypeWithQualifiers); ok {
  1076  			in = twq.Base
  1077  		}
  1078  		if _, ok := in.(*ArrayType); ok {
  1079  			if in == ps.inner[len(ps.inner)-1] {
  1080  				space = ""
  1081  			}
  1082  			ps.printOneInner(nil)
  1083  		} else {
  1084  			ps.writeString(" (")
  1085  			ps.printInner(false)
  1086  			ps.writeByte(')')
  1087  		}
  1088  	}
  1089  	ps.writeString(space)
  1090  	ps.writeByte('[')
  1091  	ps.print(at.Dimension)
  1092  	ps.writeByte(']')
  1093  }
  1094  
  1095  func (at *ArrayType) Traverse(fn func(AST) bool) {
  1096  	if fn(at) {
  1097  		at.Dimension.Traverse(fn)
  1098  		at.Element.Traverse(fn)
  1099  	}
  1100  }
  1101  
  1102  func (at *ArrayType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1103  	if skip(at) {
  1104  		return nil
  1105  	}
  1106  	dimension := at.Dimension.Copy(fn, skip)
  1107  	element := at.Element.Copy(fn, skip)
  1108  	if dimension == nil && element == nil {
  1109  		return fn(at)
  1110  	}
  1111  	if dimension == nil {
  1112  		dimension = at.Dimension
  1113  	}
  1114  	if element == nil {
  1115  		element = at.Element
  1116  	}
  1117  	at = &ArrayType{Dimension: dimension, Element: element}
  1118  	if r := fn(at); r != nil {
  1119  		return r
  1120  	}
  1121  	return at
  1122  }
  1123  
  1124  func (at *ArrayType) GoString() string {
  1125  	return at.goString(0, "")
  1126  }
  1127  
  1128  func (at *ArrayType) goString(indent int, field string) string {
  1129  	return fmt.Sprintf("%*s%sArrayType:\n%s\n%s", indent, "", field,
  1130  		at.Dimension.goString(indent+2, "Dimension: "),
  1131  		at.Element.goString(indent+2, "Element: "))
  1132  }
  1133  
  1134  // FunctionType is a function type.
  1135  type FunctionType struct {
  1136  	Return AST
  1137  	Args   []AST
  1138  
  1139  	// The forLocalName field reports whether this FunctionType
  1140  	// was created for a local name. With the default GNU demangling
  1141  	// output we don't print the return type in that case.
  1142  	ForLocalName bool
  1143  }
  1144  
  1145  func (ft *FunctionType) print(ps *printState) {
  1146  	retType := ft.Return
  1147  	if ft.ForLocalName && !ps.llvmStyle {
  1148  		retType = nil
  1149  	}
  1150  	if retType != nil {
  1151  		// Pass the return type as an inner type in order to
  1152  		// print the arguments in the right location.
  1153  		ps.inner = append(ps.inner, ft)
  1154  		ps.print(retType)
  1155  		if len(ps.inner) == 0 {
  1156  			// Everything was printed.
  1157  			return
  1158  		}
  1159  		ps.inner = ps.inner[:len(ps.inner)-1]
  1160  		ps.writeByte(' ')
  1161  	}
  1162  	ft.printArgs(ps)
  1163  }
  1164  
  1165  func (ft *FunctionType) printInner(ps *printState) {
  1166  	ft.printArgs(ps)
  1167  }
  1168  
  1169  // printArgs prints the arguments of a function type.  It looks at the
  1170  // inner types for spacing.
  1171  func (ft *FunctionType) printArgs(ps *printState) {
  1172  	paren := false
  1173  	space := false
  1174  	for i := len(ps.inner) - 1; i >= 0; i-- {
  1175  		switch ps.inner[i].(type) {
  1176  		case *PointerType, *ReferenceType, *RvalueReferenceType:
  1177  			paren = true
  1178  		case *TypeWithQualifiers, *ComplexType, *ImaginaryType, *PtrMem:
  1179  			space = true
  1180  			paren = true
  1181  		}
  1182  		if paren {
  1183  			break
  1184  		}
  1185  	}
  1186  
  1187  	if paren {
  1188  		if !space && (ps.last != '(' && ps.last != '*') {
  1189  			space = true
  1190  		}
  1191  		if space && ps.last != ' ' {
  1192  			ps.writeByte(' ')
  1193  		}
  1194  		ps.writeByte('(')
  1195  	}
  1196  
  1197  	save := ps.printInner(true)
  1198  
  1199  	if paren {
  1200  		ps.writeByte(')')
  1201  	}
  1202  
  1203  	ps.writeByte('(')
  1204  	first := true
  1205  	for _, a := range ft.Args {
  1206  		if ps.isEmpty(a) {
  1207  			continue
  1208  		}
  1209  		if !first {
  1210  			ps.writeString(", ")
  1211  		}
  1212  		ps.print(a)
  1213  		first = false
  1214  	}
  1215  	ps.writeByte(')')
  1216  
  1217  	ps.inner = save
  1218  	ps.printInner(false)
  1219  }
  1220  
  1221  func (ft *FunctionType) Traverse(fn func(AST) bool) {
  1222  	if fn(ft) {
  1223  		if ft.Return != nil {
  1224  			ft.Return.Traverse(fn)
  1225  		}
  1226  		for _, a := range ft.Args {
  1227  			a.Traverse(fn)
  1228  		}
  1229  	}
  1230  }
  1231  
  1232  func (ft *FunctionType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1233  	if skip(ft) {
  1234  		return nil
  1235  	}
  1236  	changed := false
  1237  	var ret AST
  1238  	if ft.Return != nil {
  1239  		ret = ft.Return.Copy(fn, skip)
  1240  		if ret == nil {
  1241  			ret = ft.Return
  1242  		} else {
  1243  			changed = true
  1244  		}
  1245  	}
  1246  	args := make([]AST, len(ft.Args))
  1247  	for i, a := range ft.Args {
  1248  		ac := a.Copy(fn, skip)
  1249  		if ac == nil {
  1250  			args[i] = a
  1251  		} else {
  1252  			args[i] = ac
  1253  			changed = true
  1254  		}
  1255  	}
  1256  	if !changed {
  1257  		return fn(ft)
  1258  	}
  1259  	ft = &FunctionType{
  1260  		Return:       ret,
  1261  		Args:         args,
  1262  		ForLocalName: ft.ForLocalName,
  1263  	}
  1264  	if r := fn(ft); r != nil {
  1265  		return r
  1266  	}
  1267  	return ft
  1268  }
  1269  
  1270  func (ft *FunctionType) GoString() string {
  1271  	return ft.goString(0, "")
  1272  }
  1273  
  1274  func (ft *FunctionType) goString(indent int, field string) string {
  1275  	var forLocalName string
  1276  	if ft.ForLocalName {
  1277  		forLocalName = " ForLocalName: true"
  1278  	}
  1279  	var r string
  1280  	if ft.Return == nil {
  1281  		r = fmt.Sprintf("%*sReturn: nil", indent+2, "")
  1282  	} else {
  1283  		r = ft.Return.goString(indent+2, "Return: ")
  1284  	}
  1285  	var args string
  1286  	if len(ft.Args) == 0 {
  1287  		args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
  1288  	} else {
  1289  		args = fmt.Sprintf("%*sArgs:", indent+2, "")
  1290  		for i, a := range ft.Args {
  1291  			args += "\n"
  1292  			args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
  1293  		}
  1294  	}
  1295  	return fmt.Sprintf("%*s%sFunctionType:%s\n%s\n%s", indent, "", field,
  1296  		forLocalName, r, args)
  1297  }
  1298  
  1299  // FunctionParam is a parameter of a function, used for last-specified
  1300  // return type in a closure.
  1301  type FunctionParam struct {
  1302  	Index int
  1303  }
  1304  
  1305  func (fp *FunctionParam) print(ps *printState) {
  1306  	if fp.Index == 0 {
  1307  		ps.writeString("this")
  1308  	} else if ps.llvmStyle {
  1309  		if fp.Index == 1 {
  1310  			ps.writeString("fp")
  1311  		} else {
  1312  			fmt.Fprintf(&ps.buf, "fp%d", fp.Index-2)
  1313  		}
  1314  	} else {
  1315  		fmt.Fprintf(&ps.buf, "{parm#%d}", fp.Index)
  1316  	}
  1317  }
  1318  
  1319  func (fp *FunctionParam) Traverse(fn func(AST) bool) {
  1320  	fn(fp)
  1321  }
  1322  
  1323  func (fp *FunctionParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1324  	if skip(fp) {
  1325  		return nil
  1326  	}
  1327  	return fn(fp)
  1328  }
  1329  
  1330  func (fp *FunctionParam) GoString() string {
  1331  	return fp.goString(0, "")
  1332  }
  1333  
  1334  func (fp *FunctionParam) goString(indent int, field string) string {
  1335  	return fmt.Sprintf("%*s%sFunctionParam: %d", indent, "", field, fp.Index)
  1336  }
  1337  
  1338  // PtrMem is a pointer-to-member expression.
  1339  type PtrMem struct {
  1340  	Class  AST
  1341  	Member AST
  1342  }
  1343  
  1344  func (pm *PtrMem) print(ps *printState) {
  1345  	ps.inner = append(ps.inner, pm)
  1346  	ps.print(pm.Member)
  1347  	if len(ps.inner) > 0 {
  1348  		ps.printOneInner(nil)
  1349  	}
  1350  }
  1351  
  1352  func (pm *PtrMem) printInner(ps *printState) {
  1353  	if ps.last != '(' {
  1354  		ps.writeByte(' ')
  1355  	}
  1356  	ps.print(pm.Class)
  1357  	ps.writeString("::*")
  1358  }
  1359  
  1360  func (pm *PtrMem) Traverse(fn func(AST) bool) {
  1361  	if fn(pm) {
  1362  		pm.Class.Traverse(fn)
  1363  		pm.Member.Traverse(fn)
  1364  	}
  1365  }
  1366  
  1367  func (pm *PtrMem) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1368  	if skip(pm) {
  1369  		return nil
  1370  	}
  1371  	class := pm.Class.Copy(fn, skip)
  1372  	member := pm.Member.Copy(fn, skip)
  1373  	if class == nil && member == nil {
  1374  		return fn(pm)
  1375  	}
  1376  	if class == nil {
  1377  		class = pm.Class
  1378  	}
  1379  	if member == nil {
  1380  		member = pm.Member
  1381  	}
  1382  	pm = &PtrMem{Class: class, Member: member}
  1383  	if r := fn(pm); r != nil {
  1384  		return r
  1385  	}
  1386  	return pm
  1387  }
  1388  
  1389  func (pm *PtrMem) GoString() string {
  1390  	return pm.goString(0, "")
  1391  }
  1392  
  1393  func (pm *PtrMem) goString(indent int, field string) string {
  1394  	return fmt.Sprintf("%*s%sPtrMem:\n%s\n%s", indent, "", field,
  1395  		pm.Class.goString(indent+2, "Class: "),
  1396  		pm.Member.goString(indent+2, "Member: "))
  1397  }
  1398  
  1399  // FixedType is a fixed numeric type of unknown size.
  1400  type FixedType struct {
  1401  	Base  AST
  1402  	Accum bool
  1403  	Sat   bool
  1404  }
  1405  
  1406  func (ft *FixedType) print(ps *printState) {
  1407  	if ft.Sat {
  1408  		ps.writeString("_Sat ")
  1409  	}
  1410  	if bt, ok := ft.Base.(*BuiltinType); ok && bt.Name == "int" {
  1411  		// The standard demangler skips printing "int".
  1412  	} else {
  1413  		ps.print(ft.Base)
  1414  		ps.writeByte(' ')
  1415  	}
  1416  	if ft.Accum {
  1417  		ps.writeString("_Accum")
  1418  	} else {
  1419  		ps.writeString("_Fract")
  1420  	}
  1421  }
  1422  
  1423  func (ft *FixedType) Traverse(fn func(AST) bool) {
  1424  	if fn(ft) {
  1425  		ft.Base.Traverse(fn)
  1426  	}
  1427  }
  1428  
  1429  func (ft *FixedType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1430  	if skip(ft) {
  1431  		return nil
  1432  	}
  1433  	base := ft.Base.Copy(fn, skip)
  1434  	if base == nil {
  1435  		return fn(ft)
  1436  	}
  1437  	ft = &FixedType{Base: base, Accum: ft.Accum, Sat: ft.Sat}
  1438  	if r := fn(ft); r != nil {
  1439  		return r
  1440  	}
  1441  	return ft
  1442  }
  1443  
  1444  func (ft *FixedType) GoString() string {
  1445  	return ft.goString(0, "")
  1446  }
  1447  
  1448  func (ft *FixedType) goString(indent int, field string) string {
  1449  	return fmt.Sprintf("%*s%sFixedType: Accum: %t; Sat: %t\n%s", indent, "", field,
  1450  		ft.Accum, ft.Sat,
  1451  		ft.Base.goString(indent+2, "Base: "))
  1452  }
  1453  
  1454  // VectorType is a vector type.
  1455  type VectorType struct {
  1456  	Dimension AST
  1457  	Base      AST
  1458  }
  1459  
  1460  func (vt *VectorType) print(ps *printState) {
  1461  	ps.inner = append(ps.inner, vt)
  1462  	ps.print(vt.Base)
  1463  	if len(ps.inner) > 0 {
  1464  		ps.printOneInner(nil)
  1465  	}
  1466  }
  1467  
  1468  func (vt *VectorType) printInner(ps *printState) {
  1469  	end := byte(')')
  1470  	if ps.llvmStyle {
  1471  		ps.writeString(" vector[")
  1472  		end = ']'
  1473  	} else {
  1474  		ps.writeString(" __vector(")
  1475  	}
  1476  	ps.print(vt.Dimension)
  1477  	ps.writeByte(end)
  1478  }
  1479  
  1480  func (vt *VectorType) Traverse(fn func(AST) bool) {
  1481  	if fn(vt) {
  1482  		vt.Dimension.Traverse(fn)
  1483  		vt.Base.Traverse(fn)
  1484  	}
  1485  }
  1486  
  1487  func (vt *VectorType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1488  	if skip(vt) {
  1489  		return nil
  1490  	}
  1491  	dimension := vt.Dimension.Copy(fn, skip)
  1492  	base := vt.Base.Copy(fn, skip)
  1493  	if dimension == nil && base == nil {
  1494  		return fn(vt)
  1495  	}
  1496  	if dimension == nil {
  1497  		dimension = vt.Dimension
  1498  	}
  1499  	if base == nil {
  1500  		base = vt.Base
  1501  	}
  1502  	vt = &VectorType{Dimension: dimension, Base: base}
  1503  	if r := fn(vt); r != nil {
  1504  		return r
  1505  	}
  1506  	return vt
  1507  }
  1508  
  1509  func (vt *VectorType) GoString() string {
  1510  	return vt.goString(0, "")
  1511  }
  1512  
  1513  func (vt *VectorType) goString(indent int, field string) string {
  1514  	return fmt.Sprintf("%*s%sVectorType:\n%s\n%s", indent, "", field,
  1515  		vt.Dimension.goString(indent+2, "Dimension: "),
  1516  		vt.Base.goString(indent+2, "Base: "))
  1517  }
  1518  
  1519  // ElaboratedType is an elaborated struct/union/enum type.
  1520  type ElaboratedType struct {
  1521  	Kind string
  1522  	Type AST
  1523  }
  1524  
  1525  func (et *ElaboratedType) print(ps *printState) {
  1526  	ps.writeString(et.Kind)
  1527  	ps.writeString(" ")
  1528  	et.Type.print(ps)
  1529  }
  1530  
  1531  func (et *ElaboratedType) Traverse(fn func(AST) bool) {
  1532  	if fn(et) {
  1533  		et.Type.Traverse(fn)
  1534  	}
  1535  }
  1536  
  1537  func (et *ElaboratedType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1538  	if skip(et) {
  1539  		return nil
  1540  	}
  1541  	typ := et.Type.Copy(fn, skip)
  1542  	if typ == nil {
  1543  		return fn(et)
  1544  	}
  1545  	et = &ElaboratedType{Kind: et.Kind, Type: typ}
  1546  	if r := fn(et); r != nil {
  1547  		return r
  1548  	}
  1549  	return et
  1550  }
  1551  
  1552  func (et *ElaboratedType) GoString() string {
  1553  	return et.goString(0, "")
  1554  }
  1555  
  1556  func (et *ElaboratedType) goString(indent int, field string) string {
  1557  	return fmt.Sprintf("%*s%sElaboratedtype: Kind: %s\n%s", indent, "", field,
  1558  		et.Kind, et.Type.goString(indent+2, "Expr: "))
  1559  }
  1560  
  1561  // Decltype is the decltype operator.
  1562  type Decltype struct {
  1563  	Expr AST
  1564  }
  1565  
  1566  func (dt *Decltype) print(ps *printState) {
  1567  	ps.writeString("decltype")
  1568  	if !ps.llvmStyle {
  1569  		ps.writeString(" ")
  1570  	}
  1571  	ps.writeString("(")
  1572  	ps.print(dt.Expr)
  1573  	ps.writeByte(')')
  1574  }
  1575  
  1576  func (dt *Decltype) Traverse(fn func(AST) bool) {
  1577  	if fn(dt) {
  1578  		dt.Expr.Traverse(fn)
  1579  	}
  1580  }
  1581  
  1582  func (dt *Decltype) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1583  	if skip(dt) {
  1584  		return nil
  1585  	}
  1586  	expr := dt.Expr.Copy(fn, skip)
  1587  	if expr == nil {
  1588  		return fn(dt)
  1589  	}
  1590  	dt = &Decltype{Expr: expr}
  1591  	if r := fn(dt); r != nil {
  1592  		return r
  1593  	}
  1594  	return dt
  1595  }
  1596  
  1597  func (dt *Decltype) GoString() string {
  1598  	return dt.goString(0, "")
  1599  }
  1600  
  1601  func (dt *Decltype) goString(indent int, field string) string {
  1602  	return fmt.Sprintf("%*s%sDecltype:\n%s", indent, "", field,
  1603  		dt.Expr.goString(indent+2, "Expr: "))
  1604  }
  1605  
  1606  // Operator is an operator.
  1607  type Operator struct {
  1608  	Name string
  1609  }
  1610  
  1611  func (op *Operator) print(ps *printState) {
  1612  	ps.writeString("operator")
  1613  	if isLower(op.Name[0]) {
  1614  		ps.writeByte(' ')
  1615  	}
  1616  	n := op.Name
  1617  	n = strings.TrimSuffix(n, " ")
  1618  	ps.writeString(n)
  1619  }
  1620  
  1621  func (op *Operator) Traverse(fn func(AST) bool) {
  1622  	fn(op)
  1623  }
  1624  
  1625  func (op *Operator) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1626  	if skip(op) {
  1627  		return nil
  1628  	}
  1629  	return fn(op)
  1630  }
  1631  
  1632  func (op *Operator) GoString() string {
  1633  	return op.goString(0, "")
  1634  }
  1635  
  1636  func (op *Operator) goString(indent int, field string) string {
  1637  	return fmt.Sprintf("%*s%sOperator: %s", indent, "", field, op.Name)
  1638  }
  1639  
  1640  // Constructor is a constructor.
  1641  type Constructor struct {
  1642  	Name AST
  1643  	Base AST // base class of inheriting constructor
  1644  }
  1645  
  1646  func (c *Constructor) print(ps *printState) {
  1647  	ps.print(c.Name)
  1648  	// We don't include the base class in the demangled string.
  1649  }
  1650  
  1651  func (c *Constructor) Traverse(fn func(AST) bool) {
  1652  	if fn(c) {
  1653  		c.Name.Traverse(fn)
  1654  		if c.Base != nil {
  1655  			c.Base.Traverse(fn)
  1656  		}
  1657  	}
  1658  }
  1659  
  1660  func (c *Constructor) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1661  	if skip(c) {
  1662  		return nil
  1663  	}
  1664  	name := c.Name.Copy(fn, skip)
  1665  	var base AST
  1666  	if c.Base != nil {
  1667  		base = c.Base.Copy(fn, skip)
  1668  	}
  1669  	if name == nil && base == nil {
  1670  		return fn(c)
  1671  	}
  1672  	if name == nil {
  1673  		name = c.Name
  1674  	}
  1675  	if base == nil {
  1676  		base = c.Base
  1677  	}
  1678  	c = &Constructor{Name: name, Base: base}
  1679  	if r := fn(c); r != nil {
  1680  		return r
  1681  	}
  1682  	return c
  1683  }
  1684  
  1685  func (c *Constructor) GoString() string {
  1686  	return c.goString(0, "")
  1687  }
  1688  
  1689  func (c *Constructor) goString(indent int, field string) string {
  1690  	var sb strings.Builder
  1691  	fmt.Fprintf(&sb, "%*s%sConstructor:\n", indent, "", field)
  1692  	if c.Base != nil {
  1693  		fmt.Fprintf(&sb, "%s\n", c.Base.goString(indent+2, "Base: "))
  1694  	}
  1695  	fmt.Fprintf(&sb, "%s", c.Name.goString(indent+2, "Name: "))
  1696  	return sb.String()
  1697  }
  1698  
  1699  // Destructor is a destructor.
  1700  type Destructor struct {
  1701  	Name AST
  1702  }
  1703  
  1704  func (d *Destructor) print(ps *printState) {
  1705  	ps.writeByte('~')
  1706  	ps.print(d.Name)
  1707  }
  1708  
  1709  func (d *Destructor) Traverse(fn func(AST) bool) {
  1710  	if fn(d) {
  1711  		d.Name.Traverse(fn)
  1712  	}
  1713  }
  1714  
  1715  func (d *Destructor) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1716  	if skip(d) {
  1717  		return nil
  1718  	}
  1719  	name := d.Name.Copy(fn, skip)
  1720  	if name == nil {
  1721  		return fn(d)
  1722  	}
  1723  	d = &Destructor{Name: name}
  1724  	if r := fn(d); r != nil {
  1725  		return r
  1726  	}
  1727  	return d
  1728  }
  1729  
  1730  func (d *Destructor) GoString() string {
  1731  	return d.goString(0, "")
  1732  }
  1733  
  1734  func (d *Destructor) goString(indent int, field string) string {
  1735  	return fmt.Sprintf("%*s%sDestructor:\n%s", indent, "", field, d.Name.goString(indent+2, "Name: "))
  1736  }
  1737  
  1738  // GlobalCDtor is a global constructor or destructor.
  1739  type GlobalCDtor struct {
  1740  	Ctor bool
  1741  	Key  AST
  1742  }
  1743  
  1744  func (gcd *GlobalCDtor) print(ps *printState) {
  1745  	ps.writeString("global ")
  1746  	if gcd.Ctor {
  1747  		ps.writeString("constructors")
  1748  	} else {
  1749  		ps.writeString("destructors")
  1750  	}
  1751  	ps.writeString(" keyed to ")
  1752  	ps.print(gcd.Key)
  1753  }
  1754  
  1755  func (gcd *GlobalCDtor) Traverse(fn func(AST) bool) {
  1756  	if fn(gcd) {
  1757  		gcd.Key.Traverse(fn)
  1758  	}
  1759  }
  1760  
  1761  func (gcd *GlobalCDtor) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1762  	if skip(gcd) {
  1763  		return nil
  1764  	}
  1765  	key := gcd.Key.Copy(fn, skip)
  1766  	if key == nil {
  1767  		return fn(gcd)
  1768  	}
  1769  	gcd = &GlobalCDtor{Ctor: gcd.Ctor, Key: key}
  1770  	if r := fn(gcd); r != nil {
  1771  		return r
  1772  	}
  1773  	return gcd
  1774  }
  1775  
  1776  func (gcd *GlobalCDtor) GoString() string {
  1777  	return gcd.goString(0, "")
  1778  }
  1779  
  1780  func (gcd *GlobalCDtor) goString(indent int, field string) string {
  1781  	return fmt.Sprintf("%*s%sGlobalCDtor: Ctor: %t\n%s", indent, "", field,
  1782  		gcd.Ctor, gcd.Key.goString(indent+2, "Key: "))
  1783  }
  1784  
  1785  // TaggedName is a name with an ABI tag.
  1786  type TaggedName struct {
  1787  	Name AST
  1788  	Tag  AST
  1789  }
  1790  
  1791  func (t *TaggedName) print(ps *printState) {
  1792  	ps.print(t.Name)
  1793  	ps.writeString("[abi:")
  1794  	ps.print(t.Tag)
  1795  	ps.writeByte(']')
  1796  }
  1797  
  1798  func (t *TaggedName) Traverse(fn func(AST) bool) {
  1799  	if fn(t) {
  1800  		t.Name.Traverse(fn)
  1801  		t.Tag.Traverse(fn)
  1802  	}
  1803  }
  1804  
  1805  func (t *TaggedName) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1806  	if skip(t) {
  1807  		return nil
  1808  	}
  1809  	name := t.Name.Copy(fn, skip)
  1810  	tag := t.Tag.Copy(fn, skip)
  1811  	if name == nil && tag == nil {
  1812  		return fn(t)
  1813  	}
  1814  	if name == nil {
  1815  		name = t.Name
  1816  	}
  1817  	if tag == nil {
  1818  		tag = t.Tag
  1819  	}
  1820  	t = &TaggedName{Name: name, Tag: tag}
  1821  	if r := fn(t); r != nil {
  1822  		return r
  1823  	}
  1824  	return t
  1825  }
  1826  
  1827  func (t *TaggedName) GoString() string {
  1828  	return t.goString(0, "")
  1829  }
  1830  
  1831  func (t *TaggedName) goString(indent int, field string) string {
  1832  	return fmt.Sprintf("%*s%sTaggedName:\n%s\n%s", indent, "", field,
  1833  		t.Name.goString(indent+2, "Name: "),
  1834  		t.Tag.goString(indent+2, "Tag: "))
  1835  }
  1836  
  1837  // PackExpansion is a pack expansion.  The Pack field may be nil.
  1838  type PackExpansion struct {
  1839  	Base AST
  1840  	Pack *ArgumentPack
  1841  }
  1842  
  1843  func (pe *PackExpansion) print(ps *printState) {
  1844  	// We normally only get here if the simplify function was
  1845  	// unable to locate and expand the pack.
  1846  	if pe.Pack == nil {
  1847  		if ps.llvmStyle {
  1848  			ps.print(pe.Base)
  1849  		} else {
  1850  			parenthesize(ps, pe.Base)
  1851  			ps.writeString("...")
  1852  		}
  1853  	} else {
  1854  		ps.print(pe.Base)
  1855  	}
  1856  }
  1857  
  1858  func (pe *PackExpansion) Traverse(fn func(AST) bool) {
  1859  	if fn(pe) {
  1860  		pe.Base.Traverse(fn)
  1861  		// Don't traverse Template--it points elsewhere in the AST.
  1862  	}
  1863  }
  1864  
  1865  func (pe *PackExpansion) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1866  	if skip(pe) {
  1867  		return nil
  1868  	}
  1869  	base := pe.Base.Copy(fn, skip)
  1870  	if base == nil {
  1871  		return fn(pe)
  1872  	}
  1873  	pe = &PackExpansion{Base: base, Pack: pe.Pack}
  1874  	if r := fn(pe); r != nil {
  1875  		return r
  1876  	}
  1877  	return pe
  1878  }
  1879  
  1880  func (pe *PackExpansion) GoString() string {
  1881  	return pe.goString(0, "")
  1882  }
  1883  
  1884  func (pe *PackExpansion) goString(indent int, field string) string {
  1885  	return fmt.Sprintf("%*s%sPackExpansion: Pack: %p\n%s", indent, "", field,
  1886  		pe.Pack, pe.Base.goString(indent+2, "Base: "))
  1887  }
  1888  
  1889  // ArgumentPack is an argument pack.
  1890  type ArgumentPack struct {
  1891  	Args []AST
  1892  }
  1893  
  1894  func (ap *ArgumentPack) print(ps *printState) {
  1895  	for i, a := range ap.Args {
  1896  		if i > 0 {
  1897  			ps.writeString(", ")
  1898  		}
  1899  		ps.print(a)
  1900  	}
  1901  }
  1902  
  1903  func (ap *ArgumentPack) Traverse(fn func(AST) bool) {
  1904  	if fn(ap) {
  1905  		for _, a := range ap.Args {
  1906  			a.Traverse(fn)
  1907  		}
  1908  	}
  1909  }
  1910  
  1911  func (ap *ArgumentPack) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1912  	if skip(ap) {
  1913  		return nil
  1914  	}
  1915  	args := make([]AST, len(ap.Args))
  1916  	changed := false
  1917  	for i, a := range ap.Args {
  1918  		ac := a.Copy(fn, skip)
  1919  		if ac == nil {
  1920  			args[i] = a
  1921  		} else {
  1922  			args[i] = ac
  1923  			changed = true
  1924  		}
  1925  	}
  1926  	if !changed {
  1927  		return fn(ap)
  1928  	}
  1929  	ap = &ArgumentPack{Args: args}
  1930  	if r := fn(ap); r != nil {
  1931  		return r
  1932  	}
  1933  	return ap
  1934  }
  1935  
  1936  func (ap *ArgumentPack) GoString() string {
  1937  	return ap.goString(0, "")
  1938  }
  1939  
  1940  func (ap *ArgumentPack) goString(indent int, field string) string {
  1941  	if len(ap.Args) == 0 {
  1942  		return fmt.Sprintf("%*s%sArgumentPack: nil", indent, "", field)
  1943  	}
  1944  	s := fmt.Sprintf("%*s%sArgumentPack:", indent, "", field)
  1945  	for i, a := range ap.Args {
  1946  		s += "\n"
  1947  		s += a.goString(indent+2, fmt.Sprintf("%d: ", i))
  1948  	}
  1949  	return s
  1950  }
  1951  
  1952  // SizeofPack is the sizeof operator applied to an argument pack.
  1953  type SizeofPack struct {
  1954  	Pack *ArgumentPack
  1955  }
  1956  
  1957  func (sp *SizeofPack) print(ps *printState) {
  1958  	if ps.llvmStyle {
  1959  		ps.writeString("sizeof...(")
  1960  		ps.print(sp.Pack)
  1961  		ps.writeByte(')')
  1962  	} else {
  1963  		ps.writeString(fmt.Sprintf("%d", len(sp.Pack.Args)))
  1964  	}
  1965  }
  1966  
  1967  func (sp *SizeofPack) Traverse(fn func(AST) bool) {
  1968  	fn(sp)
  1969  	// Don't traverse the pack--it points elsewhere in the AST.
  1970  }
  1971  
  1972  func (sp *SizeofPack) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  1973  	if skip(sp) {
  1974  		return nil
  1975  	}
  1976  	sp = &SizeofPack{Pack: sp.Pack}
  1977  	if r := fn(sp); r != nil {
  1978  		return r
  1979  	}
  1980  	return sp
  1981  }
  1982  
  1983  func (sp *SizeofPack) GoString() string {
  1984  	return sp.goString(0, "")
  1985  }
  1986  
  1987  func (sp *SizeofPack) goString(indent int, field string) string {
  1988  	return fmt.Sprintf("%*s%sSizeofPack: Pack: %p", indent, "", field, sp.Pack)
  1989  }
  1990  
  1991  // SizeofArgs is the size of a captured template parameter pack from
  1992  // an alias template.
  1993  type SizeofArgs struct {
  1994  	Args []AST
  1995  }
  1996  
  1997  func (sa *SizeofArgs) print(ps *printState) {
  1998  	c := 0
  1999  	for _, a := range sa.Args {
  2000  		if ap, ok := a.(*ArgumentPack); ok {
  2001  			c += len(ap.Args)
  2002  		} else if el, ok := a.(*ExprList); ok {
  2003  			c += len(el.Exprs)
  2004  		} else {
  2005  			c++
  2006  		}
  2007  	}
  2008  	ps.writeString(fmt.Sprintf("%d", c))
  2009  }
  2010  
  2011  func (sa *SizeofArgs) Traverse(fn func(AST) bool) {
  2012  	if fn(sa) {
  2013  		for _, a := range sa.Args {
  2014  			a.Traverse(fn)
  2015  		}
  2016  	}
  2017  }
  2018  
  2019  func (sa *SizeofArgs) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2020  	if skip(sa) {
  2021  		return nil
  2022  	}
  2023  	changed := false
  2024  	args := make([]AST, len(sa.Args))
  2025  	for i, a := range sa.Args {
  2026  		ac := a.Copy(fn, skip)
  2027  		if ac == nil {
  2028  			args[i] = a
  2029  		} else {
  2030  			args[i] = ac
  2031  			changed = true
  2032  		}
  2033  	}
  2034  	if !changed {
  2035  		return fn(sa)
  2036  	}
  2037  	sa = &SizeofArgs{Args: args}
  2038  	if r := fn(sa); r != nil {
  2039  		return r
  2040  	}
  2041  	return sa
  2042  }
  2043  
  2044  func (sa *SizeofArgs) GoString() string {
  2045  	return sa.goString(0, "")
  2046  }
  2047  
  2048  func (sa *SizeofArgs) goString(indent int, field string) string {
  2049  	var args string
  2050  	if len(sa.Args) == 0 {
  2051  		args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
  2052  	} else {
  2053  		args = fmt.Sprintf("%*sArgs:", indent+2, "")
  2054  		for i, a := range sa.Args {
  2055  			args += "\n"
  2056  			args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
  2057  		}
  2058  	}
  2059  	return fmt.Sprintf("%*s%sSizeofArgs:\n%s", indent, "", field, args)
  2060  }
  2061  
  2062  // TemplateParamName is the name of a template parameter that the
  2063  // demangler introduced for a lambda that has explicit template
  2064  // parameters.  This is a prefix with an index.
  2065  type TemplateParamName struct {
  2066  	Prefix string
  2067  	Index  int
  2068  }
  2069  
  2070  func (tpn *TemplateParamName) print(ps *printState) {
  2071  	ps.writeString(tpn.Prefix)
  2072  	if tpn.Index > 0 {
  2073  		ps.writeString(fmt.Sprintf("%d", tpn.Index-1))
  2074  	}
  2075  }
  2076  
  2077  func (tpn *TemplateParamName) Traverse(fn func(AST) bool) {
  2078  	fn(tpn)
  2079  }
  2080  
  2081  func (tpn *TemplateParamName) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2082  	if skip(tpn) {
  2083  		return nil
  2084  	}
  2085  	return fn(tpn)
  2086  }
  2087  
  2088  func (tpn *TemplateParamName) GoString() string {
  2089  	return tpn.goString(0, "")
  2090  }
  2091  
  2092  func (tpn *TemplateParamName) goString(indent int, field string) string {
  2093  	name := tpn.Prefix
  2094  	if tpn.Index > 0 {
  2095  		name += fmt.Sprintf("%d", tpn.Index-1)
  2096  	}
  2097  	return fmt.Sprintf("%*s%sTemplateParamName: %s", indent, "", field, name)
  2098  }
  2099  
  2100  // TypeTemplateParam is a type template parameter that appears in a
  2101  // lambda with explicit template parameters.
  2102  type TypeTemplateParam struct {
  2103  	Name AST
  2104  }
  2105  
  2106  func (ttp *TypeTemplateParam) print(ps *printState) {
  2107  	ps.writeString("typename ")
  2108  	ps.printInner(false)
  2109  	ps.print(ttp.Name)
  2110  }
  2111  
  2112  func (ttp *TypeTemplateParam) Traverse(fn func(AST) bool) {
  2113  	if fn(ttp) {
  2114  		ttp.Name.Traverse(fn)
  2115  	}
  2116  }
  2117  
  2118  func (ttp *TypeTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2119  	if skip(ttp) {
  2120  		return nil
  2121  	}
  2122  	name := ttp.Name.Copy(fn, skip)
  2123  	if name == nil {
  2124  		return fn(ttp)
  2125  	}
  2126  	ttp = &TypeTemplateParam{Name: name}
  2127  	if r := fn(ttp); r != nil {
  2128  		return r
  2129  	}
  2130  	return ttp
  2131  }
  2132  
  2133  func (ttp *TypeTemplateParam) GoString() string {
  2134  	return ttp.goString(0, "")
  2135  }
  2136  
  2137  func (ttp *TypeTemplateParam) goString(indent int, field string) string {
  2138  	return fmt.Sprintf("%*s%sTypeTemplateParam:\n%s", indent, "", field,
  2139  		ttp.Name.goString(indent+2, "Name"))
  2140  }
  2141  
  2142  // NonTypeTemplateParam is a non-type template parameter that appears
  2143  // in a lambda with explicit template parameters.
  2144  type NonTypeTemplateParam struct {
  2145  	Name AST
  2146  	Type AST
  2147  }
  2148  
  2149  func (nttp *NonTypeTemplateParam) print(ps *printState) {
  2150  	ps.inner = append(ps.inner, nttp)
  2151  	ps.print(nttp.Type)
  2152  	if len(ps.inner) > 0 {
  2153  		ps.writeByte(' ')
  2154  		ps.print(nttp.Name)
  2155  		ps.inner = ps.inner[:len(ps.inner)-1]
  2156  	}
  2157  }
  2158  
  2159  func (nttp *NonTypeTemplateParam) printInner(ps *printState) {
  2160  	ps.print(nttp.Name)
  2161  }
  2162  
  2163  func (nttp *NonTypeTemplateParam) Traverse(fn func(AST) bool) {
  2164  	if fn(nttp) {
  2165  		nttp.Name.Traverse(fn)
  2166  		nttp.Type.Traverse(fn)
  2167  	}
  2168  }
  2169  
  2170  func (nttp *NonTypeTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2171  	if skip(nttp) {
  2172  		return nil
  2173  	}
  2174  	name := nttp.Name.Copy(fn, skip)
  2175  	typ := nttp.Type.Copy(fn, skip)
  2176  	if name == nil && typ == nil {
  2177  		return fn(nttp)
  2178  	}
  2179  	if name == nil {
  2180  		name = nttp.Name
  2181  	}
  2182  	if typ == nil {
  2183  		typ = nttp.Type
  2184  	}
  2185  	nttp = &NonTypeTemplateParam{Name: name, Type: typ}
  2186  	if r := fn(nttp); r != nil {
  2187  		return r
  2188  	}
  2189  	return nttp
  2190  }
  2191  
  2192  func (nttp *NonTypeTemplateParam) GoString() string {
  2193  	return nttp.goString(0, "")
  2194  }
  2195  
  2196  func (nttp *NonTypeTemplateParam) goString(indent int, field string) string {
  2197  	return fmt.Sprintf("%*s%sNonTypeTemplateParam:\n%s\n%s", indent, "", field,
  2198  		nttp.Name.goString(indent+2, "Name: "),
  2199  		nttp.Type.goString(indent+2, "Type: "))
  2200  }
  2201  
  2202  // TemplateTemplateParam is a template template parameter that appears
  2203  // in a lambda with explicit template parameters.
  2204  type TemplateTemplateParam struct {
  2205  	Name   AST
  2206  	Params []AST
  2207  }
  2208  
  2209  func (ttp *TemplateTemplateParam) print(ps *printState) {
  2210  	ps.writeString("template<")
  2211  	for i, param := range ttp.Params {
  2212  		if i > 0 {
  2213  			ps.writeString(", ")
  2214  		}
  2215  		ps.print(param)
  2216  	}
  2217  	ps.writeString("> typename ")
  2218  	ps.print(ttp.Name)
  2219  }
  2220  
  2221  func (ttp *TemplateTemplateParam) Traverse(fn func(AST) bool) {
  2222  	if fn(ttp) {
  2223  		ttp.Name.Traverse(fn)
  2224  		for _, param := range ttp.Params {
  2225  			param.Traverse(fn)
  2226  		}
  2227  	}
  2228  }
  2229  
  2230  func (ttp *TemplateTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2231  	if skip(ttp) {
  2232  		return nil
  2233  	}
  2234  
  2235  	changed := false
  2236  
  2237  	name := ttp.Name.Copy(fn, skip)
  2238  	if name == nil {
  2239  		name = ttp.Name
  2240  	} else {
  2241  		changed = true
  2242  	}
  2243  
  2244  	params := make([]AST, len(ttp.Params))
  2245  	for i, p := range ttp.Params {
  2246  		pc := p.Copy(fn, skip)
  2247  		if pc == nil {
  2248  			params[i] = p
  2249  		} else {
  2250  			params[i] = pc
  2251  			changed = true
  2252  		}
  2253  	}
  2254  
  2255  	if !changed {
  2256  		return fn(ttp)
  2257  	}
  2258  
  2259  	ttp = &TemplateTemplateParam{
  2260  		Name:   name,
  2261  		Params: params,
  2262  	}
  2263  	if r := fn(ttp); r != nil {
  2264  		return r
  2265  	}
  2266  	return ttp
  2267  }
  2268  
  2269  func (ttp *TemplateTemplateParam) GoString() string {
  2270  	return ttp.goString(0, "")
  2271  }
  2272  
  2273  func (ttp *TemplateTemplateParam) goString(indent int, field string) string {
  2274  	var params strings.Builder
  2275  	fmt.Fprintf(&params, "%*sParams:", indent+2, "")
  2276  	for i, p := range ttp.Params {
  2277  		params.WriteByte('\n')
  2278  		params.WriteString(p.goString(indent+4, fmt.Sprintf("%d: ", i)))
  2279  	}
  2280  	return fmt.Sprintf("%*s%sTemplateTemplateParam:\n%s\n%s", indent, "", field,
  2281  		ttp.Name.goString(indent+2, "Name: "),
  2282  		params.String())
  2283  }
  2284  
  2285  // TemplateParamPack is a template parameter pack that appears in a
  2286  // lambda with explicit template parameters.
  2287  type TemplateParamPack struct {
  2288  	Param AST
  2289  }
  2290  
  2291  func (tpp *TemplateParamPack) print(ps *printState) {
  2292  	holdInner := ps.inner
  2293  	defer func() { ps.inner = holdInner }()
  2294  
  2295  	ps.inner = []AST{tpp}
  2296  	if nttp, ok := tpp.Param.(*NonTypeTemplateParam); ok {
  2297  		ps.print(nttp.Type)
  2298  	} else {
  2299  		ps.print(tpp.Param)
  2300  	}
  2301  	if len(ps.inner) > 0 {
  2302  		ps.writeString("...")
  2303  	}
  2304  }
  2305  
  2306  func (tpp *TemplateParamPack) printInner(ps *printState) {
  2307  	ps.writeString("...")
  2308  	if nttp, ok := tpp.Param.(*NonTypeTemplateParam); ok {
  2309  		ps.print(nttp.Name)
  2310  	}
  2311  }
  2312  
  2313  func (tpp *TemplateParamPack) Traverse(fn func(AST) bool) {
  2314  	if fn(tpp) {
  2315  		tpp.Param.Traverse(fn)
  2316  	}
  2317  }
  2318  
  2319  func (tpp *TemplateParamPack) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2320  	if skip(tpp) {
  2321  		return nil
  2322  	}
  2323  	param := tpp.Param.Copy(fn, skip)
  2324  	if param == nil {
  2325  		return fn(tpp)
  2326  	}
  2327  	tpp = &TemplateParamPack{Param: param}
  2328  	if r := fn(tpp); r != nil {
  2329  		return r
  2330  	}
  2331  	return tpp
  2332  }
  2333  
  2334  func (tpp *TemplateParamPack) GoString() string {
  2335  	return tpp.goString(0, "")
  2336  }
  2337  
  2338  func (tpp *TemplateParamPack) goString(indent int, field string) string {
  2339  	return fmt.Sprintf("%*s%sTemplateParamPack:\n%s", indent, "", field,
  2340  		tpp.Param.goString(indent+2, "Param: "))
  2341  }
  2342  
  2343  // Cast is a type cast.
  2344  type Cast struct {
  2345  	To AST
  2346  }
  2347  
  2348  func (c *Cast) print(ps *printState) {
  2349  	ps.writeString("operator ")
  2350  	ps.print(c.To)
  2351  }
  2352  
  2353  func (c *Cast) Traverse(fn func(AST) bool) {
  2354  	if fn(c) {
  2355  		c.To.Traverse(fn)
  2356  	}
  2357  }
  2358  
  2359  func (c *Cast) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2360  	if skip(c) {
  2361  		return nil
  2362  	}
  2363  	to := c.To.Copy(fn, skip)
  2364  	if to == nil {
  2365  		return fn(c)
  2366  	}
  2367  	c = &Cast{To: to}
  2368  	if r := fn(c); r != nil {
  2369  		return r
  2370  	}
  2371  	return c
  2372  }
  2373  
  2374  func (c *Cast) GoString() string {
  2375  	return c.goString(0, "")
  2376  }
  2377  
  2378  func (c *Cast) goString(indent int, field string) string {
  2379  	return fmt.Sprintf("%*s%sCast\n%s", indent, "", field,
  2380  		c.To.goString(indent+2, "To: "))
  2381  }
  2382  
  2383  // The parenthesize function prints the string for val, wrapped in
  2384  // parentheses if necessary.
  2385  func parenthesize(ps *printState, val AST) {
  2386  	paren := false
  2387  	switch v := val.(type) {
  2388  	case *Name, *InitializerList:
  2389  	case *FunctionParam:
  2390  		if ps.llvmStyle {
  2391  			paren = true
  2392  		}
  2393  	case *Qualified:
  2394  		if v.LocalName {
  2395  			paren = true
  2396  		}
  2397  	default:
  2398  		paren = true
  2399  	}
  2400  	if paren {
  2401  		ps.writeByte('(')
  2402  	}
  2403  	ps.print(val)
  2404  	if paren {
  2405  		ps.writeByte(')')
  2406  	}
  2407  }
  2408  
  2409  // Nullary is an operator in an expression with no arguments, such as
  2410  // throw.
  2411  type Nullary struct {
  2412  	Op AST
  2413  }
  2414  
  2415  func (n *Nullary) print(ps *printState) {
  2416  	if op, ok := n.Op.(*Operator); ok {
  2417  		ps.writeString(op.Name)
  2418  	} else {
  2419  		ps.print(n.Op)
  2420  	}
  2421  }
  2422  
  2423  func (n *Nullary) Traverse(fn func(AST) bool) {
  2424  	if fn(n) {
  2425  		n.Op.Traverse(fn)
  2426  	}
  2427  }
  2428  
  2429  func (n *Nullary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2430  	if skip(n) {
  2431  		return nil
  2432  	}
  2433  	op := n.Op.Copy(fn, skip)
  2434  	if op == nil {
  2435  		return fn(n)
  2436  	}
  2437  	n = &Nullary{Op: op}
  2438  	if r := fn(n); r != nil {
  2439  		return r
  2440  	}
  2441  	return n
  2442  }
  2443  
  2444  func (n *Nullary) GoString() string {
  2445  	return n.goString(0, "")
  2446  }
  2447  
  2448  func (n *Nullary) goString(indent int, field string) string {
  2449  	return fmt.Sprintf("%*s%sNullary:\n%s", indent, "", field,
  2450  		n.Op.goString(indent+2, "Op: "))
  2451  }
  2452  
  2453  // Unary is a unary operation in an expression.
  2454  type Unary struct {
  2455  	Op         AST
  2456  	Expr       AST
  2457  	Suffix     bool // true for ++ -- when used as postfix
  2458  	SizeofType bool // true for sizeof (type)
  2459  }
  2460  
  2461  func (u *Unary) print(ps *printState) {
  2462  	op, _ := u.Op.(*Operator)
  2463  	expr := u.Expr
  2464  
  2465  	// Don't print the argument list when taking the address of a
  2466  	// function.
  2467  	if !ps.llvmStyle {
  2468  		if op != nil && op.Name == "&" {
  2469  			if t, ok := expr.(*Typed); ok {
  2470  				if _, ok := t.Type.(*FunctionType); ok {
  2471  					expr = t.Name
  2472  				}
  2473  			}
  2474  		}
  2475  	}
  2476  
  2477  	if u.Suffix {
  2478  		parenthesize(ps, expr)
  2479  	}
  2480  
  2481  	if op != nil {
  2482  		ps.writeString(op.Name)
  2483  		if ps.llvmStyle && op.Name == "noexcept" {
  2484  			ps.writeByte(' ')
  2485  		}
  2486  	} else if c, ok := u.Op.(*Cast); ok {
  2487  		ps.writeByte('(')
  2488  		ps.print(c.To)
  2489  		ps.writeByte(')')
  2490  	} else {
  2491  		ps.print(u.Op)
  2492  	}
  2493  
  2494  	if !u.Suffix {
  2495  		if op != nil && op.Name == "::" {
  2496  			// Don't use parentheses after ::.
  2497  			ps.print(expr)
  2498  		} else if u.SizeofType {
  2499  			// Always use parentheses for sizeof argument.
  2500  			ps.writeByte('(')
  2501  			ps.print(expr)
  2502  			ps.writeByte(')')
  2503  		} else if op != nil && op.Name == "__alignof__" {
  2504  			// Always use parentheses for __alignof__ argument.
  2505  			ps.writeByte('(')
  2506  			ps.print(expr)
  2507  			ps.writeByte(')')
  2508  		} else if ps.llvmStyle {
  2509  			if op == nil || op.Name != `operator"" ` {
  2510  				ps.writeByte('(')
  2511  			}
  2512  			ps.print(expr)
  2513  			if op == nil || op.Name != `operator"" ` {
  2514  				ps.writeByte(')')
  2515  			}
  2516  		} else {
  2517  			parenthesize(ps, expr)
  2518  		}
  2519  	}
  2520  }
  2521  
  2522  func (u *Unary) Traverse(fn func(AST) bool) {
  2523  	if fn(u) {
  2524  		u.Op.Traverse(fn)
  2525  		u.Expr.Traverse(fn)
  2526  	}
  2527  }
  2528  
  2529  func (u *Unary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2530  	if skip(u) {
  2531  		return nil
  2532  	}
  2533  	op := u.Op.Copy(fn, skip)
  2534  	expr := u.Expr.Copy(fn, skip)
  2535  	if op == nil && expr == nil {
  2536  		return fn(u)
  2537  	}
  2538  	if op == nil {
  2539  		op = u.Op
  2540  	}
  2541  	if expr == nil {
  2542  		expr = u.Expr
  2543  	}
  2544  	u = &Unary{Op: op, Expr: expr, Suffix: u.Suffix, SizeofType: u.SizeofType}
  2545  	if r := fn(u); r != nil {
  2546  		return r
  2547  	}
  2548  	return u
  2549  }
  2550  
  2551  func (u *Unary) GoString() string {
  2552  	return u.goString(0, "")
  2553  }
  2554  
  2555  func (u *Unary) goString(indent int, field string) string {
  2556  	var s string
  2557  	if u.Suffix {
  2558  		s = " Suffix: true"
  2559  	}
  2560  	if u.SizeofType {
  2561  		s += " SizeofType: true"
  2562  	}
  2563  	return fmt.Sprintf("%*s%sUnary:%s\n%s\n%s", indent, "", field,
  2564  		s, u.Op.goString(indent+2, "Op: "),
  2565  		u.Expr.goString(indent+2, "Expr: "))
  2566  }
  2567  
  2568  // isDesignatedInitializer reports whether x is a designated
  2569  // initializer.
  2570  func isDesignatedInitializer(x AST) bool {
  2571  	switch x := x.(type) {
  2572  	case *Binary:
  2573  		if op, ok := x.Op.(*Operator); ok {
  2574  			if op.Name == "]=" {
  2575  				return true
  2576  			}
  2577  			if op.Name != "=" {
  2578  				return false
  2579  			}
  2580  			if _, ok := x.Left.(*Literal); ok {
  2581  				return false
  2582  			}
  2583  			return true
  2584  		}
  2585  	case *Trinary:
  2586  		if op, ok := x.Op.(*Operator); ok {
  2587  			return op.Name == "[...]="
  2588  		}
  2589  	}
  2590  	return false
  2591  }
  2592  
  2593  // Binary is a binary operation in an expression.
  2594  type Binary struct {
  2595  	Op    AST
  2596  	Left  AST
  2597  	Right AST
  2598  }
  2599  
  2600  func (b *Binary) print(ps *printState) {
  2601  	op, _ := b.Op.(*Operator)
  2602  
  2603  	if op != nil && strings.Contains(op.Name, "cast") {
  2604  		ps.writeString(op.Name)
  2605  		ps.writeByte('<')
  2606  		ps.print(b.Left)
  2607  		ps.writeString(">(")
  2608  		ps.print(b.Right)
  2609  		ps.writeByte(')')
  2610  		return
  2611  	}
  2612  
  2613  	if isDesignatedInitializer(b) {
  2614  		if op.Name == "=" {
  2615  			ps.writeByte('.')
  2616  		} else {
  2617  			ps.writeByte('[')
  2618  		}
  2619  		ps.print(b.Left)
  2620  		if op.Name == "]=" {
  2621  			ps.writeByte(']')
  2622  		}
  2623  		if isDesignatedInitializer(b.Right) {
  2624  			// Don't add anything between designated
  2625  			// initializer chains.
  2626  			ps.print(b.Right)
  2627  		} else {
  2628  			if ps.llvmStyle {
  2629  				ps.writeString(" = ")
  2630  				ps.print(b.Right)
  2631  			} else {
  2632  				ps.writeByte('=')
  2633  				parenthesize(ps, b.Right)
  2634  			}
  2635  		}
  2636  		return
  2637  	}
  2638  
  2639  	// Use an extra set of parentheses around an expression that
  2640  	// uses the greater-than operator, so that it does not get
  2641  	// confused with the '>' that ends template parameters.
  2642  	if op != nil && op.Name == ">" {
  2643  		ps.writeByte('(')
  2644  	}
  2645  
  2646  	left := b.Left
  2647  
  2648  	skipParens := false
  2649  	skipBothParens := false
  2650  	addSpaces := ps.llvmStyle
  2651  	if ps.llvmStyle && op != nil {
  2652  		switch op.Name {
  2653  		case ".", "->":
  2654  			skipBothParens = true
  2655  			addSpaces = false
  2656  		}
  2657  	}
  2658  
  2659  	// For a function call in an expression, don't print the types
  2660  	// of the arguments unless there is a return type.
  2661  	if op != nil && op.Name == "()" {
  2662  		if ty, ok := b.Left.(*Typed); ok {
  2663  			if ft, ok := ty.Type.(*FunctionType); ok {
  2664  				if ft.Return == nil {
  2665  					left = ty.Name
  2666  				} else {
  2667  					skipParens = true
  2668  				}
  2669  			} else {
  2670  				left = ty.Name
  2671  			}
  2672  		}
  2673  		if ps.llvmStyle {
  2674  			skipParens = true
  2675  		}
  2676  	}
  2677  
  2678  	if skipParens || skipBothParens {
  2679  		ps.print(left)
  2680  	} else if ps.llvmStyle {
  2681  		ps.writeByte('(')
  2682  		ps.print(left)
  2683  		ps.writeByte(')')
  2684  	} else {
  2685  		parenthesize(ps, left)
  2686  	}
  2687  
  2688  	if op != nil && op.Name == "[]" {
  2689  		ps.writeByte('[')
  2690  		ps.print(b.Right)
  2691  		ps.writeByte(']')
  2692  		return
  2693  	}
  2694  
  2695  	if op != nil {
  2696  		if op.Name != "()" {
  2697  			if addSpaces {
  2698  				ps.writeByte(' ')
  2699  			}
  2700  			ps.writeString(op.Name)
  2701  			if addSpaces {
  2702  				ps.writeByte(' ')
  2703  			}
  2704  		}
  2705  	} else {
  2706  		ps.print(b.Op)
  2707  	}
  2708  
  2709  	if skipBothParens {
  2710  		ps.print(b.Right)
  2711  	} else if ps.llvmStyle {
  2712  		ps.writeByte('(')
  2713  		ps.print(b.Right)
  2714  		ps.writeByte(')')
  2715  	} else {
  2716  		parenthesize(ps, b.Right)
  2717  	}
  2718  
  2719  	if op != nil && op.Name == ">" {
  2720  		ps.writeByte(')')
  2721  	}
  2722  }
  2723  
  2724  func (b *Binary) Traverse(fn func(AST) bool) {
  2725  	if fn(b) {
  2726  		b.Op.Traverse(fn)
  2727  		b.Left.Traverse(fn)
  2728  		b.Right.Traverse(fn)
  2729  	}
  2730  }
  2731  
  2732  func (b *Binary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2733  	if skip(b) {
  2734  		return nil
  2735  	}
  2736  	op := b.Op.Copy(fn, skip)
  2737  	left := b.Left.Copy(fn, skip)
  2738  	right := b.Right.Copy(fn, skip)
  2739  	if op == nil && left == nil && right == nil {
  2740  		return fn(b)
  2741  	}
  2742  	if op == nil {
  2743  		op = b.Op
  2744  	}
  2745  	if left == nil {
  2746  		left = b.Left
  2747  	}
  2748  	if right == nil {
  2749  		right = b.Right
  2750  	}
  2751  	b = &Binary{Op: op, Left: left, Right: right}
  2752  	if r := fn(b); r != nil {
  2753  		return r
  2754  	}
  2755  	return b
  2756  }
  2757  
  2758  func (b *Binary) GoString() string {
  2759  	return b.goString(0, "")
  2760  }
  2761  
  2762  func (b *Binary) goString(indent int, field string) string {
  2763  	return fmt.Sprintf("%*s%sBinary:\n%s\n%s\n%s", indent, "", field,
  2764  		b.Op.goString(indent+2, "Op: "),
  2765  		b.Left.goString(indent+2, "Left: "),
  2766  		b.Right.goString(indent+2, "Right: "))
  2767  }
  2768  
  2769  // Trinary is the ?: trinary operation in an expression.
  2770  type Trinary struct {
  2771  	Op     AST
  2772  	First  AST
  2773  	Second AST
  2774  	Third  AST
  2775  }
  2776  
  2777  func (t *Trinary) print(ps *printState) {
  2778  	if isDesignatedInitializer(t) {
  2779  		ps.writeByte('[')
  2780  		ps.print(t.First)
  2781  		ps.writeString(" ... ")
  2782  		ps.print(t.Second)
  2783  		ps.writeByte(']')
  2784  		if isDesignatedInitializer(t.Third) {
  2785  			// Don't add anything between designated
  2786  			// initializer chains.
  2787  			ps.print(t.Third)
  2788  		} else {
  2789  			if ps.llvmStyle {
  2790  				ps.writeString(" = ")
  2791  				ps.print(t.Third)
  2792  			} else {
  2793  				ps.writeByte('=')
  2794  				parenthesize(ps, t.Third)
  2795  			}
  2796  		}
  2797  		return
  2798  	}
  2799  
  2800  	parenthesize(ps, t.First)
  2801  	if ps.llvmStyle {
  2802  		ps.writeString(" ? ")
  2803  	} else {
  2804  		ps.writeByte('?')
  2805  	}
  2806  	parenthesize(ps, t.Second)
  2807  	ps.writeString(" : ")
  2808  	parenthesize(ps, t.Third)
  2809  }
  2810  
  2811  func (t *Trinary) Traverse(fn func(AST) bool) {
  2812  	if fn(t) {
  2813  		t.Op.Traverse(fn)
  2814  		t.First.Traverse(fn)
  2815  		t.Second.Traverse(fn)
  2816  		t.Third.Traverse(fn)
  2817  	}
  2818  }
  2819  
  2820  func (t *Trinary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2821  	if skip(t) {
  2822  		return nil
  2823  	}
  2824  	op := t.Op.Copy(fn, skip)
  2825  	first := t.First.Copy(fn, skip)
  2826  	second := t.Second.Copy(fn, skip)
  2827  	third := t.Third.Copy(fn, skip)
  2828  	if op == nil && first == nil && second == nil && third == nil {
  2829  		return fn(t)
  2830  	}
  2831  	if op == nil {
  2832  		op = t.Op
  2833  	}
  2834  	if first == nil {
  2835  		first = t.First
  2836  	}
  2837  	if second == nil {
  2838  		second = t.Second
  2839  	}
  2840  	if third == nil {
  2841  		third = t.Third
  2842  	}
  2843  	t = &Trinary{Op: op, First: first, Second: second, Third: third}
  2844  	if r := fn(t); r != nil {
  2845  		return r
  2846  	}
  2847  	return t
  2848  }
  2849  
  2850  func (t *Trinary) GoString() string {
  2851  	return t.goString(0, "")
  2852  }
  2853  
  2854  func (t *Trinary) goString(indent int, field string) string {
  2855  	return fmt.Sprintf("%*s%sTrinary:\n%s\n%s\n%s\n%s", indent, "", field,
  2856  		t.Op.goString(indent+2, "Op: "),
  2857  		t.First.goString(indent+2, "First: "),
  2858  		t.Second.goString(indent+2, "Second: "),
  2859  		t.Third.goString(indent+2, "Third: "))
  2860  }
  2861  
  2862  // Fold is a C++17 fold-expression.  Arg2 is nil for a unary operator.
  2863  type Fold struct {
  2864  	Left bool
  2865  	Op   AST
  2866  	Arg1 AST
  2867  	Arg2 AST
  2868  }
  2869  
  2870  func (f *Fold) print(ps *printState) {
  2871  	op, _ := f.Op.(*Operator)
  2872  	printOp := func() {
  2873  		if op != nil {
  2874  			if ps.llvmStyle {
  2875  				ps.writeByte(' ')
  2876  			}
  2877  			ps.writeString(op.Name)
  2878  			if ps.llvmStyle {
  2879  				ps.writeByte(' ')
  2880  			}
  2881  		} else {
  2882  			ps.print(f.Op)
  2883  		}
  2884  	}
  2885  	foldParenthesize := func(a AST) {
  2886  		if _, ok := a.(*ArgumentPack); ok || !ps.llvmStyle {
  2887  			parenthesize(ps, a)
  2888  		} else {
  2889  			ps.print(a)
  2890  		}
  2891  	}
  2892  
  2893  	if f.Arg2 == nil {
  2894  		if f.Left {
  2895  			ps.writeString("(...")
  2896  			printOp()
  2897  			foldParenthesize(f.Arg1)
  2898  			ps.writeString(")")
  2899  		} else {
  2900  			ps.writeString("(")
  2901  			foldParenthesize(f.Arg1)
  2902  			printOp()
  2903  			ps.writeString("...)")
  2904  		}
  2905  	} else {
  2906  		ps.writeString("(")
  2907  		foldParenthesize(f.Arg1)
  2908  		printOp()
  2909  		ps.writeString("...")
  2910  		printOp()
  2911  		foldParenthesize(f.Arg2)
  2912  		ps.writeString(")")
  2913  	}
  2914  }
  2915  
  2916  func (f *Fold) Traverse(fn func(AST) bool) {
  2917  	if fn(f) {
  2918  		f.Op.Traverse(fn)
  2919  		f.Arg1.Traverse(fn)
  2920  		if f.Arg2 != nil {
  2921  			f.Arg2.Traverse(fn)
  2922  		}
  2923  	}
  2924  }
  2925  
  2926  func (f *Fold) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  2927  	if skip(f) {
  2928  		return nil
  2929  	}
  2930  	op := f.Op.Copy(fn, skip)
  2931  	arg1 := f.Arg1.Copy(fn, skip)
  2932  	var arg2 AST
  2933  	if f.Arg2 != nil {
  2934  		arg2 = f.Arg2.Copy(fn, skip)
  2935  	}
  2936  	if op == nil && arg1 == nil && arg2 == nil {
  2937  		return fn(f)
  2938  	}
  2939  	if op == nil {
  2940  		op = f.Op
  2941  	}
  2942  	if arg1 == nil {
  2943  		arg1 = f.Arg1
  2944  	}
  2945  	if arg2 == nil {
  2946  		arg2 = f.Arg2
  2947  	}
  2948  	f = &Fold{Left: f.Left, Op: op, Arg1: arg1, Arg2: arg2}
  2949  	if r := fn(f); r != nil {
  2950  		return r
  2951  	}
  2952  	return f
  2953  }
  2954  
  2955  func (f *Fold) GoString() string {
  2956  	return f.goString(0, "")
  2957  }
  2958  
  2959  func (f *Fold) goString(indent int, field string) string {
  2960  	if f.Arg2 == nil {
  2961  		return fmt.Sprintf("%*s%sFold: Left: %t\n%s\n%s", indent, "", field,
  2962  			f.Left, f.Op.goString(indent+2, "Op: "),
  2963  			f.Arg1.goString(indent+2, "Arg1: "))
  2964  	} else {
  2965  		return fmt.Sprintf("%*s%sFold: Left: %t\n%s\n%s\n%s", indent, "", field,
  2966  			f.Left, f.Op.goString(indent+2, "Op: "),
  2967  			f.Arg1.goString(indent+2, "Arg1: "),
  2968  			f.Arg2.goString(indent+2, "Arg2: "))
  2969  	}
  2970  }
  2971  
  2972  // Subobject is a a reference to an offset in an expression.  This is
  2973  // used for C++20 manglings of class types used as the type of
  2974  // non-type template arguments.
  2975  //
  2976  // See https://github.com/itanium-cxx-abi/cxx-abi/issues/47.
  2977  type Subobject struct {
  2978  	Type      AST
  2979  	SubExpr   AST
  2980  	Offset    int
  2981  	Selectors []int
  2982  	PastEnd   bool
  2983  }
  2984  
  2985  func (so *Subobject) print(ps *printState) {
  2986  	ps.print(so.SubExpr)
  2987  	ps.writeString(".<")
  2988  	ps.print(so.Type)
  2989  	ps.writeString(fmt.Sprintf(" at offset %d>", so.Offset))
  2990  }
  2991  
  2992  func (so *Subobject) Traverse(fn func(AST) bool) {
  2993  	if fn(so) {
  2994  		so.Type.Traverse(fn)
  2995  		so.SubExpr.Traverse(fn)
  2996  	}
  2997  }
  2998  
  2999  func (so *Subobject) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3000  	if skip(so) {
  3001  		return nil
  3002  	}
  3003  	typ := so.Type.Copy(fn, skip)
  3004  	subExpr := so.SubExpr.Copy(fn, skip)
  3005  	if typ == nil && subExpr == nil {
  3006  		return nil
  3007  	}
  3008  	if typ == nil {
  3009  		typ = so.Type
  3010  	}
  3011  	if subExpr == nil {
  3012  		subExpr = so.SubExpr
  3013  	}
  3014  	so = &Subobject{
  3015  		Type:      typ,
  3016  		SubExpr:   subExpr,
  3017  		Offset:    so.Offset,
  3018  		Selectors: so.Selectors,
  3019  		PastEnd:   so.PastEnd,
  3020  	}
  3021  	if r := fn(so); r != nil {
  3022  		return r
  3023  	}
  3024  	return so
  3025  }
  3026  
  3027  func (so *Subobject) GoString() string {
  3028  	return so.goString(0, "")
  3029  }
  3030  
  3031  func (so *Subobject) goString(indent int, field string) string {
  3032  	var selectors string
  3033  	for _, s := range so.Selectors {
  3034  		selectors += fmt.Sprintf(" %d", s)
  3035  	}
  3036  	return fmt.Sprintf("%*s%sSubobject:\n%s\n%s\n%*sOffset: %d\n%*sSelectors:%s\n%*sPastEnd: %t",
  3037  		indent, "", field,
  3038  		so.Type.goString(indent+2, "Type: "),
  3039  		so.SubExpr.goString(indent+2, "SubExpr: "),
  3040  		indent+2, "", so.Offset,
  3041  		indent+2, "", selectors,
  3042  		indent+2, "", so.PastEnd)
  3043  }
  3044  
  3045  // PtrMemCast is a conversion of an expression to a pointer-to-member
  3046  // type.  This is used for C++20 manglings of class types used as the
  3047  // type of non-type template arguments.
  3048  //
  3049  // See https://github.com/itanium-cxx-abi/cxx-abi/issues/47.
  3050  type PtrMemCast struct {
  3051  	Type   AST
  3052  	Expr   AST
  3053  	Offset int
  3054  }
  3055  
  3056  func (pmc *PtrMemCast) print(ps *printState) {
  3057  	ps.writeString("(")
  3058  	ps.print(pmc.Type)
  3059  	ps.writeString(")(")
  3060  	ps.print(pmc.Expr)
  3061  	ps.writeString(")")
  3062  }
  3063  
  3064  func (pmc *PtrMemCast) Traverse(fn func(AST) bool) {
  3065  	if fn(pmc) {
  3066  		pmc.Type.Traverse(fn)
  3067  		pmc.Expr.Traverse(fn)
  3068  	}
  3069  }
  3070  
  3071  func (pmc *PtrMemCast) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3072  	if skip(pmc) {
  3073  		return nil
  3074  	}
  3075  	typ := pmc.Type.Copy(fn, skip)
  3076  	expr := pmc.Expr.Copy(fn, skip)
  3077  	if typ == nil && expr == nil {
  3078  		return nil
  3079  	}
  3080  	if typ == nil {
  3081  		typ = pmc.Type
  3082  	}
  3083  	if expr == nil {
  3084  		expr = pmc.Expr
  3085  	}
  3086  	pmc = &PtrMemCast{
  3087  		Type:   typ,
  3088  		Expr:   expr,
  3089  		Offset: pmc.Offset,
  3090  	}
  3091  	if r := fn(pmc); r != nil {
  3092  		return r
  3093  	}
  3094  	return pmc
  3095  }
  3096  
  3097  func (pmc *PtrMemCast) GoString() string {
  3098  	return pmc.goString(0, "")
  3099  }
  3100  
  3101  func (pmc *PtrMemCast) goString(indent int, field string) string {
  3102  	return fmt.Sprintf("%*s%sPtrMemCast:\n%s\n%s\n%*sOffset: %d",
  3103  		indent, "", field,
  3104  		pmc.Type.goString(indent+2, "Type: "),
  3105  		pmc.Expr.goString(indent+2, "Expr: "),
  3106  		indent+2, "", pmc.Offset)
  3107  }
  3108  
  3109  // New is a use of operator new in an expression.
  3110  type New struct {
  3111  	Op    AST
  3112  	Place AST
  3113  	Type  AST
  3114  	Init  AST
  3115  }
  3116  
  3117  func (n *New) print(ps *printState) {
  3118  	// Op doesn't really matter for printing--we always print "new".
  3119  	ps.writeString("new ")
  3120  	if n.Place != nil {
  3121  		parenthesize(ps, n.Place)
  3122  		ps.writeByte(' ')
  3123  	}
  3124  	ps.print(n.Type)
  3125  	if n.Init != nil {
  3126  		parenthesize(ps, n.Init)
  3127  	}
  3128  }
  3129  
  3130  func (n *New) Traverse(fn func(AST) bool) {
  3131  	if fn(n) {
  3132  		n.Op.Traverse(fn)
  3133  		if n.Place != nil {
  3134  			n.Place.Traverse(fn)
  3135  		}
  3136  		n.Type.Traverse(fn)
  3137  		if n.Init != nil {
  3138  			n.Init.Traverse(fn)
  3139  		}
  3140  	}
  3141  }
  3142  
  3143  func (n *New) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3144  	if skip(n) {
  3145  		return nil
  3146  	}
  3147  	op := n.Op.Copy(fn, skip)
  3148  	var place AST
  3149  	if n.Place != nil {
  3150  		place = n.Place.Copy(fn, skip)
  3151  	}
  3152  	typ := n.Type.Copy(fn, skip)
  3153  	var ini AST
  3154  	if n.Init != nil {
  3155  		ini = n.Init.Copy(fn, skip)
  3156  	}
  3157  	if op == nil && place == nil && typ == nil && ini == nil {
  3158  		return fn(n)
  3159  	}
  3160  	if op == nil {
  3161  		op = n.Op
  3162  	}
  3163  	if place == nil {
  3164  		place = n.Place
  3165  	}
  3166  	if typ == nil {
  3167  		typ = n.Type
  3168  	}
  3169  	if ini == nil {
  3170  		ini = n.Init
  3171  	}
  3172  	n = &New{Op: op, Place: place, Type: typ, Init: ini}
  3173  	if r := fn(n); r != nil {
  3174  		return r
  3175  	}
  3176  	return n
  3177  }
  3178  
  3179  func (n *New) GoString() string {
  3180  	return n.goString(0, "")
  3181  }
  3182  
  3183  func (n *New) goString(indent int, field string) string {
  3184  	var place string
  3185  	if n.Place == nil {
  3186  		place = fmt.Sprintf("%*sPlace: nil", indent, "")
  3187  	} else {
  3188  		place = n.Place.goString(indent+2, "Place: ")
  3189  	}
  3190  	var ini string
  3191  	if n.Init == nil {
  3192  		ini = fmt.Sprintf("%*sInit: nil", indent, "")
  3193  	} else {
  3194  		ini = n.Init.goString(indent+2, "Init: ")
  3195  	}
  3196  	return fmt.Sprintf("%*s%sNew:\n%s\n%s\n%s\n%s", indent, "", field,
  3197  		n.Op.goString(indent+2, "Op: "), place,
  3198  		n.Type.goString(indent+2, "Type: "), ini)
  3199  }
  3200  
  3201  // Literal is a literal in an expression.
  3202  type Literal struct {
  3203  	Type AST
  3204  	Val  string
  3205  	Neg  bool
  3206  }
  3207  
  3208  // Suffixes to use for constants of the given integer type.
  3209  var builtinTypeSuffix = map[string]string{
  3210  	"int":                "",
  3211  	"unsigned int":       "u",
  3212  	"long":               "l",
  3213  	"unsigned long":      "ul",
  3214  	"long long":          "ll",
  3215  	"unsigned long long": "ull",
  3216  }
  3217  
  3218  // Builtin float types.
  3219  var builtinTypeFloat = map[string]bool{
  3220  	"double":      true,
  3221  	"long double": true,
  3222  	"float":       true,
  3223  	"__float128":  true,
  3224  	"half":        true,
  3225  }
  3226  
  3227  func (l *Literal) print(ps *printState) {
  3228  	isFloat := false
  3229  	if b, ok := l.Type.(*BuiltinType); ok {
  3230  		if suffix, ok := builtinTypeSuffix[b.Name]; ok {
  3231  			if l.Neg {
  3232  				ps.writeByte('-')
  3233  			}
  3234  			ps.writeString(l.Val)
  3235  			ps.writeString(suffix)
  3236  			return
  3237  		} else if b.Name == "bool" && !l.Neg {
  3238  			switch l.Val {
  3239  			case "0":
  3240  				ps.writeString("false")
  3241  				return
  3242  			case "1":
  3243  				ps.writeString("true")
  3244  				return
  3245  			}
  3246  		} else if b.Name == "decltype(nullptr)" && l.Val == "" {
  3247  			if ps.llvmStyle {
  3248  				ps.writeString("nullptr")
  3249  			} else {
  3250  				ps.print(l.Type)
  3251  			}
  3252  			return
  3253  		} else {
  3254  			isFloat = builtinTypeFloat[b.Name]
  3255  		}
  3256  	}
  3257  
  3258  	ps.writeByte('(')
  3259  	ps.print(l.Type)
  3260  	ps.writeByte(')')
  3261  
  3262  	if isFloat {
  3263  		ps.writeByte('[')
  3264  	}
  3265  	if l.Neg {
  3266  		ps.writeByte('-')
  3267  	}
  3268  	ps.writeString(l.Val)
  3269  	if isFloat {
  3270  		ps.writeByte(']')
  3271  	}
  3272  }
  3273  
  3274  func (l *Literal) Traverse(fn func(AST) bool) {
  3275  	if fn(l) {
  3276  		l.Type.Traverse(fn)
  3277  	}
  3278  }
  3279  
  3280  func (l *Literal) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3281  	if skip(l) {
  3282  		return nil
  3283  	}
  3284  	typ := l.Type.Copy(fn, skip)
  3285  	if typ == nil {
  3286  		return fn(l)
  3287  	}
  3288  	l = &Literal{Type: typ, Val: l.Val, Neg: l.Neg}
  3289  	if r := fn(l); r != nil {
  3290  		return r
  3291  	}
  3292  	return l
  3293  }
  3294  
  3295  func (l *Literal) GoString() string {
  3296  	return l.goString(0, "")
  3297  }
  3298  
  3299  func (l *Literal) goString(indent int, field string) string {
  3300  	var neg string
  3301  	if l.Neg {
  3302  		neg = " Neg: true"
  3303  	}
  3304  	return fmt.Sprintf("%*s%sLiteral:%s\n%s\n%*sVal: %s", indent, "", field,
  3305  		neg, l.Type.goString(indent+2, "Type: "),
  3306  		indent+2, "", l.Val)
  3307  }
  3308  
  3309  // StringLiteral is a string literal.
  3310  type StringLiteral struct {
  3311  	Type AST
  3312  }
  3313  
  3314  func (sl *StringLiteral) print(ps *printState) {
  3315  	ps.writeString(`"<`)
  3316  	sl.Type.print(ps)
  3317  	ps.writeString(`>"`)
  3318  }
  3319  
  3320  func (sl *StringLiteral) Traverse(fn func(AST) bool) {
  3321  	if fn(sl) {
  3322  		sl.Type.Traverse(fn)
  3323  	}
  3324  }
  3325  
  3326  func (sl *StringLiteral) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3327  	if skip(sl) {
  3328  		return nil
  3329  	}
  3330  	typ := sl.Type.Copy(fn, skip)
  3331  	if typ == nil {
  3332  		return fn(sl)
  3333  	}
  3334  	sl = &StringLiteral{Type: typ}
  3335  	if r := fn(sl); r != nil {
  3336  		return r
  3337  	}
  3338  	return sl
  3339  }
  3340  
  3341  func (sl *StringLiteral) GoString() string {
  3342  	return sl.goString(0, "")
  3343  }
  3344  
  3345  func (sl *StringLiteral) goString(indent int, field string) string {
  3346  	return fmt.Sprintf("%*s%sStringLiteral:\n%s", indent, "", field,
  3347  		sl.Type.goString(indent+2, ""))
  3348  }
  3349  
  3350  // LambdaExpr is a literal that is a lambda expression.
  3351  type LambdaExpr struct {
  3352  	Type AST
  3353  }
  3354  
  3355  func (le *LambdaExpr) print(ps *printState) {
  3356  	ps.writeString("[]")
  3357  	if cl, ok := le.Type.(*Closure); ok {
  3358  		cl.printTypes(ps)
  3359  	}
  3360  	ps.writeString("{...}")
  3361  }
  3362  
  3363  func (le *LambdaExpr) Traverse(fn func(AST) bool) {
  3364  	if fn(le) {
  3365  		le.Type.Traverse(fn)
  3366  	}
  3367  }
  3368  
  3369  func (le *LambdaExpr) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3370  	if skip(le) {
  3371  		return nil
  3372  	}
  3373  	typ := le.Type.Copy(fn, skip)
  3374  	if typ == nil {
  3375  		return fn(le)
  3376  	}
  3377  	le = &LambdaExpr{Type: typ}
  3378  	if r := fn(le); r != nil {
  3379  		return r
  3380  	}
  3381  	return le
  3382  }
  3383  
  3384  func (le *LambdaExpr) GoString() string {
  3385  	return le.goString(0, "")
  3386  }
  3387  
  3388  func (le *LambdaExpr) goString(indent int, field string) string {
  3389  	return fmt.Sprintf("%*s%sLambdaExpr:\n%s", indent, "", field,
  3390  		le.Type.goString(indent+2, ""))
  3391  }
  3392  
  3393  // ExprList is a list of expressions, typically arguments to a
  3394  // function call in an expression.
  3395  type ExprList struct {
  3396  	Exprs []AST
  3397  }
  3398  
  3399  func (el *ExprList) print(ps *printState) {
  3400  	for i, e := range el.Exprs {
  3401  		if i > 0 {
  3402  			ps.writeString(", ")
  3403  		}
  3404  		ps.print(e)
  3405  	}
  3406  }
  3407  
  3408  func (el *ExprList) Traverse(fn func(AST) bool) {
  3409  	if fn(el) {
  3410  		for _, e := range el.Exprs {
  3411  			e.Traverse(fn)
  3412  		}
  3413  	}
  3414  }
  3415  
  3416  func (el *ExprList) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3417  	if skip(el) {
  3418  		return nil
  3419  	}
  3420  	exprs := make([]AST, len(el.Exprs))
  3421  	changed := false
  3422  	for i, e := range el.Exprs {
  3423  		ec := e.Copy(fn, skip)
  3424  		if ec == nil {
  3425  			exprs[i] = e
  3426  		} else {
  3427  			exprs[i] = ec
  3428  			changed = true
  3429  		}
  3430  	}
  3431  	if !changed {
  3432  		return fn(el)
  3433  	}
  3434  	el = &ExprList{Exprs: exprs}
  3435  	if r := fn(el); r != nil {
  3436  		return r
  3437  	}
  3438  	return el
  3439  }
  3440  
  3441  func (el *ExprList) GoString() string {
  3442  	return el.goString(0, "")
  3443  }
  3444  
  3445  func (el *ExprList) goString(indent int, field string) string {
  3446  	if len(el.Exprs) == 0 {
  3447  		return fmt.Sprintf("%*s%sExprList: nil", indent, "", field)
  3448  	}
  3449  	s := fmt.Sprintf("%*s%sExprList:", indent, "", field)
  3450  	for i, e := range el.Exprs {
  3451  		s += "\n"
  3452  		s += e.goString(indent+2, fmt.Sprintf("%d: ", i))
  3453  	}
  3454  	return s
  3455  }
  3456  
  3457  // InitializerList is an initializer list: an optional type with a
  3458  // list of expressions.
  3459  type InitializerList struct {
  3460  	Type  AST
  3461  	Exprs AST
  3462  }
  3463  
  3464  func (il *InitializerList) print(ps *printState) {
  3465  	if il.Type != nil {
  3466  		ps.print(il.Type)
  3467  	}
  3468  	ps.writeByte('{')
  3469  	ps.print(il.Exprs)
  3470  	ps.writeByte('}')
  3471  }
  3472  
  3473  func (il *InitializerList) Traverse(fn func(AST) bool) {
  3474  	if fn(il) {
  3475  		if il.Type != nil {
  3476  			il.Type.Traverse(fn)
  3477  		}
  3478  		il.Exprs.Traverse(fn)
  3479  	}
  3480  }
  3481  
  3482  func (il *InitializerList) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3483  	if skip(il) {
  3484  		return nil
  3485  	}
  3486  	var typ AST
  3487  	if il.Type != nil {
  3488  		typ = il.Type.Copy(fn, skip)
  3489  	}
  3490  	exprs := il.Exprs.Copy(fn, skip)
  3491  	if typ == nil && exprs == nil {
  3492  		return fn(il)
  3493  	}
  3494  	if typ == nil {
  3495  		typ = il.Type
  3496  	}
  3497  	if exprs == nil {
  3498  		exprs = il.Exprs
  3499  	}
  3500  	il = &InitializerList{Type: typ, Exprs: exprs}
  3501  	if r := fn(il); r != nil {
  3502  		return r
  3503  	}
  3504  	return il
  3505  }
  3506  
  3507  func (il *InitializerList) GoString() string {
  3508  	return il.goString(0, "")
  3509  }
  3510  
  3511  func (il *InitializerList) goString(indent int, field string) string {
  3512  	var t string
  3513  	if il.Type == nil {
  3514  		t = fmt.Sprintf("%*sType: nil", indent+2, "")
  3515  	} else {
  3516  		t = il.Type.goString(indent+2, "Type: ")
  3517  	}
  3518  	return fmt.Sprintf("%*s%sInitializerList:\n%s\n%s", indent, "", field,
  3519  		t, il.Exprs.goString(indent+2, "Exprs: "))
  3520  }
  3521  
  3522  // DefaultArg holds a default argument for a local name.
  3523  type DefaultArg struct {
  3524  	Num int
  3525  	Arg AST
  3526  }
  3527  
  3528  func (da *DefaultArg) print(ps *printState) {
  3529  	if !ps.llvmStyle {
  3530  		fmt.Fprintf(&ps.buf, "{default arg#%d}::", da.Num+1)
  3531  	}
  3532  	ps.print(da.Arg)
  3533  }
  3534  
  3535  func (da *DefaultArg) Traverse(fn func(AST) bool) {
  3536  	if fn(da) {
  3537  		da.Arg.Traverse(fn)
  3538  	}
  3539  }
  3540  
  3541  func (da *DefaultArg) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3542  	if skip(da) {
  3543  		return nil
  3544  	}
  3545  	arg := da.Arg.Copy(fn, skip)
  3546  	if arg == nil {
  3547  		return fn(da)
  3548  	}
  3549  	da = &DefaultArg{Num: da.Num, Arg: arg}
  3550  	if r := fn(da); r != nil {
  3551  		return r
  3552  	}
  3553  	return da
  3554  }
  3555  
  3556  func (da *DefaultArg) GoString() string {
  3557  	return da.goString(0, "")
  3558  }
  3559  
  3560  func (da *DefaultArg) goString(indent int, field string) string {
  3561  	return fmt.Sprintf("%*s%sDefaultArg: Num: %d\n%s", indent, "", field, da.Num,
  3562  		da.Arg.goString(indent+2, "Arg: "))
  3563  }
  3564  
  3565  // Closure is a closure, or lambda expression.
  3566  type Closure struct {
  3567  	TemplateArgs []AST
  3568  	Types        []AST
  3569  	Num          int
  3570  }
  3571  
  3572  func (cl *Closure) print(ps *printState) {
  3573  	if ps.llvmStyle {
  3574  		if cl.Num == 0 {
  3575  			ps.writeString("'lambda'")
  3576  		} else {
  3577  			ps.writeString(fmt.Sprintf("'lambda%d'", cl.Num-1))
  3578  		}
  3579  	} else {
  3580  		ps.writeString("{lambda")
  3581  	}
  3582  	cl.printTypes(ps)
  3583  	if !ps.llvmStyle {
  3584  		ps.writeString(fmt.Sprintf("#%d}", cl.Num+1))
  3585  	}
  3586  }
  3587  
  3588  func (cl *Closure) printTypes(ps *printState) {
  3589  	if len(cl.TemplateArgs) > 0 {
  3590  		ps.writeString("<")
  3591  		for i, a := range cl.TemplateArgs {
  3592  			if i > 0 {
  3593  				ps.writeString(", ")
  3594  			}
  3595  			ps.print(a)
  3596  		}
  3597  		ps.writeString(">")
  3598  	}
  3599  	ps.writeString("(")
  3600  	for i, t := range cl.Types {
  3601  		if i > 0 {
  3602  			ps.writeString(", ")
  3603  		}
  3604  		ps.print(t)
  3605  	}
  3606  	ps.writeString(")")
  3607  }
  3608  
  3609  func (cl *Closure) Traverse(fn func(AST) bool) {
  3610  	if fn(cl) {
  3611  		for _, a := range cl.TemplateArgs {
  3612  			a.Traverse(fn)
  3613  		}
  3614  		for _, t := range cl.Types {
  3615  			t.Traverse(fn)
  3616  		}
  3617  	}
  3618  }
  3619  
  3620  func (cl *Closure) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3621  	if skip(cl) {
  3622  		return nil
  3623  	}
  3624  	changed := false
  3625  
  3626  	args := make([]AST, len(cl.TemplateArgs))
  3627  	for i, a := range cl.TemplateArgs {
  3628  		ac := a.Copy(fn, skip)
  3629  		if ac == nil {
  3630  			args[i] = a
  3631  		} else {
  3632  			args[i] = ac
  3633  			changed = true
  3634  		}
  3635  	}
  3636  
  3637  	types := make([]AST, len(cl.Types))
  3638  	for i, t := range cl.Types {
  3639  		tc := t.Copy(fn, skip)
  3640  		if tc == nil {
  3641  			types[i] = t
  3642  		} else {
  3643  			types[i] = tc
  3644  			changed = true
  3645  		}
  3646  	}
  3647  
  3648  	if !changed {
  3649  		return fn(cl)
  3650  	}
  3651  	cl = &Closure{TemplateArgs: args, Types: types, Num: cl.Num}
  3652  	if r := fn(cl); r != nil {
  3653  		return r
  3654  	}
  3655  	return cl
  3656  }
  3657  
  3658  func (cl *Closure) GoString() string {
  3659  	return cl.goString(0, "")
  3660  }
  3661  
  3662  func (cl *Closure) goString(indent int, field string) string {
  3663  	var args string
  3664  	if len(cl.TemplateArgs) == 0 {
  3665  		args = fmt.Sprintf("%*sTemplateArgs: nil", indent+2, "")
  3666  	} else {
  3667  		args = fmt.Sprintf("%*sTemplateArgs:", indent+2, "")
  3668  		for i, a := range cl.TemplateArgs {
  3669  			args += "\n"
  3670  			args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
  3671  		}
  3672  	}
  3673  	var types string
  3674  	if len(cl.Types) == 0 {
  3675  		types = fmt.Sprintf("%*sTypes: nil", indent+2, "")
  3676  	} else {
  3677  		types = fmt.Sprintf("%*sTypes:", indent+2, "")
  3678  		for i, t := range cl.Types {
  3679  			types += "\n"
  3680  			types += t.goString(indent+4, fmt.Sprintf("%d: ", i))
  3681  		}
  3682  	}
  3683  	return fmt.Sprintf("%*s%sClosure: Num: %d\n%s\n%s", indent, "", field,
  3684  		cl.Num, args, types)
  3685  }
  3686  
  3687  // StructuredBindings is a structured binding declaration.
  3688  type StructuredBindings struct {
  3689  	Bindings []AST
  3690  }
  3691  
  3692  func (sb *StructuredBindings) print(ps *printState) {
  3693  	ps.writeString("[")
  3694  	for i, b := range sb.Bindings {
  3695  		if i > 0 {
  3696  			ps.writeString(", ")
  3697  		}
  3698  		b.print(ps)
  3699  	}
  3700  	ps.writeString("]")
  3701  }
  3702  
  3703  func (sb *StructuredBindings) Traverse(fn func(AST) bool) {
  3704  	if fn(sb) {
  3705  		for _, b := range sb.Bindings {
  3706  			b.Traverse(fn)
  3707  		}
  3708  	}
  3709  }
  3710  
  3711  func (sb *StructuredBindings) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3712  	if skip(sb) {
  3713  		return nil
  3714  	}
  3715  	changed := false
  3716  	bindings := make([]AST, len(sb.Bindings))
  3717  	for i, b := range sb.Bindings {
  3718  		bc := b.Copy(fn, skip)
  3719  		if bc == nil {
  3720  			bindings[i] = b
  3721  		} else {
  3722  			bindings[i] = bc
  3723  			changed = true
  3724  		}
  3725  	}
  3726  	if !changed {
  3727  		return fn(sb)
  3728  	}
  3729  	sb = &StructuredBindings{Bindings: bindings}
  3730  	if r := fn(sb); r != nil {
  3731  		return r
  3732  	}
  3733  	return sb
  3734  }
  3735  
  3736  func (sb *StructuredBindings) GoString() string {
  3737  	return sb.goString(0, "")
  3738  }
  3739  
  3740  func (sb *StructuredBindings) goString(indent int, field string) string {
  3741  	var strb strings.Builder
  3742  	fmt.Fprintf(&strb, "%*s%sStructuredBinding:", indent, "", field)
  3743  	for _, b := range sb.Bindings {
  3744  		strb.WriteByte('\n')
  3745  		strb.WriteString(b.goString(indent+2, ""))
  3746  	}
  3747  	return strb.String()
  3748  }
  3749  
  3750  // UnnamedType is an unnamed type, that just has an index.
  3751  type UnnamedType struct {
  3752  	Num int
  3753  }
  3754  
  3755  func (ut *UnnamedType) print(ps *printState) {
  3756  	if ps.llvmStyle {
  3757  		if ut.Num == 0 {
  3758  			ps.writeString("'unnamed'")
  3759  		} else {
  3760  			ps.writeString(fmt.Sprintf("'unnamed%d'", ut.Num-1))
  3761  		}
  3762  	} else {
  3763  		ps.writeString(fmt.Sprintf("{unnamed type#%d}", ut.Num+1))
  3764  	}
  3765  }
  3766  
  3767  func (ut *UnnamedType) Traverse(fn func(AST) bool) {
  3768  	fn(ut)
  3769  }
  3770  
  3771  func (ut *UnnamedType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3772  	if skip(ut) {
  3773  		return nil
  3774  	}
  3775  	return fn(ut)
  3776  }
  3777  
  3778  func (ut *UnnamedType) GoString() string {
  3779  	return ut.goString(0, "")
  3780  }
  3781  
  3782  func (ut *UnnamedType) goString(indent int, field string) string {
  3783  	return fmt.Sprintf("%*s%sUnnamedType: Num: %d", indent, "", field, ut.Num)
  3784  }
  3785  
  3786  // Clone is a clone of a function, with a distinguishing suffix.
  3787  type Clone struct {
  3788  	Base   AST
  3789  	Suffix string
  3790  }
  3791  
  3792  func (c *Clone) print(ps *printState) {
  3793  	ps.print(c.Base)
  3794  	if ps.llvmStyle {
  3795  		ps.writeString(" (")
  3796  		ps.writeString(c.Suffix)
  3797  		ps.writeByte(')')
  3798  	} else {
  3799  		ps.writeString(fmt.Sprintf(" [clone %s]", c.Suffix))
  3800  	}
  3801  }
  3802  
  3803  func (c *Clone) Traverse(fn func(AST) bool) {
  3804  	if fn(c) {
  3805  		c.Base.Traverse(fn)
  3806  	}
  3807  }
  3808  
  3809  func (c *Clone) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3810  	if skip(c) {
  3811  		return nil
  3812  	}
  3813  	base := c.Base.Copy(fn, skip)
  3814  	if base == nil {
  3815  		return fn(c)
  3816  	}
  3817  	c = &Clone{Base: base, Suffix: c.Suffix}
  3818  	if r := fn(c); r != nil {
  3819  		return r
  3820  	}
  3821  	return c
  3822  }
  3823  
  3824  func (c *Clone) GoString() string {
  3825  	return c.goString(0, "")
  3826  }
  3827  
  3828  func (c *Clone) goString(indent int, field string) string {
  3829  	return fmt.Sprintf("%*s%sClone: Suffix: %s\n%s", indent, "", field,
  3830  		c.Suffix, c.Base.goString(indent+2, "Base: "))
  3831  }
  3832  
  3833  // Special is a special symbol, printed as a prefix plus another
  3834  // value.
  3835  type Special struct {
  3836  	Prefix string
  3837  	Val    AST
  3838  }
  3839  
  3840  func (s *Special) print(ps *printState) {
  3841  	prefix := s.Prefix
  3842  	if ps.llvmStyle {
  3843  		switch prefix {
  3844  		case "TLS wrapper function for ":
  3845  			prefix = "thread-local wrapper routine for "
  3846  		case "TLS init function for ":
  3847  			prefix = "thread-local initialization routine for "
  3848  		}
  3849  	}
  3850  	ps.writeString(prefix)
  3851  	ps.print(s.Val)
  3852  }
  3853  
  3854  func (s *Special) Traverse(fn func(AST) bool) {
  3855  	if fn(s) {
  3856  		s.Val.Traverse(fn)
  3857  	}
  3858  }
  3859  
  3860  func (s *Special) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3861  	if skip(s) {
  3862  		return nil
  3863  	}
  3864  	val := s.Val.Copy(fn, skip)
  3865  	if val == nil {
  3866  		return fn(s)
  3867  	}
  3868  	s = &Special{Prefix: s.Prefix, Val: val}
  3869  	if r := fn(s); r != nil {
  3870  		return r
  3871  	}
  3872  	return s
  3873  }
  3874  
  3875  func (s *Special) GoString() string {
  3876  	return s.goString(0, "")
  3877  }
  3878  
  3879  func (s *Special) goString(indent int, field string) string {
  3880  	return fmt.Sprintf("%*s%sSpecial: Prefix: %s\n%s", indent, "", field,
  3881  		s.Prefix, s.Val.goString(indent+2, "Val: "))
  3882  }
  3883  
  3884  // Special2 is like special, but uses two values.
  3885  type Special2 struct {
  3886  	Prefix string
  3887  	Val1   AST
  3888  	Middle string
  3889  	Val2   AST
  3890  }
  3891  
  3892  func (s *Special2) print(ps *printState) {
  3893  	ps.writeString(s.Prefix)
  3894  	ps.print(s.Val1)
  3895  	ps.writeString(s.Middle)
  3896  	ps.print(s.Val2)
  3897  }
  3898  
  3899  func (s *Special2) Traverse(fn func(AST) bool) {
  3900  	if fn(s) {
  3901  		s.Val1.Traverse(fn)
  3902  		s.Val2.Traverse(fn)
  3903  	}
  3904  }
  3905  
  3906  func (s *Special2) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3907  	if skip(s) {
  3908  		return nil
  3909  	}
  3910  	val1 := s.Val1.Copy(fn, skip)
  3911  	val2 := s.Val2.Copy(fn, skip)
  3912  	if val1 == nil && val2 == nil {
  3913  		return fn(s)
  3914  	}
  3915  	if val1 == nil {
  3916  		val1 = s.Val1
  3917  	}
  3918  	if val2 == nil {
  3919  		val2 = s.Val2
  3920  	}
  3921  	s = &Special2{Prefix: s.Prefix, Val1: val1, Middle: s.Middle, Val2: val2}
  3922  	if r := fn(s); r != nil {
  3923  		return r
  3924  	}
  3925  	return s
  3926  }
  3927  
  3928  func (s *Special2) GoString() string {
  3929  	return s.goString(0, "")
  3930  }
  3931  
  3932  func (s *Special2) goString(indent int, field string) string {
  3933  	return fmt.Sprintf("%*s%sSpecial2: Prefix: %s\n%s\n%*sMiddle: %s\n%s", indent, "", field,
  3934  		s.Prefix, s.Val1.goString(indent+2, "Val1: "),
  3935  		indent+2, "", s.Middle, s.Val2.goString(indent+2, "Val2: "))
  3936  }
  3937  
  3938  // EnableIf is used by clang for an enable_if attribute.
  3939  type EnableIf struct {
  3940  	Type AST
  3941  	Args []AST
  3942  }
  3943  
  3944  func (ei *EnableIf) print(ps *printState) {
  3945  	ps.print(ei.Type)
  3946  	ps.writeString(" [enable_if:")
  3947  	first := true
  3948  	for _, a := range ei.Args {
  3949  		if !first {
  3950  			ps.writeString(", ")
  3951  		}
  3952  		ps.print(a)
  3953  		first = false
  3954  	}
  3955  	ps.writeString("]")
  3956  }
  3957  
  3958  func (ei *EnableIf) Traverse(fn func(AST) bool) {
  3959  	if fn(ei) {
  3960  		ei.Type.Traverse(fn)
  3961  		for _, a := range ei.Args {
  3962  			a.Traverse(fn)
  3963  		}
  3964  	}
  3965  }
  3966  
  3967  func (ei *EnableIf) Copy(fn func(AST) AST, skip func(AST) bool) AST {
  3968  	if skip(ei) {
  3969  		return nil
  3970  	}
  3971  	typ := ei.Type.Copy(fn, skip)
  3972  	argsChanged := false
  3973  	args := make([]AST, len(ei.Args))
  3974  	for i, a := range ei.Args {
  3975  		ac := a.Copy(fn, skip)
  3976  		if ac == nil {
  3977  			args[i] = a
  3978  		} else {
  3979  			args[i] = ac
  3980  			argsChanged = true
  3981  		}
  3982  	}
  3983  	if typ == nil && !argsChanged {
  3984  		return fn(ei)
  3985  	}
  3986  	if typ == nil {
  3987  		typ = ei.Type
  3988  	}
  3989  	ei = &EnableIf{Type: typ, Args: args}
  3990  	if r := fn(ei); r != nil {
  3991  		return r
  3992  	}
  3993  	return ei
  3994  }
  3995  
  3996  func (ei *EnableIf) GoString() string {
  3997  	return ei.goString(0, "")
  3998  }
  3999  
  4000  func (ei *EnableIf) goString(indent int, field string) string {
  4001  	var args string
  4002  	if len(ei.Args) == 0 {
  4003  		args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
  4004  	} else {
  4005  		args = fmt.Sprintf("%*sArgs:", indent+2, "")
  4006  		for i, a := range ei.Args {
  4007  			args += "\n"
  4008  			args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
  4009  		}
  4010  	}
  4011  	return fmt.Sprintf("%*s%sEnableIf:\n%s\n%s", indent, "", field,
  4012  		ei.Type.goString(indent+2, "Type: "), args)
  4013  }
  4014  
  4015  // Print the inner types.
  4016  func (ps *printState) printInner(prefixOnly bool) []AST {
  4017  	var save []AST
  4018  	var psave *[]AST
  4019  	if prefixOnly {
  4020  		psave = &save
  4021  	}
  4022  	for len(ps.inner) > 0 {
  4023  		ps.printOneInner(psave)
  4024  	}
  4025  	return save
  4026  }
  4027  
  4028  // innerPrinter is an interface for types that can print themselves as
  4029  // inner types.
  4030  type innerPrinter interface {
  4031  	printInner(*printState)
  4032  }
  4033  
  4034  // Print the most recent inner type.  If save is not nil, only print
  4035  // prefixes.
  4036  func (ps *printState) printOneInner(save *[]AST) {
  4037  	if len(ps.inner) == 0 {
  4038  		panic("printOneInner called with no inner types")
  4039  	}
  4040  	ln := len(ps.inner)
  4041  	a := ps.inner[ln-1]
  4042  	ps.inner = ps.inner[:ln-1]
  4043  
  4044  	if save != nil {
  4045  		if _, ok := a.(*MethodWithQualifiers); ok {
  4046  			*save = append(*save, a)
  4047  			return
  4048  		}
  4049  	}
  4050  
  4051  	if ip, ok := a.(innerPrinter); ok {
  4052  		ip.printInner(ps)
  4053  	} else {
  4054  		ps.print(a)
  4055  	}
  4056  }
  4057  
  4058  // isEmpty returns whether printing a will not print anything.
  4059  func (ps *printState) isEmpty(a AST) bool {
  4060  	switch a := a.(type) {
  4061  	case *ArgumentPack:
  4062  		for _, a := range a.Args {
  4063  			if !ps.isEmpty(a) {
  4064  				return false
  4065  			}
  4066  		}
  4067  		return true
  4068  	case *ExprList:
  4069  		return len(a.Exprs) == 0
  4070  	case *PackExpansion:
  4071  		return a.Pack != nil && ps.isEmpty(a.Base)
  4072  	default:
  4073  		return false
  4074  	}
  4075  }
  4076  

View as plain text