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