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