Source file src/pkg/cmd/vendor/github.com/ianlancetaylor/demangle/ast.go
1
2
3
4
5 package demangle
6
7 import (
8 "bytes"
9 "fmt"
10 "strings"
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 Copy(copy func(AST) AST, skip func(AST) bool) AST
29
30
31 GoString() string
32 goString(indent int, field string) string
33 }
34
35
36 func ASTToString(a AST, options ...Option) string {
37 tparams := true
38 for _, o := range options {
39 switch o {
40 case NoTemplateParams:
41 tparams = false
42 }
43 }
44
45 ps := printState{tparams: tparams}
46 a.print(&ps)
47 return ps.buf.String()
48 }
49
50
51 type printState struct {
52 tparams bool
53
54 buf bytes.Buffer
55 last byte
56
57
58
59
60 inner []AST
61
62
63
64
65 printing []AST
66 }
67
68
69 func (ps *printState) writeByte(b byte) {
70 ps.last = b
71 ps.buf.WriteByte(b)
72 }
73
74
75 func (ps *printState) writeString(s string) {
76 if len(s) > 0 {
77 ps.last = s[len(s)-1]
78 }
79 ps.buf.WriteString(s)
80 }
81
82
83 func (ps *printState) print(a AST) {
84 c := 0
85 for _, v := range ps.printing {
86 if v == a {
87
88
89
90
91
92
93
94 c++
95 if c > 1 {
96 return
97 }
98 }
99 }
100 ps.printing = append(ps.printing, a)
101
102 a.print(ps)
103
104 ps.printing = ps.printing[:len(ps.printing)-1]
105 }
106
107
108 type Name struct {
109 Name string
110 }
111
112 func (n *Name) print(ps *printState) {
113 ps.writeString(n.Name)
114 }
115
116 func (n *Name) Traverse(fn func(AST) bool) {
117 fn(n)
118 }
119
120 func (n *Name) Copy(fn func(AST) AST, skip func(AST) bool) AST {
121 if skip(n) {
122 return nil
123 }
124 return fn(n)
125 }
126
127 func (n *Name) GoString() string {
128 return n.goString(0, "Name: ")
129 }
130
131 func (n *Name) goString(indent int, field string) string {
132 return fmt.Sprintf("%*s%s%s", indent, "", field, n.Name)
133 }
134
135
136 type Typed struct {
137 Name AST
138 Type AST
139 }
140
141 func (t *Typed) print(ps *printState) {
142
143
144 holdInner := ps.inner
145 defer func() { ps.inner = holdInner }()
146
147 ps.inner = []AST{t}
148 ps.print(t.Type)
149 if len(ps.inner) > 0 {
150
151
152 ps.writeByte(' ')
153 ps.print(t.Name)
154 }
155 }
156
157 func (t *Typed) printInner(ps *printState) {
158 ps.print(t.Name)
159 }
160
161 func (t *Typed) Traverse(fn func(AST) bool) {
162 if fn(t) {
163 t.Name.Traverse(fn)
164 t.Type.Traverse(fn)
165 }
166 }
167
168 func (t *Typed) Copy(fn func(AST) AST, skip func(AST) bool) AST {
169 if skip(t) {
170 return nil
171 }
172 name := t.Name.Copy(fn, skip)
173 typ := t.Type.Copy(fn, skip)
174 if name == nil && typ == nil {
175 return fn(t)
176 }
177 if name == nil {
178 name = t.Name
179 }
180 if typ == nil {
181 typ = t.Type
182 }
183 t = &Typed{Name: name, Type: typ}
184 if r := fn(t); r != nil {
185 return r
186 }
187 return t
188 }
189
190 func (t *Typed) GoString() string {
191 return t.goString(0, "")
192 }
193
194 func (t *Typed) goString(indent int, field string) string {
195 return fmt.Sprintf("%*s%sTyped:\n%s\n%s", indent, "", field,
196 t.Name.goString(indent+2, "Name: "),
197 t.Type.goString(indent+2, "Type: "))
198 }
199
200
201 type Qualified struct {
202 Scope AST
203 Name AST
204
205
206
207
208
209
210 LocalName bool
211 }
212
213 func (q *Qualified) print(ps *printState) {
214 ps.print(q.Scope)
215 ps.writeString("::")
216 ps.print(q.Name)
217 }
218
219 func (q *Qualified) Traverse(fn func(AST) bool) {
220 if fn(q) {
221 q.Scope.Traverse(fn)
222 q.Name.Traverse(fn)
223 }
224 }
225
226 func (q *Qualified) Copy(fn func(AST) AST, skip func(AST) bool) AST {
227 if skip(q) {
228 return nil
229 }
230 scope := q.Scope.Copy(fn, skip)
231 name := q.Name.Copy(fn, skip)
232 if scope == nil && name == nil {
233 return fn(q)
234 }
235 if scope == nil {
236 scope = q.Scope
237 }
238 if name == nil {
239 name = q.Name
240 }
241 q = &Qualified{Scope: scope, Name: name, LocalName: q.LocalName}
242 if r := fn(q); r != nil {
243 return r
244 }
245 return q
246 }
247
248 func (q *Qualified) GoString() string {
249 return q.goString(0, "")
250 }
251
252 func (q *Qualified) goString(indent int, field string) string {
253 s := ""
254 if q.LocalName {
255 s = " LocalName: true"
256 }
257 return fmt.Sprintf("%*s%sQualified:%s\n%s\n%s", indent, "", field,
258 s, q.Scope.goString(indent+2, "Scope: "),
259 q.Name.goString(indent+2, "Name: "))
260 }
261
262
263 type Template struct {
264 Name AST
265 Args []AST
266 }
267
268 func (t *Template) print(ps *printState) {
269
270
271 holdInner := ps.inner
272 defer func() { ps.inner = holdInner }()
273
274 ps.inner = nil
275 ps.print(t.Name)
276
277 if !ps.tparams {
278
279 return
280 }
281
282 if ps.last == '<' {
283 ps.writeByte(' ')
284 }
285
286 ps.writeByte('<')
287 first := true
288 for _, a := range t.Args {
289 if ps.isEmpty(a) {
290 continue
291 }
292 if !first {
293 ps.writeString(", ")
294 }
295 ps.print(a)
296 first = false
297 }
298 if ps.last == '>' {
299
300 ps.writeByte(' ')
301 }
302 ps.writeByte('>')
303 }
304
305 func (t *Template) Traverse(fn func(AST) bool) {
306 if fn(t) {
307 t.Name.Traverse(fn)
308 for _, a := range t.Args {
309 a.Traverse(fn)
310 }
311 }
312 }
313
314 func (t *Template) Copy(fn func(AST) AST, skip func(AST) bool) AST {
315 if skip(t) {
316 return nil
317 }
318 name := t.Name.Copy(fn, skip)
319 changed := name != nil
320 args := make([]AST, len(t.Args))
321 for i, a := range t.Args {
322 ac := a.Copy(fn, skip)
323 if ac == nil {
324 args[i] = a
325 } else {
326 args[i] = ac
327 changed = true
328 }
329 }
330 if !changed {
331 return fn(t)
332 }
333 if name == nil {
334 name = t.Name
335 }
336 t = &Template{Name: name, Args: args}
337 if r := fn(t); r != nil {
338 return r
339 }
340 return t
341 }
342
343 func (t *Template) GoString() string {
344 return t.goString(0, "")
345 }
346
347 func (t *Template) goString(indent int, field string) string {
348 var args string
349 if len(t.Args) == 0 {
350 args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
351 } else {
352 args = fmt.Sprintf("%*sArgs:", indent+2, "")
353 for i, a := range t.Args {
354 args += "\n"
355 args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
356 }
357 }
358 return fmt.Sprintf("%*s%sTemplate (%p):\n%s\n%s", indent, "", field, t,
359 t.Name.goString(indent+2, "Name: "), args)
360 }
361
362
363
364
365
366 type TemplateParam struct {
367 Index int
368 Template *Template
369 }
370
371 func (tp *TemplateParam) print(ps *printState) {
372 if tp.Template == nil {
373 panic("TemplateParam Template field is nil")
374 }
375 if tp.Index >= len(tp.Template.Args) {
376 panic("TemplateParam Index out of bounds")
377 }
378 ps.print(tp.Template.Args[tp.Index])
379 }
380
381 func (tp *TemplateParam) Traverse(fn func(AST) bool) {
382 fn(tp)
383
384 }
385
386 func (tp *TemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
387 if skip(tp) {
388 return nil
389 }
390 return fn(tp)
391 }
392
393 func (tp *TemplateParam) GoString() string {
394 return tp.goString(0, "")
395 }
396
397 func (tp *TemplateParam) goString(indent int, field string) string {
398 return fmt.Sprintf("%*s%sTemplateParam: Template: %p; Index %d", indent, "", field, tp.Template, tp.Index)
399 }
400
401
402 type Qualifiers []string
403
404
405 type TypeWithQualifiers struct {
406 Base AST
407 Qualifiers Qualifiers
408 }
409
410 func (twq *TypeWithQualifiers) print(ps *printState) {
411
412 ps.inner = append(ps.inner, twq)
413 ps.print(twq.Base)
414 if len(ps.inner) > 0 {
415
416 ps.writeByte(' ')
417 ps.writeString(strings.Join(twq.Qualifiers, " "))
418 ps.inner = ps.inner[:len(ps.inner)-1]
419 }
420 }
421
422
423 func (twq *TypeWithQualifiers) printInner(ps *printState) {
424 ps.writeByte(' ')
425 ps.writeString(strings.Join(twq.Qualifiers, " "))
426 }
427
428 func (twq *TypeWithQualifiers) Traverse(fn func(AST) bool) {
429 if fn(twq) {
430 twq.Base.Traverse(fn)
431 }
432 }
433
434 func (twq *TypeWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST {
435 if skip(twq) {
436 return nil
437 }
438 base := twq.Base.Copy(fn, skip)
439 if base == nil {
440 return fn(twq)
441 }
442 twq = &TypeWithQualifiers{Base: base, Qualifiers: twq.Qualifiers}
443 if r := fn(twq); r != nil {
444 return r
445 }
446 return twq
447 }
448
449 func (twq *TypeWithQualifiers) GoString() string {
450 return twq.goString(0, "")
451 }
452
453 func (twq *TypeWithQualifiers) goString(indent int, field string) string {
454 return fmt.Sprintf("%*s%sTypeWithQualifiers: Qualifiers: %s\n%s", indent, "", field,
455 twq.Qualifiers, twq.Base.goString(indent+2, "Base: "))
456 }
457
458
459 type MethodWithQualifiers struct {
460 Method AST
461 Qualifiers Qualifiers
462 RefQualifier string
463 }
464
465 func (mwq *MethodWithQualifiers) print(ps *printState) {
466
467 ps.inner = append(ps.inner, mwq)
468 ps.print(mwq.Method)
469 if len(ps.inner) > 0 {
470 if len(mwq.Qualifiers) > 0 {
471 ps.writeByte(' ')
472 ps.writeString(strings.Join(mwq.Qualifiers, " "))
473 }
474 if mwq.RefQualifier != "" {
475 ps.writeByte(' ')
476 ps.writeString(mwq.RefQualifier)
477 }
478 ps.inner = ps.inner[:len(ps.inner)-1]
479 }
480 }
481
482 func (mwq *MethodWithQualifiers) printInner(ps *printState) {
483 if len(mwq.Qualifiers) > 0 {
484 ps.writeByte(' ')
485 ps.writeString(strings.Join(mwq.Qualifiers, " "))
486 }
487 if mwq.RefQualifier != "" {
488 ps.writeByte(' ')
489 ps.writeString(mwq.RefQualifier)
490 }
491 }
492
493 func (mwq *MethodWithQualifiers) Traverse(fn func(AST) bool) {
494 if fn(mwq) {
495 mwq.Method.Traverse(fn)
496 }
497 }
498
499 func (mwq *MethodWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST {
500 if skip(mwq) {
501 return nil
502 }
503 method := mwq.Method.Copy(fn, skip)
504 if method == nil {
505 return fn(mwq)
506 }
507 mwq = &MethodWithQualifiers{Method: method, Qualifiers: mwq.Qualifiers, RefQualifier: mwq.RefQualifier}
508 if r := fn(mwq); r != nil {
509 return r
510 }
511 return mwq
512 }
513
514 func (mwq *MethodWithQualifiers) GoString() string {
515 return mwq.goString(0, "")
516 }
517
518 func (mwq *MethodWithQualifiers) goString(indent int, field string) string {
519 var q string
520 if len(mwq.Qualifiers) > 0 {
521 q += fmt.Sprintf(" Qualifiers: %v", mwq.Qualifiers)
522 }
523 if mwq.RefQualifier != "" {
524 if q != "" {
525 q += ";"
526 }
527 q += " RefQualifier: " + mwq.RefQualifier
528 }
529 return fmt.Sprintf("%*s%sMethodWithQualifiers:%s\n%s", indent, "", field,
530 q, mwq.Method.goString(indent+2, "Method: "))
531 }
532
533
534 type BuiltinType struct {
535 Name string
536 }
537
538 func (bt *BuiltinType) print(ps *printState) {
539 ps.writeString(bt.Name)
540 }
541
542 func (bt *BuiltinType) Traverse(fn func(AST) bool) {
543 fn(bt)
544 }
545
546 func (bt *BuiltinType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
547 if skip(bt) {
548 return nil
549 }
550 return fn(bt)
551 }
552
553 func (bt *BuiltinType) GoString() string {
554 return bt.goString(0, "")
555 }
556
557 func (bt *BuiltinType) goString(indent int, field string) string {
558 return fmt.Sprintf("%*s%sBuiltinType: %s", indent, "", field, bt.Name)
559 }
560
561
562
563 func printBase(ps *printState, qual, base AST) {
564 ps.inner = append(ps.inner, qual)
565 ps.print(base)
566 if len(ps.inner) > 0 {
567 qual.(innerPrinter).printInner(ps)
568 ps.inner = ps.inner[:len(ps.inner)-1]
569 }
570 }
571
572
573 type PointerType struct {
574 Base AST
575 }
576
577 func (pt *PointerType) print(ps *printState) {
578 printBase(ps, pt, pt.Base)
579 }
580
581 func (pt *PointerType) printInner(ps *printState) {
582 ps.writeString("*")
583 }
584
585 func (pt *PointerType) Traverse(fn func(AST) bool) {
586 if fn(pt) {
587 pt.Base.Traverse(fn)
588 }
589 }
590
591 func (pt *PointerType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
592 if skip(pt) {
593 return nil
594 }
595 base := pt.Base.Copy(fn, skip)
596 if base == nil {
597 return fn(pt)
598 }
599 pt = &PointerType{Base: base}
600 if r := fn(pt); r != nil {
601 return r
602 }
603 return pt
604 }
605
606 func (pt *PointerType) GoString() string {
607 return pt.goString(0, "")
608 }
609
610 func (pt *PointerType) goString(indent int, field string) string {
611 return fmt.Sprintf("%*s%sPointerType:\n%s", indent, "", field,
612 pt.Base.goString(indent+2, ""))
613 }
614
615
616 type ReferenceType struct {
617 Base AST
618 }
619
620 func (rt *ReferenceType) print(ps *printState) {
621 printBase(ps, rt, rt.Base)
622 }
623
624 func (rt *ReferenceType) printInner(ps *printState) {
625 ps.writeString("&")
626 }
627
628 func (rt *ReferenceType) Traverse(fn func(AST) bool) {
629 if fn(rt) {
630 rt.Base.Traverse(fn)
631 }
632 }
633
634 func (rt *ReferenceType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
635 if skip(rt) {
636 return nil
637 }
638 base := rt.Base.Copy(fn, skip)
639 if base == nil {
640 return fn(rt)
641 }
642 rt = &ReferenceType{Base: base}
643 if r := fn(rt); r != nil {
644 return r
645 }
646 return rt
647 }
648
649 func (rt *ReferenceType) GoString() string {
650 return rt.goString(0, "")
651 }
652
653 func (rt *ReferenceType) goString(indent int, field string) string {
654 return fmt.Sprintf("%*s%sReferenceType:\n%s", indent, "", field,
655 rt.Base.goString(indent+2, ""))
656 }
657
658
659 type RvalueReferenceType struct {
660 Base AST
661 }
662
663 func (rt *RvalueReferenceType) print(ps *printState) {
664 printBase(ps, rt, rt.Base)
665 }
666
667 func (rt *RvalueReferenceType) printInner(ps *printState) {
668 ps.writeString("&&")
669 }
670
671 func (rt *RvalueReferenceType) Traverse(fn func(AST) bool) {
672 if fn(rt) {
673 rt.Base.Traverse(fn)
674 }
675 }
676
677 func (rt *RvalueReferenceType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
678 if skip(rt) {
679 return nil
680 }
681 base := rt.Base.Copy(fn, skip)
682 if base == nil {
683 return fn(rt)
684 }
685 rt = &RvalueReferenceType{Base: base}
686 if r := fn(rt); r != nil {
687 return r
688 }
689 return rt
690 }
691
692 func (rt *RvalueReferenceType) GoString() string {
693 return rt.goString(0, "")
694 }
695
696 func (rt *RvalueReferenceType) goString(indent int, field string) string {
697 return fmt.Sprintf("%*s%sRvalueReferenceType:\n%s", indent, "", field,
698 rt.Base.goString(indent+2, ""))
699 }
700
701
702 type ComplexType struct {
703 Base AST
704 }
705
706 func (ct *ComplexType) print(ps *printState) {
707 printBase(ps, ct, ct.Base)
708 }
709
710 func (ct *ComplexType) printInner(ps *printState) {
711 ps.writeString(" _Complex")
712 }
713
714 func (ct *ComplexType) Traverse(fn func(AST) bool) {
715 if fn(ct) {
716 ct.Base.Traverse(fn)
717 }
718 }
719
720 func (ct *ComplexType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
721 if skip(ct) {
722 return nil
723 }
724 base := ct.Base.Copy(fn, skip)
725 if base == nil {
726 return fn(ct)
727 }
728 ct = &ComplexType{Base: base}
729 if r := fn(ct); r != nil {
730 return r
731 }
732 return ct
733 }
734
735 func (ct *ComplexType) GoString() string {
736 return ct.goString(0, "")
737 }
738
739 func (ct *ComplexType) goString(indent int, field string) string {
740 return fmt.Sprintf("%*s%sComplexType:\n%s", indent, "", field,
741 ct.Base.goString(indent+2, ""))
742 }
743
744
745 type ImaginaryType struct {
746 Base AST
747 }
748
749 func (it *ImaginaryType) print(ps *printState) {
750 printBase(ps, it, it.Base)
751 }
752
753 func (it *ImaginaryType) printInner(ps *printState) {
754 ps.writeString(" _Imaginary")
755 }
756
757 func (it *ImaginaryType) Traverse(fn func(AST) bool) {
758 if fn(it) {
759 it.Base.Traverse(fn)
760 }
761 }
762
763 func (it *ImaginaryType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
764 if skip(it) {
765 return nil
766 }
767 base := it.Base.Copy(fn, skip)
768 if base == nil {
769 return fn(it)
770 }
771 it = &ImaginaryType{Base: base}
772 if r := fn(it); r != nil {
773 return r
774 }
775 return it
776 }
777
778 func (it *ImaginaryType) GoString() string {
779 return it.goString(0, "")
780 }
781
782 func (it *ImaginaryType) goString(indent int, field string) string {
783 return fmt.Sprintf("%*s%sImaginaryType:\n%s", indent, "", field,
784 it.Base.goString(indent+2, ""))
785 }
786
787
788 type VendorQualifier struct {
789 Qualifier AST
790 Type AST
791 }
792
793 func (vq *VendorQualifier) print(ps *printState) {
794 ps.inner = append(ps.inner, vq)
795 ps.print(vq.Type)
796 if len(ps.inner) > 0 {
797 ps.printOneInner(nil)
798 }
799 }
800
801 func (vq *VendorQualifier) printInner(ps *printState) {
802 ps.writeByte(' ')
803 ps.print(vq.Qualifier)
804 }
805
806 func (vq *VendorQualifier) Traverse(fn func(AST) bool) {
807 if fn(vq) {
808 vq.Qualifier.Traverse(fn)
809 vq.Type.Traverse(fn)
810 }
811 }
812
813 func (vq *VendorQualifier) Copy(fn func(AST) AST, skip func(AST) bool) AST {
814 if skip(vq) {
815 return nil
816 }
817 qualifier := vq.Qualifier.Copy(fn, skip)
818 typ := vq.Type.Copy(fn, skip)
819 if qualifier == nil && typ == nil {
820 return fn(vq)
821 }
822 if qualifier == nil {
823 qualifier = vq.Qualifier
824 }
825 if typ == nil {
826 typ = vq.Type
827 }
828 vq = &VendorQualifier{Qualifier: qualifier, Type: vq.Type}
829 if r := fn(vq); r != nil {
830 return r
831 }
832 return vq
833 }
834
835 func (vq *VendorQualifier) GoString() string {
836 return vq.goString(0, "")
837 }
838
839 func (vq *VendorQualifier) goString(indent int, field string) string {
840 return fmt.Sprintf("%*s%sVendorQualifier:\n%s\n%s", indent, "", field,
841 vq.Qualifier.goString(indent+2, "Qualifier: "),
842 vq.Type.goString(indent+2, "Type: "))
843 }
844
845
846 type ArrayType struct {
847 Dimension AST
848 Element AST
849 }
850
851 func (at *ArrayType) print(ps *printState) {
852
853
854 ps.inner = append(ps.inner, at)
855 ps.print(at.Element)
856 if ln := len(ps.inner); ln > 0 {
857 ps.inner = ps.inner[:ln-1]
858 at.printDimension(ps)
859 }
860 }
861
862 func (at *ArrayType) printInner(ps *printState) {
863 at.printDimension(ps)
864 }
865
866
867 func (at *ArrayType) printDimension(ps *printState) {
868 space := " "
869 for len(ps.inner) > 0 {
870
871
872
873
874 in := ps.inner[len(ps.inner)-1]
875 if twq, ok := in.(*TypeWithQualifiers); ok {
876 in = twq.Base
877 }
878 if _, ok := in.(*ArrayType); ok {
879 if in == ps.inner[len(ps.inner)-1] {
880 space = ""
881 }
882 ps.printOneInner(nil)
883 } else {
884 ps.writeString(" (")
885 ps.printInner(false)
886 ps.writeByte(')')
887 }
888 }
889 ps.writeString(space)
890 ps.writeByte('[')
891 ps.print(at.Dimension)
892 ps.writeByte(']')
893 }
894
895 func (at *ArrayType) Traverse(fn func(AST) bool) {
896 if fn(at) {
897 at.Dimension.Traverse(fn)
898 at.Element.Traverse(fn)
899 }
900 }
901
902 func (at *ArrayType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
903 if skip(at) {
904 return nil
905 }
906 dimension := at.Dimension.Copy(fn, skip)
907 element := at.Element.Copy(fn, skip)
908 if dimension == nil && element == nil {
909 return fn(at)
910 }
911 if dimension == nil {
912 dimension = at.Dimension
913 }
914 if element == nil {
915 element = at.Element
916 }
917 at = &ArrayType{Dimension: dimension, Element: element}
918 if r := fn(at); r != nil {
919 return r
920 }
921 return at
922 }
923
924 func (at *ArrayType) GoString() string {
925 return at.goString(0, "")
926 }
927
928 func (at *ArrayType) goString(indent int, field string) string {
929 return fmt.Sprintf("%*s%sArrayType:\n%s\n%s", indent, "", field,
930 at.Dimension.goString(indent+2, "Dimension: "),
931 at.Element.goString(indent+2, "Element: "))
932 }
933
934
935
936 type FunctionType struct {
937 Return AST
938 Args []AST
939 }
940
941 func (ft *FunctionType) print(ps *printState) {
942 if ft.Return != nil {
943
944
945 ps.inner = append(ps.inner, ft)
946 ps.print(ft.Return)
947 if len(ps.inner) == 0 {
948
949 return
950 }
951 ps.inner = ps.inner[:len(ps.inner)-1]
952 ps.writeByte(' ')
953 }
954 ft.printArgs(ps)
955 }
956
957 func (ft *FunctionType) printInner(ps *printState) {
958 ft.printArgs(ps)
959 }
960
961
962
963 func (ft *FunctionType) printArgs(ps *printState) {
964 paren := false
965 space := false
966 for i := len(ps.inner) - 1; i >= 0; i-- {
967 switch ps.inner[i].(type) {
968 case *PointerType, *ReferenceType, *RvalueReferenceType:
969 paren = true
970 case *TypeWithQualifiers, *ComplexType, *ImaginaryType, *PtrMem:
971 space = true
972 paren = true
973 }
974 if paren {
975 break
976 }
977 }
978
979 if paren {
980 if !space && (ps.last != '(' && ps.last != '*') {
981 space = true
982 }
983 if space && ps.last != ' ' {
984 ps.writeByte(' ')
985 }
986 ps.writeByte('(')
987 }
988
989 save := ps.printInner(true)
990
991 if paren {
992 ps.writeByte(')')
993 }
994
995 ps.writeByte('(')
996 first := true
997 for _, a := range ft.Args {
998 if ps.isEmpty(a) {
999 continue
1000 }
1001 if !first {
1002 ps.writeString(", ")
1003 }
1004 ps.print(a)
1005 first = false
1006 }
1007 ps.writeByte(')')
1008
1009 ps.inner = save
1010 ps.printInner(false)
1011 }
1012
1013 func (ft *FunctionType) Traverse(fn func(AST) bool) {
1014 if fn(ft) {
1015 if ft.Return != nil {
1016 ft.Return.Traverse(fn)
1017 }
1018 for _, a := range ft.Args {
1019 a.Traverse(fn)
1020 }
1021 }
1022 }
1023
1024 func (ft *FunctionType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1025 if skip(ft) {
1026 return nil
1027 }
1028 changed := false
1029 var ret AST
1030 if ft.Return != nil {
1031 ret = ft.Return.Copy(fn, skip)
1032 if ret == nil {
1033 ret = ft.Return
1034 } else {
1035 changed = true
1036 }
1037 }
1038 args := make([]AST, len(ft.Args))
1039 for i, a := range ft.Args {
1040 ac := a.Copy(fn, skip)
1041 if ac == nil {
1042 args[i] = a
1043 } else {
1044 args[i] = ac
1045 changed = true
1046 }
1047 }
1048 if !changed {
1049 return fn(ft)
1050 }
1051 ft = &FunctionType{Return: ret, Args: args}
1052 if r := fn(ft); r != nil {
1053 return r
1054 }
1055 return ft
1056 }
1057
1058 func (ft *FunctionType) GoString() string {
1059 return ft.goString(0, "")
1060 }
1061
1062 func (ft *FunctionType) goString(indent int, field string) string {
1063 var r string
1064 if ft.Return == nil {
1065 r = fmt.Sprintf("%*sReturn: nil", indent+2, "")
1066 } else {
1067 r = ft.Return.goString(indent+2, "Return: ")
1068 }
1069 var args string
1070 if len(ft.Args) == 0 {
1071 args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
1072 } else {
1073 args = fmt.Sprintf("%*sArgs:", indent+2, "")
1074 for i, a := range ft.Args {
1075 args += "\n"
1076 args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
1077 }
1078 }
1079 return fmt.Sprintf("%*s%sFunctionType:\n%s\n%s", indent, "", field, r, args)
1080 }
1081
1082
1083
1084 type FunctionParam struct {
1085 Index int
1086 }
1087
1088 func (fp *FunctionParam) print(ps *printState) {
1089 if fp.Index == 0 {
1090 ps.writeString("this")
1091 } else {
1092 fmt.Fprintf(&ps.buf, "{parm#%d}", fp.Index)
1093 }
1094 }
1095
1096 func (fp *FunctionParam) Traverse(fn func(AST) bool) {
1097 fn(fp)
1098 }
1099
1100 func (fp *FunctionParam) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1101 if skip(fp) {
1102 return nil
1103 }
1104 return fn(fp)
1105 }
1106
1107 func (fp *FunctionParam) GoString() string {
1108 return fp.goString(0, "")
1109 }
1110
1111 func (fp *FunctionParam) goString(indent int, field string) string {
1112 return fmt.Sprintf("%*s%sFunctionParam: %d", indent, "", field, fp.Index)
1113 }
1114
1115
1116 type PtrMem struct {
1117 Class AST
1118 Member AST
1119 }
1120
1121 func (pm *PtrMem) print(ps *printState) {
1122 ps.inner = append(ps.inner, pm)
1123 ps.print(pm.Member)
1124 if len(ps.inner) > 0 {
1125 ps.printOneInner(nil)
1126 }
1127 }
1128
1129 func (pm *PtrMem) printInner(ps *printState) {
1130 if ps.last != '(' {
1131 ps.writeByte(' ')
1132 }
1133 ps.print(pm.Class)
1134 ps.writeString("::*")
1135 }
1136
1137 func (pm *PtrMem) Traverse(fn func(AST) bool) {
1138 if fn(pm) {
1139 pm.Class.Traverse(fn)
1140 pm.Member.Traverse(fn)
1141 }
1142 }
1143
1144 func (pm *PtrMem) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1145 if skip(pm) {
1146 return nil
1147 }
1148 class := pm.Class.Copy(fn, skip)
1149 member := pm.Member.Copy(fn, skip)
1150 if class == nil && member == nil {
1151 return fn(pm)
1152 }
1153 if class == nil {
1154 class = pm.Class
1155 }
1156 if member == nil {
1157 member = pm.Member
1158 }
1159 pm = &PtrMem{Class: class, Member: member}
1160 if r := fn(pm); r != nil {
1161 return r
1162 }
1163 return pm
1164 }
1165
1166 func (pm *PtrMem) GoString() string {
1167 return pm.goString(0, "")
1168 }
1169
1170 func (pm *PtrMem) goString(indent int, field string) string {
1171 return fmt.Sprintf("%*s%sPtrMem:\n%s\n%s", indent, "", field,
1172 pm.Class.goString(indent+2, "Class: "),
1173 pm.Member.goString(indent+2, "Member: "))
1174 }
1175
1176
1177 type FixedType struct {
1178 Base AST
1179 Accum bool
1180 Sat bool
1181 }
1182
1183 func (ft *FixedType) print(ps *printState) {
1184 if ft.Sat {
1185 ps.writeString("_Sat ")
1186 }
1187 if bt, ok := ft.Base.(*BuiltinType); ok && bt.Name == "int" {
1188
1189 } else {
1190 ps.print(ft.Base)
1191 ps.writeByte(' ')
1192 }
1193 if ft.Accum {
1194 ps.writeString("_Accum")
1195 } else {
1196 ps.writeString("_Fract")
1197 }
1198 }
1199
1200 func (ft *FixedType) Traverse(fn func(AST) bool) {
1201 if fn(ft) {
1202 ft.Base.Traverse(fn)
1203 }
1204 }
1205
1206 func (ft *FixedType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1207 if skip(ft) {
1208 return nil
1209 }
1210 base := ft.Base.Copy(fn, skip)
1211 if base == nil {
1212 return fn(ft)
1213 }
1214 ft = &FixedType{Base: base, Accum: ft.Accum, Sat: ft.Sat}
1215 if r := fn(ft); r != nil {
1216 return r
1217 }
1218 return ft
1219 }
1220
1221 func (ft *FixedType) GoString() string {
1222 return ft.goString(0, "")
1223 }
1224
1225 func (ft *FixedType) goString(indent int, field string) string {
1226 return fmt.Sprintf("%*s%sFixedType: Accum: %t; Sat: %t\n%s", indent, "", field,
1227 ft.Accum, ft.Sat,
1228 ft.Base.goString(indent+2, "Base: "))
1229 }
1230
1231
1232 type VectorType struct {
1233 Dimension AST
1234 Base AST
1235 }
1236
1237 func (vt *VectorType) print(ps *printState) {
1238 ps.inner = append(ps.inner, vt)
1239 ps.print(vt.Base)
1240 if len(ps.inner) > 0 {
1241 ps.printOneInner(nil)
1242 }
1243 }
1244
1245 func (vt *VectorType) printInner(ps *printState) {
1246 ps.writeString(" __vector(")
1247 ps.print(vt.Dimension)
1248 ps.writeByte(')')
1249 }
1250
1251 func (vt *VectorType) Traverse(fn func(AST) bool) {
1252 if fn(vt) {
1253 vt.Dimension.Traverse(fn)
1254 vt.Base.Traverse(fn)
1255 }
1256 }
1257
1258 func (vt *VectorType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1259 if skip(vt) {
1260 return nil
1261 }
1262 dimension := vt.Dimension.Copy(fn, skip)
1263 base := vt.Base.Copy(fn, skip)
1264 if dimension == nil && base == nil {
1265 return fn(vt)
1266 }
1267 if dimension == nil {
1268 dimension = vt.Dimension
1269 }
1270 if base == nil {
1271 base = vt.Base
1272 }
1273 vt = &VectorType{Dimension: dimension, Base: base}
1274 if r := fn(vt); r != nil {
1275 return r
1276 }
1277 return vt
1278 }
1279
1280 func (vt *VectorType) GoString() string {
1281 return vt.goString(0, "")
1282 }
1283
1284 func (vt *VectorType) goString(indent int, field string) string {
1285 return fmt.Sprintf("%*s%sVectorType:\n%s\n%s", indent, "", field,
1286 vt.Dimension.goString(indent+2, "Dimension: "),
1287 vt.Base.goString(indent+2, "Base: "))
1288 }
1289
1290
1291 type Decltype struct {
1292 Expr AST
1293 }
1294
1295 func (dt *Decltype) print(ps *printState) {
1296 ps.writeString("decltype (")
1297 ps.print(dt.Expr)
1298 ps.writeByte(')')
1299 }
1300
1301 func (dt *Decltype) Traverse(fn func(AST) bool) {
1302 if fn(dt) {
1303 dt.Expr.Traverse(fn)
1304 }
1305 }
1306
1307 func (dt *Decltype) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1308 if skip(dt) {
1309 return nil
1310 }
1311 expr := dt.Expr.Copy(fn, skip)
1312 if expr == nil {
1313 return fn(dt)
1314 }
1315 dt = &Decltype{Expr: expr}
1316 if r := fn(dt); r != nil {
1317 return r
1318 }
1319 return dt
1320 }
1321
1322 func (dt *Decltype) GoString() string {
1323 return dt.goString(0, "")
1324 }
1325
1326 func (dt *Decltype) goString(indent int, field string) string {
1327 return fmt.Sprintf("%*s%sDecltype:\n%s", indent, "", field,
1328 dt.Expr.goString(indent+2, "Expr: "))
1329 }
1330
1331
1332 type Operator struct {
1333 Name string
1334 }
1335
1336 func (op *Operator) print(ps *printState) {
1337 ps.writeString("operator")
1338 if isLower(op.Name[0]) {
1339 ps.writeByte(' ')
1340 }
1341 n := op.Name
1342 n = strings.TrimSuffix(n, " ")
1343 ps.writeString(n)
1344 }
1345
1346 func (op *Operator) Traverse(fn func(AST) bool) {
1347 fn(op)
1348 }
1349
1350 func (op *Operator) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1351 if skip(op) {
1352 return nil
1353 }
1354 return fn(op)
1355 }
1356
1357 func (op *Operator) GoString() string {
1358 return op.goString(0, "")
1359 }
1360
1361 func (op *Operator) goString(indent int, field string) string {
1362 return fmt.Sprintf("%*s%sOperator: %s", indent, "", field, op.Name)
1363 }
1364
1365
1366 type Constructor struct {
1367 Name AST
1368 }
1369
1370 func (c *Constructor) print(ps *printState) {
1371 ps.print(c.Name)
1372 }
1373
1374 func (c *Constructor) Traverse(fn func(AST) bool) {
1375 if fn(c) {
1376 c.Name.Traverse(fn)
1377 }
1378 }
1379
1380 func (c *Constructor) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1381 if skip(c) {
1382 return nil
1383 }
1384 name := c.Name.Copy(fn, skip)
1385 if name == nil {
1386 return fn(c)
1387 }
1388 c = &Constructor{Name: name}
1389 if r := fn(c); r != nil {
1390 return r
1391 }
1392 return c
1393 }
1394
1395 func (c *Constructor) GoString() string {
1396 return c.goString(0, "")
1397 }
1398
1399 func (c *Constructor) goString(indent int, field string) string {
1400 return fmt.Sprintf("%*s%sConstructor:\n%s", indent, "", field, c.Name.goString(indent+2, "Name: "))
1401 }
1402
1403
1404 type Destructor struct {
1405 Name AST
1406 }
1407
1408 func (d *Destructor) print(ps *printState) {
1409 ps.writeByte('~')
1410 ps.print(d.Name)
1411 }
1412
1413 func (d *Destructor) Traverse(fn func(AST) bool) {
1414 if fn(d) {
1415 d.Name.Traverse(fn)
1416 }
1417 }
1418
1419 func (d *Destructor) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1420 if skip(d) {
1421 return nil
1422 }
1423 name := d.Name.Copy(fn, skip)
1424 if name == nil {
1425 return fn(d)
1426 }
1427 d = &Destructor{Name: name}
1428 if r := fn(d); r != nil {
1429 return r
1430 }
1431 return d
1432 }
1433
1434 func (d *Destructor) GoString() string {
1435 return d.goString(0, "")
1436 }
1437
1438 func (d *Destructor) goString(indent int, field string) string {
1439 return fmt.Sprintf("%*s%sDestructor:\n%s", indent, "", field, d.Name.goString(indent+2, "Name: "))
1440 }
1441
1442
1443 type GlobalCDtor struct {
1444 Ctor bool
1445 Key AST
1446 }
1447
1448 func (gcd *GlobalCDtor) print(ps *printState) {
1449 ps.writeString("global ")
1450 if gcd.Ctor {
1451 ps.writeString("constructors")
1452 } else {
1453 ps.writeString("destructors")
1454 }
1455 ps.writeString(" keyed to ")
1456 ps.print(gcd.Key)
1457 }
1458
1459 func (gcd *GlobalCDtor) Traverse(fn func(AST) bool) {
1460 if fn(gcd) {
1461 gcd.Key.Traverse(fn)
1462 }
1463 }
1464
1465 func (gcd *GlobalCDtor) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1466 if skip(gcd) {
1467 return nil
1468 }
1469 key := gcd.Key.Copy(fn, skip)
1470 if key == nil {
1471 return fn(gcd)
1472 }
1473 gcd = &GlobalCDtor{Ctor: gcd.Ctor, Key: key}
1474 if r := fn(gcd); r != nil {
1475 return r
1476 }
1477 return gcd
1478 }
1479
1480 func (gcd *GlobalCDtor) GoString() string {
1481 return gcd.goString(0, "")
1482 }
1483
1484 func (gcd *GlobalCDtor) goString(indent int, field string) string {
1485 return fmt.Sprintf("%*s%sGlobalCDtor: Ctor: %t\n%s", indent, "", field,
1486 gcd.Ctor, gcd.Key.goString(indent+2, "Key: "))
1487 }
1488
1489
1490 type TaggedName struct {
1491 Name AST
1492 Tag AST
1493 }
1494
1495 func (t *TaggedName) print(ps *printState) {
1496 ps.print(t.Name)
1497 ps.writeString("[abi:")
1498 ps.print(t.Tag)
1499 ps.writeByte(']')
1500 }
1501
1502 func (t *TaggedName) Traverse(fn func(AST) bool) {
1503 if fn(t) {
1504 t.Name.Traverse(fn)
1505 t.Tag.Traverse(fn)
1506 }
1507 }
1508
1509 func (t *TaggedName) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1510 if skip(t) {
1511 return nil
1512 }
1513 name := t.Name.Copy(fn, skip)
1514 tag := t.Tag.Copy(fn, skip)
1515 if name == nil && tag == nil {
1516 return fn(t)
1517 }
1518 if name == nil {
1519 name = t.Name
1520 }
1521 if tag == nil {
1522 tag = t.Tag
1523 }
1524 t = &TaggedName{Name: name, Tag: tag}
1525 if r := fn(t); r != nil {
1526 return r
1527 }
1528 return t
1529 }
1530
1531 func (t *TaggedName) GoString() string {
1532 return t.goString(0, "")
1533 }
1534
1535 func (t *TaggedName) goString(indent int, field string) string {
1536 return fmt.Sprintf("%*s%sTaggedName:\n%s\n%s", indent, "", field,
1537 t.Name.goString(indent+2, "Name: "),
1538 t.Tag.goString(indent+2, "Tag: "))
1539 }
1540
1541
1542 type PackExpansion struct {
1543 Base AST
1544 Pack *ArgumentPack
1545 }
1546
1547 func (pe *PackExpansion) print(ps *printState) {
1548
1549
1550 if pe.Pack == nil {
1551 parenthesize(ps, pe.Base)
1552 ps.writeString("...")
1553 } else {
1554 ps.print(pe.Base)
1555 }
1556 }
1557
1558 func (pe *PackExpansion) Traverse(fn func(AST) bool) {
1559 if fn(pe) {
1560 pe.Base.Traverse(fn)
1561
1562 }
1563 }
1564
1565 func (pe *PackExpansion) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1566 if skip(pe) {
1567 return nil
1568 }
1569 base := pe.Base.Copy(fn, skip)
1570 if base == nil {
1571 return fn(pe)
1572 }
1573 pe = &PackExpansion{Base: base, Pack: pe.Pack}
1574 if r := fn(pe); r != nil {
1575 return r
1576 }
1577 return pe
1578 }
1579
1580 func (pe *PackExpansion) GoString() string {
1581 return pe.goString(0, "")
1582 }
1583
1584 func (pe *PackExpansion) goString(indent int, field string) string {
1585 return fmt.Sprintf("%*s%sPackExpansion: Pack: %p\n%s", indent, "", field,
1586 pe.Pack, pe.Base.goString(indent+2, "Base: "))
1587 }
1588
1589
1590 type ArgumentPack struct {
1591 Args []AST
1592 }
1593
1594 func (ap *ArgumentPack) print(ps *printState) {
1595 for i, a := range ap.Args {
1596 if i > 0 {
1597 ps.writeString(", ")
1598 }
1599 ps.print(a)
1600 }
1601 }
1602
1603 func (ap *ArgumentPack) Traverse(fn func(AST) bool) {
1604 if fn(ap) {
1605 for _, a := range ap.Args {
1606 a.Traverse(fn)
1607 }
1608 }
1609 }
1610
1611 func (ap *ArgumentPack) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1612 if skip(ap) {
1613 return nil
1614 }
1615 args := make([]AST, len(ap.Args))
1616 changed := false
1617 for i, a := range ap.Args {
1618 ac := a.Copy(fn, skip)
1619 if ac == nil {
1620 args[i] = a
1621 } else {
1622 args[i] = ac
1623 changed = true
1624 }
1625 }
1626 if !changed {
1627 return fn(ap)
1628 }
1629 ap = &ArgumentPack{Args: args}
1630 if r := fn(ap); r != nil {
1631 return r
1632 }
1633 return ap
1634 }
1635
1636 func (ap *ArgumentPack) GoString() string {
1637 return ap.goString(0, "")
1638 }
1639
1640 func (ap *ArgumentPack) goString(indent int, field string) string {
1641 if len(ap.Args) == 0 {
1642 return fmt.Sprintf("%*s%sArgumentPack: nil", indent, "", field)
1643 }
1644 s := fmt.Sprintf("%*s%sArgumentPack:", indent, "", field)
1645 for i, a := range ap.Args {
1646 s += "\n"
1647 s += a.goString(indent+2, fmt.Sprintf("%d: ", i))
1648 }
1649 return s
1650 }
1651
1652
1653 type SizeofPack struct {
1654 Pack *ArgumentPack
1655 }
1656
1657 func (sp *SizeofPack) print(ps *printState) {
1658 ps.writeString(fmt.Sprintf("%d", len(sp.Pack.Args)))
1659 }
1660
1661 func (sp *SizeofPack) Traverse(fn func(AST) bool) {
1662 fn(sp)
1663
1664 }
1665
1666 func (sp *SizeofPack) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1667 if skip(sp) {
1668 return nil
1669 }
1670 sp = &SizeofPack{Pack: sp.Pack}
1671 if r := fn(sp); r != nil {
1672 return r
1673 }
1674 return sp
1675 }
1676
1677 func (sp *SizeofPack) GoString() string {
1678 return sp.goString(0, "")
1679 }
1680
1681 func (sp *SizeofPack) goString(indent int, field string) string {
1682 return fmt.Sprintf("%*s%sSizeofPack: Pack: %p", indent, "", field, sp.Pack)
1683 }
1684
1685
1686
1687 type SizeofArgs struct {
1688 Args []AST
1689 }
1690
1691 func (sa *SizeofArgs) print(ps *printState) {
1692 c := 0
1693 for _, a := range sa.Args {
1694 if ap, ok := a.(*ArgumentPack); ok {
1695 c += len(ap.Args)
1696 } else if el, ok := a.(*ExprList); ok {
1697 c += len(el.Exprs)
1698 } else {
1699 c++
1700 }
1701 }
1702 ps.writeString(fmt.Sprintf("%d", c))
1703 }
1704
1705 func (sa *SizeofArgs) Traverse(fn func(AST) bool) {
1706 if fn(sa) {
1707 for _, a := range sa.Args {
1708 a.Traverse(fn)
1709 }
1710 }
1711 }
1712
1713 func (sa *SizeofArgs) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1714 if skip(sa) {
1715 return nil
1716 }
1717 changed := false
1718 args := make([]AST, len(sa.Args))
1719 for i, a := range sa.Args {
1720 ac := a.Copy(fn, skip)
1721 if ac == nil {
1722 args[i] = a
1723 } else {
1724 args[i] = ac
1725 changed = true
1726 }
1727 }
1728 if !changed {
1729 return fn(sa)
1730 }
1731 sa = &SizeofArgs{Args: args}
1732 if r := fn(sa); r != nil {
1733 return r
1734 }
1735 return sa
1736 }
1737
1738 func (sa *SizeofArgs) GoString() string {
1739 return sa.goString(0, "")
1740 }
1741
1742 func (sa *SizeofArgs) goString(indent int, field string) string {
1743 var args string
1744 if len(sa.Args) == 0 {
1745 args = fmt.Sprintf("%*sArgs: nil", indent+2, "")
1746 } else {
1747 args = fmt.Sprintf("%*sArgs:", indent+2, "")
1748 for i, a := range sa.Args {
1749 args += "\n"
1750 args += a.goString(indent+4, fmt.Sprintf("%d: ", i))
1751 }
1752 }
1753 return fmt.Sprintf("%*s%sSizeofArgs:\n%s", indent, "", field, args)
1754 }
1755
1756
1757 type Cast struct {
1758 To AST
1759 }
1760
1761 func (c *Cast) print(ps *printState) {
1762 ps.writeString("operator ")
1763 ps.print(c.To)
1764 }
1765
1766 func (c *Cast) Traverse(fn func(AST) bool) {
1767 if fn(c) {
1768 c.To.Traverse(fn)
1769 }
1770 }
1771
1772 func (c *Cast) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1773 if skip(c) {
1774 return nil
1775 }
1776 to := c.To.Copy(fn, skip)
1777 if to == nil {
1778 return fn(c)
1779 }
1780 c = &Cast{To: to}
1781 if r := fn(c); r != nil {
1782 return r
1783 }
1784 return c
1785 }
1786
1787 func (c *Cast) GoString() string {
1788 return c.goString(0, "")
1789 }
1790
1791 func (c *Cast) goString(indent int, field string) string {
1792 return fmt.Sprintf("%*s%sCast\n%s", indent, "", field,
1793 c.To.goString(indent+2, "To: "))
1794 }
1795
1796
1797
1798 func parenthesize(ps *printState, val AST) {
1799 paren := false
1800 switch v := val.(type) {
1801 case *Name, *InitializerList, *FunctionParam:
1802 case *Qualified:
1803 if v.LocalName {
1804 paren = true
1805 }
1806 default:
1807 paren = true
1808 }
1809 if paren {
1810 ps.writeByte('(')
1811 }
1812 ps.print(val)
1813 if paren {
1814 ps.writeByte(')')
1815 }
1816 }
1817
1818
1819
1820 type Nullary struct {
1821 Op AST
1822 }
1823
1824 func (n *Nullary) print(ps *printState) {
1825 if op, ok := n.Op.(*Operator); ok {
1826 ps.writeString(op.Name)
1827 } else {
1828 ps.print(n.Op)
1829 }
1830 }
1831
1832 func (n *Nullary) Traverse(fn func(AST) bool) {
1833 if fn(n) {
1834 n.Op.Traverse(fn)
1835 }
1836 }
1837
1838 func (n *Nullary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1839 if skip(n) {
1840 return nil
1841 }
1842 op := n.Op.Copy(fn, skip)
1843 if op == nil {
1844 return fn(n)
1845 }
1846 n = &Nullary{Op: op}
1847 if r := fn(n); r != nil {
1848 return r
1849 }
1850 return n
1851 }
1852
1853 func (n *Nullary) GoString() string {
1854 return n.goString(0, "")
1855 }
1856
1857 func (n *Nullary) goString(indent int, field string) string {
1858 return fmt.Sprintf("%*s%sNullary:\n%s", indent, "", field,
1859 n.Op.goString(indent+2, "Op: "))
1860 }
1861
1862
1863 type Unary struct {
1864 Op AST
1865 Expr AST
1866 Suffix bool
1867 SizeofType bool
1868 }
1869
1870 func (u *Unary) print(ps *printState) {
1871 expr := u.Expr
1872
1873
1874
1875 if op, ok := u.Op.(*Operator); ok && op.Name == "&" {
1876 if t, ok := expr.(*Typed); ok {
1877 if _, ok := t.Type.(*FunctionType); ok {
1878 expr = t.Name
1879 }
1880 }
1881 }
1882
1883 if u.Suffix {
1884 parenthesize(ps, expr)
1885 }
1886
1887 if op, ok := u.Op.(*Operator); ok {
1888 ps.writeString(op.Name)
1889 } else if c, ok := u.Op.(*Cast); ok {
1890 ps.writeByte('(')
1891 ps.print(c.To)
1892 ps.writeByte(')')
1893 } else {
1894 ps.print(u.Op)
1895 }
1896
1897 if !u.Suffix {
1898 if op, ok := u.Op.(*Operator); ok && op.Name == "::" {
1899
1900 ps.print(expr)
1901 } else if u.SizeofType {
1902
1903 ps.writeByte('(')
1904 ps.print(expr)
1905 ps.writeByte(')')
1906 } else {
1907 parenthesize(ps, expr)
1908 }
1909 }
1910 }
1911
1912 func (u *Unary) Traverse(fn func(AST) bool) {
1913 if fn(u) {
1914 u.Op.Traverse(fn)
1915 u.Expr.Traverse(fn)
1916 }
1917 }
1918
1919 func (u *Unary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
1920 if skip(u) {
1921 return nil
1922 }
1923 op := u.Op.Copy(fn, skip)
1924 expr := u.Expr.Copy(fn, skip)
1925 if op == nil && expr == nil {
1926 return fn(u)
1927 }
1928 if op == nil {
1929 op = u.Op
1930 }
1931 if expr == nil {
1932 expr = u.Expr
1933 }
1934 u = &Unary{Op: op, Expr: expr, Suffix: u.Suffix, SizeofType: u.SizeofType}
1935 if r := fn(u); r != nil {
1936 return r
1937 }
1938 return u
1939 }
1940
1941 func (u *Unary) GoString() string {
1942 return u.goString(0, "")
1943 }
1944
1945 func (u *Unary) goString(indent int, field string) string {
1946 var s string
1947 if u.Suffix {
1948 s = " Suffix: true"
1949 }
1950 if u.SizeofType {
1951 s += " SizeofType: true"
1952 }
1953 return fmt.Sprintf("%*s%sUnary:%s\n%s\n%s", indent, "", field,
1954 s, u.Op.goString(indent+2, "Op: "),
1955 u.Expr.goString(indent+2, "Expr: "))
1956 }
1957
1958
1959 type Binary struct {
1960 Op AST
1961 Left AST
1962 Right AST
1963 }
1964
1965 func (b *Binary) print(ps *printState) {
1966 op, _ := b.Op.(*Operator)
1967
1968 if op != nil && strings.Contains(op.Name, "cast") {
1969 ps.writeString(op.Name)
1970 ps.writeByte('<')
1971 ps.print(b.Left)
1972 ps.writeString(">(")
1973 ps.print(b.Right)
1974 ps.writeByte(')')
1975 return
1976 }
1977
1978
1979
1980
1981 if op != nil && op.Name == ">" {
1982 ps.writeByte('(')
1983 }
1984
1985 left := b.Left
1986
1987
1988
1989 if op != nil && op.Name == "()" {
1990 if ty, ok := b.Left.(*Typed); ok {
1991 left = ty.Name
1992 }
1993 }
1994
1995 parenthesize(ps, left)
1996
1997 if op != nil && op.Name == "[]" {
1998 ps.writeByte('[')
1999 ps.print(b.Right)
2000 ps.writeByte(']')
2001 return
2002 }
2003
2004 if op != nil {
2005 if op.Name != "()" {
2006 ps.writeString(op.Name)
2007 }
2008 } else {
2009 ps.print(b.Op)
2010 }
2011
2012 parenthesize(ps, b.Right)
2013
2014 if op != nil && op.Name == ">" {
2015 ps.writeByte(')')
2016 }
2017 }
2018
2019 func (b *Binary) Traverse(fn func(AST) bool) {
2020 if fn(b) {
2021 b.Op.Traverse(fn)
2022 b.Left.Traverse(fn)
2023 b.Right.Traverse(fn)
2024 }
2025 }
2026
2027 func (b *Binary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2028 if skip(b) {
2029 return nil
2030 }
2031 op := b.Op.Copy(fn, skip)
2032 left := b.Left.Copy(fn, skip)
2033 right := b.Right.Copy(fn, skip)
2034 if op == nil && left == nil && right == nil {
2035 return fn(b)
2036 }
2037 if op == nil {
2038 op = b.Op
2039 }
2040 if left == nil {
2041 left = b.Left
2042 }
2043 if right == nil {
2044 right = b.Right
2045 }
2046 b = &Binary{Op: op, Left: left, Right: right}
2047 if r := fn(b); r != nil {
2048 return r
2049 }
2050 return b
2051 }
2052
2053 func (b *Binary) GoString() string {
2054 return b.goString(0, "")
2055 }
2056
2057 func (b *Binary) goString(indent int, field string) string {
2058 return fmt.Sprintf("%*s%sBinary:\n%s\n%s\n%s", indent, "", field,
2059 b.Op.goString(indent+2, "Op: "),
2060 b.Left.goString(indent+2, "Left: "),
2061 b.Right.goString(indent+2, "Right: "))
2062 }
2063
2064
2065 type Trinary struct {
2066 Op AST
2067 First AST
2068 Second AST
2069 Third AST
2070 }
2071
2072 func (t *Trinary) print(ps *printState) {
2073 parenthesize(ps, t.First)
2074 ps.writeByte('?')
2075 parenthesize(ps, t.Second)
2076 ps.writeString(" : ")
2077 parenthesize(ps, t.Third)
2078 }
2079
2080 func (t *Trinary) Traverse(fn func(AST) bool) {
2081 if fn(t) {
2082 t.Op.Traverse(fn)
2083 t.First.Traverse(fn)
2084 t.Second.Traverse(fn)
2085 t.Third.Traverse(fn)
2086 }
2087 }
2088
2089 func (t *Trinary) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2090 if skip(t) {
2091 return nil
2092 }
2093 op := t.Op.Copy(fn, skip)
2094 first := t.First.Copy(fn, skip)
2095 second := t.Second.Copy(fn, skip)
2096 third := t.Third.Copy(fn, skip)
2097 if op == nil && first == nil && second == nil && third == nil {
2098 return fn(t)
2099 }
2100 if op == nil {
2101 op = t.Op
2102 }
2103 if first == nil {
2104 first = t.First
2105 }
2106 if second == nil {
2107 second = t.Second
2108 }
2109 if third == nil {
2110 third = t.Third
2111 }
2112 t = &Trinary{Op: op, First: first, Second: second, Third: third}
2113 if r := fn(t); r != nil {
2114 return r
2115 }
2116 return t
2117 }
2118
2119 func (t *Trinary) GoString() string {
2120 return t.goString(0, "")
2121 }
2122
2123 func (t *Trinary) goString(indent int, field string) string {
2124 return fmt.Sprintf("%*s%sTrinary:\n%s\n%s\n%s\n%s", indent, "", field,
2125 t.Op.goString(indent+2, "Op: "),
2126 t.First.goString(indent+2, "First: "),
2127 t.Second.goString(indent+2, "Second: "),
2128 t.Third.goString(indent+2, "Third: "))
2129 }
2130
2131
2132 type Fold struct {
2133 Left bool
2134 Op AST
2135 Arg1 AST
2136 Arg2 AST
2137 }
2138
2139 func (f *Fold) print(ps *printState) {
2140 op, _ := f.Op.(*Operator)
2141 printOp := func() {
2142 if op != nil {
2143 ps.writeString(op.Name)
2144 } else {
2145 ps.print(f.Op)
2146 }
2147 }
2148
2149 if f.Arg2 == nil {
2150 if f.Left {
2151 ps.writeString("(...")
2152 printOp()
2153 parenthesize(ps, f.Arg1)
2154 ps.writeString(")")
2155 } else {
2156 ps.writeString("(")
2157 parenthesize(ps, f.Arg1)
2158 printOp()
2159 ps.writeString("...)")
2160 }
2161 } else {
2162 ps.writeString("(")
2163 parenthesize(ps, f.Arg1)
2164 printOp()
2165 ps.writeString("...")
2166 printOp()
2167 parenthesize(ps, f.Arg2)
2168 ps.writeString(")")
2169 }
2170 }
2171
2172 func (f *Fold) Traverse(fn func(AST) bool) {
2173 if fn(f) {
2174 f.Op.Traverse(fn)
2175 f.Arg1.Traverse(fn)
2176 if f.Arg2 != nil {
2177 f.Arg2.Traverse(fn)
2178 }
2179 }
2180 }
2181
2182 func (f *Fold) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2183 if skip(f) {
2184 return nil
2185 }
2186 op := f.Op.Copy(fn, skip)
2187 arg1 := f.Arg1.Copy(fn, skip)
2188 var arg2 AST
2189 if f.Arg2 != nil {
2190 arg2 = f.Arg2.Copy(fn, skip)
2191 }
2192 if op == nil && arg1 == nil && arg2 == nil {
2193 return fn(f)
2194 }
2195 if op == nil {
2196 op = f.Op
2197 }
2198 if arg1 == nil {
2199 arg1 = f.Arg1
2200 }
2201 if arg2 == nil {
2202 arg2 = f.Arg2
2203 }
2204 f = &Fold{Left: f.Left, Op: op, Arg1: arg1, Arg2: arg2}
2205 if r := fn(f); r != nil {
2206 return r
2207 }
2208 return f
2209 }
2210
2211 func (f *Fold) GoString() string {
2212 return f.goString(0, "")
2213 }
2214
2215 func (f *Fold) goString(indent int, field string) string {
2216 if f.Arg2 == nil {
2217 return fmt.Sprintf("%*s%sFold: Left: %t\n%s\n%s", indent, "", field,
2218 f.Left, f.Op.goString(indent+2, "Op: "),
2219 f.Arg1.goString(indent+2, "Arg1: "))
2220 } else {
2221 return fmt.Sprintf("%*s%sFold: Left: %t\n%s\n%s\n%s", indent, "", field,
2222 f.Left, f.Op.goString(indent+2, "Op: "),
2223 f.Arg1.goString(indent+2, "Arg1: "),
2224 f.Arg2.goString(indent+2, "Arg2: "))
2225 }
2226 }
2227
2228
2229 type New struct {
2230 Op AST
2231 Place AST
2232 Type AST
2233 Init AST
2234 }
2235
2236 func (n *New) print(ps *printState) {
2237
2238 ps.writeString("new ")
2239 if n.Place != nil {
2240 parenthesize(ps, n.Place)
2241 ps.writeByte(' ')
2242 }
2243 ps.print(n.Type)
2244 if n.Init != nil {
2245 parenthesize(ps, n.Init)
2246 }
2247 }
2248
2249 func (n *New) Traverse(fn func(AST) bool) {
2250 if fn(n) {
2251 n.Op.Traverse(fn)
2252 if n.Place != nil {
2253 n.Place.Traverse(fn)
2254 }
2255 n.Type.Traverse(fn)
2256 if n.Init != nil {
2257 n.Init.Traverse(fn)
2258 }
2259 }
2260 }
2261
2262 func (n *New) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2263 if skip(n) {
2264 return nil
2265 }
2266 op := n.Op.Copy(fn, skip)
2267 var place AST
2268 if n.Place != nil {
2269 place = n.Place.Copy(fn, skip)
2270 }
2271 typ := n.Type.Copy(fn, skip)
2272 var ini AST
2273 if n.Init != nil {
2274 ini = n.Init.Copy(fn, skip)
2275 }
2276 if op == nil && place == nil && typ == nil && ini == nil {
2277 return fn(n)
2278 }
2279 if op == nil {
2280 op = n.Op
2281 }
2282 if place == nil {
2283 place = n.Place
2284 }
2285 if typ == nil {
2286 typ = n.Type
2287 }
2288 if ini == nil {
2289 ini = n.Init
2290 }
2291 n = &New{Op: op, Place: place, Type: typ, Init: ini}
2292 if r := fn(n); r != nil {
2293 return r
2294 }
2295 return n
2296 }
2297
2298 func (n *New) GoString() string {
2299 return n.goString(0, "")
2300 }
2301
2302 func (n *New) goString(indent int, field string) string {
2303 var place string
2304 if n.Place == nil {
2305 place = fmt.Sprintf("%*sPlace: nil", indent, "")
2306 } else {
2307 place = n.Place.goString(indent+2, "Place: ")
2308 }
2309 var ini string
2310 if n.Init == nil {
2311 ini = fmt.Sprintf("%*sInit: nil", indent, "")
2312 } else {
2313 ini = n.Init.goString(indent+2, "Init: ")
2314 }
2315 return fmt.Sprintf("%*s%sNew:\n%s\n%s\n%s\n%s", indent, "", field,
2316 n.Op.goString(indent+2, "Op: "), place,
2317 n.Type.goString(indent+2, "Type: "), ini)
2318 }
2319
2320
2321 type Literal struct {
2322 Type AST
2323 Val string
2324 Neg bool
2325 }
2326
2327
2328 var builtinTypeSuffix = map[string]string{
2329 "int": "",
2330 "unsigned int": "u",
2331 "long": "l",
2332 "unsigned long": "ul",
2333 "long long": "ll",
2334 "unsigned long long": "ull",
2335 }
2336
2337
2338 var builtinTypeFloat = map[string]bool{
2339 "double": true,
2340 "long double": true,
2341 "float": true,
2342 "__float128": true,
2343 "half": true,
2344 }
2345
2346 func (l *Literal) print(ps *printState) {
2347 isFloat := false
2348 if b, ok := l.Type.(*BuiltinType); ok {
2349 if suffix, ok := builtinTypeSuffix[b.Name]; ok {
2350 if l.Neg {
2351 ps.writeByte('-')
2352 }
2353 ps.writeString(l.Val)
2354 ps.writeString(suffix)
2355 return
2356 } else if b.Name == "bool" && !l.Neg {
2357 switch l.Val {
2358 case "0":
2359 ps.writeString("false")
2360 return
2361 case "1":
2362 ps.writeString("true")
2363 return
2364 }
2365 } else {
2366 isFloat = builtinTypeFloat[b.Name]
2367 }
2368 }
2369
2370 ps.writeByte('(')
2371 ps.print(l.Type)
2372 ps.writeByte(')')
2373
2374 if isFloat {
2375 ps.writeByte('[')
2376 }
2377 if l.Neg {
2378 ps.writeByte('-')
2379 }
2380 ps.writeString(l.Val)
2381 if isFloat {
2382 ps.writeByte(']')
2383 }
2384 }
2385
2386 func (l *Literal) Traverse(fn func(AST) bool) {
2387 if fn(l) {
2388 l.Type.Traverse(fn)
2389 }
2390 }
2391
2392 func (l *Literal) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2393 if skip(l) {
2394 return nil
2395 }
2396 typ := l.Type.Copy(fn, skip)
2397 if typ == nil {
2398 return fn(l)
2399 }
2400 l = &Literal{Type: typ, Val: l.Val, Neg: l.Neg}
2401 if r := fn(l); r != nil {
2402 return r
2403 }
2404 return l
2405 }
2406
2407 func (l *Literal) GoString() string {
2408 return l.goString(0, "")
2409 }
2410
2411 func (l *Literal) goString(indent int, field string) string {
2412 var neg string
2413 if l.Neg {
2414 neg = " Neg: true"
2415 }
2416 return fmt.Sprintf("%*s%sLiteral:%s\n%s\n%*sVal: %s", indent, "", field,
2417 neg, l.Type.goString(indent+2, "Type: "),
2418 indent+2, "", l.Val)
2419 }
2420
2421
2422
2423 type ExprList struct {
2424 Exprs []AST
2425 }
2426
2427 func (el *ExprList) print(ps *printState) {
2428 for i, e := range el.Exprs {
2429 if i > 0 {
2430 ps.writeString(", ")
2431 }
2432 ps.print(e)
2433 }
2434 }
2435
2436 func (el *ExprList) Traverse(fn func(AST) bool) {
2437 if fn(el) {
2438 for _, e := range el.Exprs {
2439 e.Traverse(fn)
2440 }
2441 }
2442 }
2443
2444 func (el *ExprList) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2445 if skip(el) {
2446 return nil
2447 }
2448 exprs := make([]AST, len(el.Exprs))
2449 changed := false
2450 for i, e := range el.Exprs {
2451 ec := e.Copy(fn, skip)
2452 if ec == nil {
2453 exprs[i] = e
2454 } else {
2455 exprs[i] = ec
2456 changed = true
2457 }
2458 }
2459 if !changed {
2460 return fn(el)
2461 }
2462 el = &ExprList{Exprs: exprs}
2463 if r := fn(el); r != nil {
2464 return r
2465 }
2466 return el
2467 }
2468
2469 func (el *ExprList) GoString() string {
2470 return el.goString(0, "")
2471 }
2472
2473 func (el *ExprList) goString(indent int, field string) string {
2474 if len(el.Exprs) == 0 {
2475 return fmt.Sprintf("%*s%sExprList: nil", indent, "", field)
2476 }
2477 s := fmt.Sprintf("%*s%sExprList:", indent, "", field)
2478 for i, e := range el.Exprs {
2479 s += "\n"
2480 s += e.goString(indent+2, fmt.Sprintf("%d: ", i))
2481 }
2482 return s
2483 }
2484
2485
2486
2487 type InitializerList struct {
2488 Type AST
2489 Exprs AST
2490 }
2491
2492 func (il *InitializerList) print(ps *printState) {
2493 if il.Type != nil {
2494 ps.print(il.Type)
2495 }
2496 ps.writeByte('{')
2497 ps.print(il.Exprs)
2498 ps.writeByte('}')
2499 }
2500
2501 func (il *InitializerList) Traverse(fn func(AST) bool) {
2502 if fn(il) {
2503 if il.Type != nil {
2504 il.Type.Traverse(fn)
2505 }
2506 il.Exprs.Traverse(fn)
2507 }
2508 }
2509
2510 func (il *InitializerList) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2511 if skip(il) {
2512 return nil
2513 }
2514 var typ AST
2515 if il.Type != nil {
2516 typ = il.Type.Copy(fn, skip)
2517 }
2518 exprs := il.Exprs.Copy(fn, skip)
2519 if typ == nil && exprs == nil {
2520 return fn(il)
2521 }
2522 if typ == nil {
2523 typ = il.Type
2524 }
2525 if exprs == nil {
2526 exprs = il.Exprs
2527 }
2528 il = &InitializerList{Type: typ, Exprs: exprs}
2529 if r := fn(il); r != nil {
2530 return r
2531 }
2532 return il
2533 }
2534
2535 func (il *InitializerList) GoString() string {
2536 return il.goString(0, "")
2537 }
2538
2539 func (il *InitializerList) goString(indent int, field string) string {
2540 var t string
2541 if il.Type == nil {
2542 t = fmt.Sprintf("%*sType: nil", indent+2, "")
2543 } else {
2544 t = il.Type.goString(indent+2, "Type: ")
2545 }
2546 return fmt.Sprintf("%*s%sInitializerList:\n%s\n%s", indent, "", field,
2547 t, il.Exprs.goString(indent+2, "Exprs: "))
2548 }
2549
2550
2551 type DefaultArg struct {
2552 Num int
2553 Arg AST
2554 }
2555
2556 func (da *DefaultArg) print(ps *printState) {
2557 fmt.Fprintf(&ps.buf, "{default arg#%d}::", da.Num+1)
2558 ps.print(da.Arg)
2559 }
2560
2561 func (da *DefaultArg) Traverse(fn func(AST) bool) {
2562 if fn(da) {
2563 da.Arg.Traverse(fn)
2564 }
2565 }
2566
2567 func (da *DefaultArg) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2568 if skip(da) {
2569 return nil
2570 }
2571 arg := da.Arg.Copy(fn, skip)
2572 if arg == nil {
2573 return fn(da)
2574 }
2575 da = &DefaultArg{Num: da.Num, Arg: arg}
2576 if r := fn(da); r != nil {
2577 return r
2578 }
2579 return da
2580 }
2581
2582 func (da *DefaultArg) GoString() string {
2583 return da.goString(0, "")
2584 }
2585
2586 func (da *DefaultArg) goString(indent int, field string) string {
2587 return fmt.Sprintf("%*s%sDefaultArg: Num: %d\n%s", indent, "", field, da.Num,
2588 da.Arg.goString(indent+2, "Arg: "))
2589 }
2590
2591
2592 type Closure struct {
2593 Types []AST
2594 Num int
2595 }
2596
2597 func (cl *Closure) print(ps *printState) {
2598 ps.writeString("{lambda(")
2599 for i, t := range cl.Types {
2600 if i > 0 {
2601 ps.writeString(", ")
2602 }
2603 ps.print(t)
2604 }
2605 ps.writeString(fmt.Sprintf(")#%d}", cl.Num+1))
2606 }
2607
2608 func (cl *Closure) Traverse(fn func(AST) bool) {
2609 if fn(cl) {
2610 for _, t := range cl.Types {
2611 t.Traverse(fn)
2612 }
2613 }
2614 }
2615
2616 func (cl *Closure) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2617 if skip(cl) {
2618 return nil
2619 }
2620 types := make([]AST, len(cl.Types))
2621 changed := false
2622 for i, t := range cl.Types {
2623 tc := t.Copy(fn, skip)
2624 if tc == nil {
2625 types[i] = t
2626 } else {
2627 types[i] = tc
2628 changed = true
2629 }
2630 }
2631 if !changed {
2632 return fn(cl)
2633 }
2634 cl = &Closure{Types: types, Num: cl.Num}
2635 if r := fn(cl); r != nil {
2636 return r
2637 }
2638 return cl
2639 }
2640
2641 func (cl *Closure) GoString() string {
2642 return cl.goString(0, "")
2643 }
2644
2645 func (cl *Closure) goString(indent int, field string) string {
2646 var types string
2647 if len(cl.Types) == 0 {
2648 types = fmt.Sprintf("%*sTypes: nil", indent+2, "")
2649 } else {
2650 types = fmt.Sprintf("%*sTypes:", indent+2, "")
2651 for i, t := range cl.Types {
2652 types += "\n"
2653 types += t.goString(indent+4, fmt.Sprintf("%d: ", i))
2654 }
2655 }
2656 return fmt.Sprintf("%*s%sClosure: Num: %d\n%s", indent, "", field, cl.Num, types)
2657 }
2658
2659
2660 type UnnamedType struct {
2661 Num int
2662 }
2663
2664 func (ut *UnnamedType) print(ps *printState) {
2665 ps.writeString(fmt.Sprintf("{unnamed type#%d}", ut.Num+1))
2666 }
2667
2668 func (ut *UnnamedType) Traverse(fn func(AST) bool) {
2669 fn(ut)
2670 }
2671
2672 func (ut *UnnamedType) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2673 if skip(ut) {
2674 return nil
2675 }
2676 return fn(ut)
2677 }
2678
2679 func (ut *UnnamedType) GoString() string {
2680 return ut.goString(0, "")
2681 }
2682
2683 func (ut *UnnamedType) goString(indent int, field string) string {
2684 return fmt.Sprintf("%*s%sUnnamedType: Num: %d", indent, "", field, ut.Num)
2685 }
2686
2687
2688 type Clone struct {
2689 Base AST
2690 Suffix string
2691 }
2692
2693 func (c *Clone) print(ps *printState) {
2694 ps.print(c.Base)
2695 ps.writeString(fmt.Sprintf(" [clone %s]", c.Suffix))
2696 }
2697
2698 func (c *Clone) Traverse(fn func(AST) bool) {
2699 if fn(c) {
2700 c.Base.Traverse(fn)
2701 }
2702 }
2703
2704 func (c *Clone) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2705 if skip(c) {
2706 return nil
2707 }
2708 base := c.Base.Copy(fn, skip)
2709 if base == nil {
2710 return fn(c)
2711 }
2712 c = &Clone{Base: base, Suffix: c.Suffix}
2713 if r := fn(c); r != nil {
2714 return r
2715 }
2716 return c
2717 }
2718
2719 func (c *Clone) GoString() string {
2720 return c.goString(0, "")
2721 }
2722
2723 func (c *Clone) goString(indent int, field string) string {
2724 return fmt.Sprintf("%*s%sClone: Suffix: %s\n%s", indent, "", field,
2725 c.Suffix, c.Base.goString(indent+2, "Base: "))
2726 }
2727
2728
2729
2730 type Special struct {
2731 Prefix string
2732 Val AST
2733 }
2734
2735 func (s *Special) print(ps *printState) {
2736 ps.writeString(s.Prefix)
2737 ps.print(s.Val)
2738 }
2739
2740 func (s *Special) Traverse(fn func(AST) bool) {
2741 if fn(s) {
2742 s.Val.Traverse(fn)
2743 }
2744 }
2745
2746 func (s *Special) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2747 if skip(s) {
2748 return nil
2749 }
2750 val := s.Val.Copy(fn, skip)
2751 if val == nil {
2752 return fn(s)
2753 }
2754 s = &Special{Prefix: s.Prefix, Val: val}
2755 if r := fn(s); r != nil {
2756 return r
2757 }
2758 return s
2759 }
2760
2761 func (s *Special) GoString() string {
2762 return s.goString(0, "")
2763 }
2764
2765 func (s *Special) goString(indent int, field string) string {
2766 return fmt.Sprintf("%*s%sSpecial: Prefix: %s\n%s", indent, "", field,
2767 s.Prefix, s.Val.goString(indent+2, "Val: "))
2768 }
2769
2770
2771 type Special2 struct {
2772 Prefix string
2773 Val1 AST
2774 Middle string
2775 Val2 AST
2776 }
2777
2778 func (s *Special2) print(ps *printState) {
2779 ps.writeString(s.Prefix)
2780 ps.print(s.Val1)
2781 ps.writeString(s.Middle)
2782 ps.print(s.Val2)
2783 }
2784
2785 func (s *Special2) Traverse(fn func(AST) bool) {
2786 if fn(s) {
2787 s.Val1.Traverse(fn)
2788 s.Val2.Traverse(fn)
2789 }
2790 }
2791
2792 func (s *Special2) Copy(fn func(AST) AST, skip func(AST) bool) AST {
2793 if skip(s) {
2794 return nil
2795 }
2796 val1 := s.Val1.Copy(fn, skip)
2797 val2 := s.Val2.Copy(fn, skip)
2798 if val1 == nil && val2 == nil {
2799 return fn(s)
2800 }
2801 if val1 == nil {
2802 val1 = s.Val1
2803 }
2804 if val2 == nil {
2805 val2 = s.Val2
2806 }
2807 s = &Special2{Prefix: s.Prefix, Val1: val1, Middle: s.Middle, Val2: val2}
2808 if r := fn(s); r != nil {
2809 return r
2810 }
2811 return s
2812 }
2813
2814 func (s *Special2) GoString() string {
2815 return s.goString(0, "")
2816 }
2817
2818 func (s *Special2) goString(indent int, field string) string {
2819 return fmt.Sprintf("%*s%sSpecial2: Prefix: %s\n%s\n%*sMiddle: %s\n%s", indent, "", field,
2820 s.Prefix, s.Val1.goString(indent+2, "Val1: "),
2821 indent+2, "", s.Middle, s.Val2.goString(indent+2, "Val2: "))
2822 }
2823
2824
2825 func (ps *printState) printInner(prefixOnly bool) []AST {
2826 var save []AST
2827 var psave *[]AST
2828 if prefixOnly {
2829 psave = &save
2830 }
2831 for len(ps.inner) > 0 {
2832 ps.printOneInner(psave)
2833 }
2834 return save
2835 }
2836
2837
2838
2839 type innerPrinter interface {
2840 printInner(*printState)
2841 }
2842
2843
2844
2845 func (ps *printState) printOneInner(save *[]AST) {
2846 if len(ps.inner) == 0 {
2847 panic("printOneInner called with no inner types")
2848 }
2849 ln := len(ps.inner)
2850 a := ps.inner[ln-1]
2851 ps.inner = ps.inner[:ln-1]
2852
2853 if save != nil {
2854 if _, ok := a.(*MethodWithQualifiers); ok {
2855 *save = append(*save, a)
2856 return
2857 }
2858 }
2859
2860 if ip, ok := a.(innerPrinter); ok {
2861 ip.printInner(ps)
2862 } else {
2863 ps.print(a)
2864 }
2865 }
2866
2867
2868 func (ps *printState) isEmpty(a AST) bool {
2869 switch a := a.(type) {
2870 case *ArgumentPack:
2871 return len(a.Args) == 0
2872 case *ExprList:
2873 return len(a.Exprs) == 0
2874 case *PackExpansion:
2875 return a.Pack != nil && ps.isEmpty(a.Base)
2876 default:
2877 return false
2878 }
2879 }
2880
View as plain text