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