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