Source file src/pkg/cmd/compile/internal/gc/fmt.go
1
2
3
4
5 package gc
6
7 import (
8 "cmd/compile/internal/types"
9 "fmt"
10 "io"
11 "strconv"
12 "strings"
13 "unicode/utf8"
14 )
15
16
17
18
19 type FmtFlag int
20
21 const (
22 FmtLeft FmtFlag = 1 << iota
23 FmtSharp
24 FmtSign
25 FmtUnsigned
26 FmtShort
27 FmtLong
28 FmtComma
29 FmtByte
30 )
31
32
33
34 func fmtFlag(s fmt.State, verb rune) FmtFlag {
35 var flag FmtFlag
36 if s.Flag('-') {
37 flag |= FmtLeft
38 }
39 if s.Flag('#') {
40 flag |= FmtSharp
41 }
42 if s.Flag('+') {
43 flag |= FmtSign
44 }
45 if s.Flag(' ') {
46 Fatalf("FmtUnsigned in format string")
47 }
48 if _, ok := s.Precision(); ok {
49 flag |= FmtComma
50 }
51 if s.Flag('0') {
52 flag |= FmtByte
53 }
54 switch verb {
55 case 'S':
56 flag |= FmtShort
57 case 'L':
58 flag |= FmtLong
59 }
60 return flag
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 const (
96 FErr = iota
97 FDbg
98 FTypeId
99 FTypeIdName
100 )
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 func (f FmtFlag) update(mode fmtMode) (FmtFlag, fmtMode) {
130 switch {
131 case f&FmtSign != 0:
132 mode = FDbg
133 case f&FmtSharp != 0:
134
135 case f&FmtUnsigned != 0:
136 mode = FTypeIdName
137 case f&FmtLeft != 0:
138 mode = FTypeId
139 }
140
141 f &^= FmtSharp | FmtLeft | FmtSign
142 return f, mode
143 }
144
145 var goopnames = []string{
146 OADDR: "&",
147 OADD: "+",
148 OADDSTR: "+",
149 OALIGNOF: "unsafe.Alignof",
150 OANDAND: "&&",
151 OANDNOT: "&^",
152 OAND: "&",
153 OAPPEND: "append",
154 OAS: "=",
155 OAS2: "=",
156 OBREAK: "break",
157 OCALL: "function call",
158 OCAP: "cap",
159 OCASE: "case",
160 OCLOSE: "close",
161 OCOMPLEX: "complex",
162 OBITNOT: "^",
163 OCONTINUE: "continue",
164 OCOPY: "copy",
165 ODELETE: "delete",
166 ODEFER: "defer",
167 ODIV: "/",
168 OEQ: "==",
169 OFALL: "fallthrough",
170 OFOR: "for",
171 OFORUNTIL: "foruntil",
172 OGE: ">=",
173 OGOTO: "goto",
174 OGT: ">",
175 OIF: "if",
176 OIMAG: "imag",
177 OINLMARK: "inlmark",
178 ODEREF: "*",
179 OLEN: "len",
180 OLE: "<=",
181 OLSH: "<<",
182 OLT: "<",
183 OMAKE: "make",
184 ONEG: "-",
185 OMOD: "%",
186 OMUL: "*",
187 ONEW: "new",
188 ONE: "!=",
189 ONOT: "!",
190 OOFFSETOF: "unsafe.Offsetof",
191 OOROR: "||",
192 OOR: "|",
193 OPANIC: "panic",
194 OPLUS: "+",
195 OPRINTN: "println",
196 OPRINT: "print",
197 ORANGE: "range",
198 OREAL: "real",
199 ORECV: "<-",
200 ORECOVER: "recover",
201 ORETURN: "return",
202 ORSH: ">>",
203 OSELECT: "select",
204 OSEND: "<-",
205 OSIZEOF: "unsafe.Sizeof",
206 OSUB: "-",
207 OSWITCH: "switch",
208 OXOR: "^",
209 }
210
211 func (o Op) GoString() string {
212 return fmt.Sprintf("%#v", o)
213 }
214
215 func (o Op) format(s fmt.State, verb rune, mode fmtMode) {
216 switch verb {
217 case 'v':
218 o.oconv(s, fmtFlag(s, verb), mode)
219
220 default:
221 fmt.Fprintf(s, "%%!%c(Op=%d)", verb, int(o))
222 }
223 }
224
225 func (o Op) oconv(s fmt.State, flag FmtFlag, mode fmtMode) {
226 if flag&FmtSharp != 0 || mode != FDbg {
227 if int(o) < len(goopnames) && goopnames[o] != "" {
228 fmt.Fprint(s, goopnames[o])
229 return
230 }
231 }
232
233
234 fmt.Fprint(s, o.String())
235 }
236
237 type (
238 fmtMode int
239
240 fmtNodeErr Node
241 fmtNodeDbg Node
242 fmtNodeTypeId Node
243 fmtNodeTypeIdName Node
244
245 fmtOpErr Op
246 fmtOpDbg Op
247 fmtOpTypeId Op
248 fmtOpTypeIdName Op
249
250 fmtTypeErr types.Type
251 fmtTypeDbg types.Type
252 fmtTypeTypeId types.Type
253 fmtTypeTypeIdName types.Type
254
255 fmtSymErr types.Sym
256 fmtSymDbg types.Sym
257 fmtSymTypeId types.Sym
258 fmtSymTypeIdName types.Sym
259
260 fmtNodesErr Nodes
261 fmtNodesDbg Nodes
262 fmtNodesTypeId Nodes
263 fmtNodesTypeIdName Nodes
264 )
265
266 func (n *fmtNodeErr) Format(s fmt.State, verb rune) { (*Node)(n).format(s, verb, FErr) }
267 func (n *fmtNodeDbg) Format(s fmt.State, verb rune) { (*Node)(n).format(s, verb, FDbg) }
268 func (n *fmtNodeTypeId) Format(s fmt.State, verb rune) { (*Node)(n).format(s, verb, FTypeId) }
269 func (n *fmtNodeTypeIdName) Format(s fmt.State, verb rune) { (*Node)(n).format(s, verb, FTypeIdName) }
270 func (n *Node) Format(s fmt.State, verb rune) { n.format(s, verb, FErr) }
271
272 func (o fmtOpErr) Format(s fmt.State, verb rune) { Op(o).format(s, verb, FErr) }
273 func (o fmtOpDbg) Format(s fmt.State, verb rune) { Op(o).format(s, verb, FDbg) }
274 func (o fmtOpTypeId) Format(s fmt.State, verb rune) { Op(o).format(s, verb, FTypeId) }
275 func (o fmtOpTypeIdName) Format(s fmt.State, verb rune) { Op(o).format(s, verb, FTypeIdName) }
276 func (o Op) Format(s fmt.State, verb rune) { o.format(s, verb, FErr) }
277
278 func (t *fmtTypeErr) Format(s fmt.State, verb rune) { typeFormat((*types.Type)(t), s, verb, FErr) }
279 func (t *fmtTypeDbg) Format(s fmt.State, verb rune) { typeFormat((*types.Type)(t), s, verb, FDbg) }
280 func (t *fmtTypeTypeId) Format(s fmt.State, verb rune) { typeFormat((*types.Type)(t), s, verb, FTypeId) }
281 func (t *fmtTypeTypeIdName) Format(s fmt.State, verb rune) {
282 typeFormat((*types.Type)(t), s, verb, FTypeIdName)
283 }
284
285
286
287 func (y *fmtSymErr) Format(s fmt.State, verb rune) { symFormat((*types.Sym)(y), s, verb, FErr) }
288 func (y *fmtSymDbg) Format(s fmt.State, verb rune) { symFormat((*types.Sym)(y), s, verb, FDbg) }
289 func (y *fmtSymTypeId) Format(s fmt.State, verb rune) { symFormat((*types.Sym)(y), s, verb, FTypeId) }
290 func (y *fmtSymTypeIdName) Format(s fmt.State, verb rune) {
291 symFormat((*types.Sym)(y), s, verb, FTypeIdName)
292 }
293
294
295
296 func (n fmtNodesErr) Format(s fmt.State, verb rune) { (Nodes)(n).format(s, verb, FErr) }
297 func (n fmtNodesDbg) Format(s fmt.State, verb rune) { (Nodes)(n).format(s, verb, FDbg) }
298 func (n fmtNodesTypeId) Format(s fmt.State, verb rune) { (Nodes)(n).format(s, verb, FTypeId) }
299 func (n fmtNodesTypeIdName) Format(s fmt.State, verb rune) { (Nodes)(n).format(s, verb, FTypeIdName) }
300 func (n Nodes) Format(s fmt.State, verb rune) { n.format(s, verb, FErr) }
301
302 func (m fmtMode) Fprintf(s fmt.State, format string, args ...interface{}) {
303 m.prepareArgs(args)
304 fmt.Fprintf(s, format, args...)
305 }
306
307 func (m fmtMode) Sprintf(format string, args ...interface{}) string {
308 m.prepareArgs(args)
309 return fmt.Sprintf(format, args...)
310 }
311
312 func (m fmtMode) Sprint(args ...interface{}) string {
313 m.prepareArgs(args)
314 return fmt.Sprint(args...)
315 }
316
317 func (m fmtMode) prepareArgs(args []interface{}) {
318 switch m {
319 case FErr:
320 for i, arg := range args {
321 switch arg := arg.(type) {
322 case Op:
323 args[i] = fmtOpErr(arg)
324 case *Node:
325 args[i] = (*fmtNodeErr)(arg)
326 case *types.Type:
327 args[i] = (*fmtTypeErr)(arg)
328 case *types.Sym:
329 args[i] = (*fmtSymErr)(arg)
330 case Nodes:
331 args[i] = fmtNodesErr(arg)
332 case Val, int32, int64, string, types.EType:
333
334 default:
335 Fatalf("mode.prepareArgs type %T", arg)
336 }
337 }
338 case FDbg:
339 for i, arg := range args {
340 switch arg := arg.(type) {
341 case Op:
342 args[i] = fmtOpDbg(arg)
343 case *Node:
344 args[i] = (*fmtNodeDbg)(arg)
345 case *types.Type:
346 args[i] = (*fmtTypeDbg)(arg)
347 case *types.Sym:
348 args[i] = (*fmtSymDbg)(arg)
349 case Nodes:
350 args[i] = fmtNodesDbg(arg)
351 case Val, int32, int64, string, types.EType:
352
353 default:
354 Fatalf("mode.prepareArgs type %T", arg)
355 }
356 }
357 case FTypeId:
358 for i, arg := range args {
359 switch arg := arg.(type) {
360 case Op:
361 args[i] = fmtOpTypeId(arg)
362 case *Node:
363 args[i] = (*fmtNodeTypeId)(arg)
364 case *types.Type:
365 args[i] = (*fmtTypeTypeId)(arg)
366 case *types.Sym:
367 args[i] = (*fmtSymTypeId)(arg)
368 case Nodes:
369 args[i] = fmtNodesTypeId(arg)
370 case Val, int32, int64, string, types.EType:
371
372 default:
373 Fatalf("mode.prepareArgs type %T", arg)
374 }
375 }
376 case FTypeIdName:
377 for i, arg := range args {
378 switch arg := arg.(type) {
379 case Op:
380 args[i] = fmtOpTypeIdName(arg)
381 case *Node:
382 args[i] = (*fmtNodeTypeIdName)(arg)
383 case *types.Type:
384 args[i] = (*fmtTypeTypeIdName)(arg)
385 case *types.Sym:
386 args[i] = (*fmtSymTypeIdName)(arg)
387 case Nodes:
388 args[i] = fmtNodesTypeIdName(arg)
389 case Val, int32, int64, string, types.EType:
390
391 default:
392 Fatalf("mode.prepareArgs type %T", arg)
393 }
394 }
395 default:
396 Fatalf("mode.prepareArgs mode %d", m)
397 }
398 }
399
400 func (n *Node) format(s fmt.State, verb rune, mode fmtMode) {
401 switch verb {
402 case 'v', 'S', 'L':
403 n.nconv(s, fmtFlag(s, verb), mode)
404
405 case 'j':
406 n.jconv(s, fmtFlag(s, verb))
407
408 default:
409 fmt.Fprintf(s, "%%!%c(*Node=%p)", verb, n)
410 }
411 }
412
413
414 func (n *Node) jconv(s fmt.State, flag FmtFlag) {
415 c := flag & FmtShort
416
417 if c == 0 && n.Addable() {
418 fmt.Fprintf(s, " a(%v)", n.Addable())
419 }
420
421 if c == 0 && n.Name != nil && n.Name.Vargen != 0 {
422 fmt.Fprintf(s, " g(%d)", n.Name.Vargen)
423 }
424
425 if n.Pos.IsKnown() {
426 fmt.Fprintf(s, " l(%d)", n.Pos.Line())
427 }
428
429 if c == 0 && n.Xoffset != BADWIDTH {
430 fmt.Fprintf(s, " x(%d)", n.Xoffset)
431 }
432
433 if n.Class() != 0 {
434 fmt.Fprintf(s, " class(%v)", n.Class())
435 }
436
437 if n.Colas() {
438 fmt.Fprintf(s, " colas(%v)", n.Colas())
439 }
440
441 switch n.Esc {
442 case EscUnknown:
443 break
444
445 case EscHeap:
446 fmt.Fprint(s, " esc(h)")
447
448 case EscNone:
449 fmt.Fprint(s, " esc(no)")
450
451 case EscNever:
452 if c == 0 {
453 fmt.Fprint(s, " esc(N)")
454 }
455
456 default:
457 fmt.Fprintf(s, " esc(%d)", n.Esc)
458 }
459
460 if e, ok := n.Opt().(*NodeEscState); ok && e.Loopdepth != 0 {
461 fmt.Fprintf(s, " ld(%d)", e.Loopdepth)
462 }
463
464 if c == 0 && n.Typecheck() != 0 {
465 fmt.Fprintf(s, " tc(%d)", n.Typecheck())
466 }
467
468 if n.IsDDD() {
469 fmt.Fprintf(s, " isddd(%v)", n.IsDDD())
470 }
471
472 if n.Implicit() {
473 fmt.Fprintf(s, " implicit(%v)", n.Implicit())
474 }
475
476 if n.Embedded() {
477 fmt.Fprintf(s, " embedded")
478 }
479
480 if n.Addrtaken() {
481 fmt.Fprint(s, " addrtaken")
482 }
483
484 if n.Assigned() {
485 fmt.Fprint(s, " assigned")
486 }
487 if n.Bounded() {
488 fmt.Fprint(s, " bounded")
489 }
490 if n.NonNil() {
491 fmt.Fprint(s, " nonnil")
492 }
493
494 if c == 0 && n.HasCall() {
495 fmt.Fprint(s, " hascall")
496 }
497
498 if c == 0 && n.Name != nil && n.Name.Used() {
499 fmt.Fprint(s, " used")
500 }
501 }
502
503 func (v Val) Format(s fmt.State, verb rune) {
504 switch verb {
505 case 'v':
506 v.vconv(s, fmtFlag(s, verb))
507
508 default:
509 fmt.Fprintf(s, "%%!%c(Val=%T)", verb, v)
510 }
511 }
512
513 func (v Val) vconv(s fmt.State, flag FmtFlag) {
514 switch u := v.U.(type) {
515 case *Mpint:
516 if !u.Rune {
517 if flag&FmtSharp != 0 {
518 fmt.Fprint(s, u.String())
519 return
520 }
521 fmt.Fprint(s, u.GoString())
522 return
523 }
524
525 switch x := u.Int64(); {
526 case ' ' <= x && x < utf8.RuneSelf && x != '\\' && x != '\'':
527 fmt.Fprintf(s, "'%c'", int(x))
528
529 case 0 <= x && x < 1<<16:
530 fmt.Fprintf(s, "'\\u%04x'", uint(int(x)))
531
532 case 0 <= x && x <= utf8.MaxRune:
533 fmt.Fprintf(s, "'\\U%08x'", uint64(x))
534
535 default:
536 fmt.Fprintf(s, "('\\x00' + %v)", u)
537 }
538
539 case *Mpflt:
540 if flag&FmtSharp != 0 {
541 fmt.Fprint(s, u.String())
542 return
543 }
544 fmt.Fprint(s, u.GoString())
545 return
546
547 case *Mpcplx:
548 if flag&FmtSharp != 0 {
549 fmt.Fprint(s, u.String())
550 return
551 }
552 fmt.Fprint(s, u.GoString())
553 return
554
555 case string:
556 fmt.Fprint(s, strconv.Quote(u))
557
558 case bool:
559 fmt.Fprint(s, u)
560
561 case *NilVal:
562 fmt.Fprint(s, "nil")
563
564 default:
565 fmt.Fprintf(s, "<ctype=%d>", v.Ctype())
566 }
567 }
568
569
578
579 func symfmt(s *types.Sym, flag FmtFlag, mode fmtMode) string {
580 if s.Pkg != nil && flag&FmtShort == 0 {
581 switch mode {
582 case FErr:
583 if s.Pkg == builtinpkg || s.Pkg == localpkg {
584 return s.Name
585 }
586
587
588 if s.Pkg.Name != "" && numImport[s.Pkg.Name] > 1 {
589 return fmt.Sprintf("%q.%s", s.Pkg.Path, s.Name)
590 }
591 return s.Pkg.Name + "." + s.Name
592
593 case FDbg:
594 return s.Pkg.Name + "." + s.Name
595
596 case FTypeIdName:
597 return s.Pkg.Name + "." + s.Name
598
599 case FTypeId:
600 return s.Pkg.Prefix + "." + s.Name
601 }
602 }
603
604 if flag&FmtByte != 0 {
605
606
607 name := s.Name
608 if i := strings.LastIndex(name, "."); i >= 0 {
609 name = name[i+1:]
610 }
611
612 if mode == FDbg {
613 return fmt.Sprintf("@%q.%s", s.Pkg.Path, name)
614 }
615
616 return name
617 }
618
619 return s.Name
620 }
621
622 var basicnames = []string{
623 TINT: "int",
624 TUINT: "uint",
625 TINT8: "int8",
626 TUINT8: "uint8",
627 TINT16: "int16",
628 TUINT16: "uint16",
629 TINT32: "int32",
630 TUINT32: "uint32",
631 TINT64: "int64",
632 TUINT64: "uint64",
633 TUINTPTR: "uintptr",
634 TFLOAT32: "float32",
635 TFLOAT64: "float64",
636 TCOMPLEX64: "complex64",
637 TCOMPLEX128: "complex128",
638 TBOOL: "bool",
639 TANY: "any",
640 TSTRING: "string",
641 TNIL: "nil",
642 TIDEAL: "untyped number",
643 TBLANK: "blank",
644 }
645
646 func typefmt(t *types.Type, flag FmtFlag, mode fmtMode, depth int) string {
647 if t == nil {
648 return "<T>"
649 }
650
651 if t == types.Bytetype || t == types.Runetype {
652
653 switch mode {
654 case FTypeIdName, FTypeId:
655 t = types.Types[t.Etype]
656 default:
657 return sconv(t.Sym, FmtShort, mode)
658 }
659 }
660
661 if t == types.Errortype {
662 return "error"
663 }
664
665
666 if flag&FmtLong == 0 && t.Sym != nil && t != types.Types[t.Etype] {
667 switch mode {
668 case FTypeId, FTypeIdName:
669 if flag&FmtShort != 0 {
670 if t.Vargen != 0 {
671 return mode.Sprintf("%v·%d", sconv(t.Sym, FmtShort, mode), t.Vargen)
672 }
673 return sconv(t.Sym, FmtShort, mode)
674 }
675
676 if mode == FTypeIdName {
677 return sconv(t.Sym, FmtUnsigned, mode)
678 }
679
680 if t.Sym.Pkg == localpkg && t.Vargen != 0 {
681 return mode.Sprintf("%v·%d", t.Sym, t.Vargen)
682 }
683 }
684
685 return smodeString(t.Sym, mode)
686 }
687
688 if int(t.Etype) < len(basicnames) && basicnames[t.Etype] != "" {
689 name := basicnames[t.Etype]
690 if t == types.Idealbool || t == types.Idealstring {
691 name = "untyped " + name
692 }
693 return name
694 }
695
696 if mode == FDbg {
697 return t.Etype.String() + "-" + typefmt(t, flag, FErr, depth)
698 }
699
700 switch t.Etype {
701 case TPTR:
702 switch mode {
703 case FTypeId, FTypeIdName:
704 if flag&FmtShort != 0 {
705 return "*" + tconv(t.Elem(), FmtShort, mode, depth)
706 }
707 }
708 return "*" + tmodeString(t.Elem(), mode, depth)
709
710 case TARRAY:
711 if t.IsDDDArray() {
712 return "[...]" + tmodeString(t.Elem(), mode, depth)
713 }
714 return "[" + strconv.FormatInt(t.NumElem(), 10) + "]" + tmodeString(t.Elem(), mode, depth)
715
716 case TSLICE:
717 return "[]" + tmodeString(t.Elem(), mode, depth)
718
719 case TCHAN:
720 switch t.ChanDir() {
721 case types.Crecv:
722 return "<-chan " + tmodeString(t.Elem(), mode, depth)
723
724 case types.Csend:
725 return "chan<- " + tmodeString(t.Elem(), mode, depth)
726 }
727
728 if t.Elem() != nil && t.Elem().IsChan() && t.Elem().Sym == nil && t.Elem().ChanDir() == types.Crecv {
729 return "chan (" + tmodeString(t.Elem(), mode, depth) + ")"
730 }
731 return "chan " + tmodeString(t.Elem(), mode, depth)
732
733 case TMAP:
734 return "map[" + tmodeString(t.Key(), mode, depth) + "]" + tmodeString(t.Elem(), mode, depth)
735
736 case TINTER:
737 if t.IsEmptyInterface() {
738 return "interface {}"
739 }
740 buf := make([]byte, 0, 64)
741 buf = append(buf, "interface {"...)
742 for i, f := range t.Fields().Slice() {
743 if i != 0 {
744 buf = append(buf, ';')
745 }
746 buf = append(buf, ' ')
747 switch {
748 case f.Sym == nil:
749
750
751 break
752 case types.IsExported(f.Sym.Name):
753 buf = append(buf, sconv(f.Sym, FmtShort, mode)...)
754 default:
755 flag1 := FmtLeft
756 if flag&FmtUnsigned != 0 {
757 flag1 = FmtUnsigned
758 }
759 buf = append(buf, sconv(f.Sym, flag1, mode)...)
760 }
761 buf = append(buf, tconv(f.Type, FmtShort, mode, depth)...)
762 }
763 if t.NumFields() != 0 {
764 buf = append(buf, ' ')
765 }
766 buf = append(buf, '}')
767 return string(buf)
768
769 case TFUNC:
770 buf := make([]byte, 0, 64)
771 if flag&FmtShort != 0 {
772
773 } else {
774 if t.Recv() != nil {
775 buf = append(buf, "method"...)
776 buf = append(buf, tmodeString(t.Recvs(), mode, depth)...)
777 buf = append(buf, ' ')
778 }
779 buf = append(buf, "func"...)
780 }
781 buf = append(buf, tmodeString(t.Params(), mode, depth)...)
782
783 switch t.NumResults() {
784 case 0:
785
786
787 case 1:
788 buf = append(buf, ' ')
789 buf = append(buf, tmodeString(t.Results().Field(0).Type, mode, depth)...)
790
791 default:
792 buf = append(buf, ' ')
793 buf = append(buf, tmodeString(t.Results(), mode, depth)...)
794 }
795 return string(buf)
796
797 case TSTRUCT:
798 if m := t.StructType().Map; m != nil {
799 mt := m.MapType()
800
801
802 var subtype string
803 switch t {
804 case mt.Bucket:
805 subtype = "bucket"
806 case mt.Hmap:
807 subtype = "hdr"
808 case mt.Hiter:
809 subtype = "iter"
810 default:
811 Fatalf("unknown internal map type")
812 }
813 return fmt.Sprintf("map.%s[%s]%s", subtype, tmodeString(m.Key(), mode, depth), tmodeString(m.Elem(), mode, depth))
814 }
815
816 buf := make([]byte, 0, 64)
817 if funarg := t.StructType().Funarg; funarg != types.FunargNone {
818 buf = append(buf, '(')
819 var flag1 FmtFlag
820 switch mode {
821 case FTypeId, FTypeIdName, FErr:
822
823 flag1 = FmtShort
824 }
825 for i, f := range t.Fields().Slice() {
826 if i != 0 {
827 buf = append(buf, ", "...)
828 }
829 buf = append(buf, fldconv(f, flag1, mode, depth, funarg)...)
830 }
831 buf = append(buf, ')')
832 } else {
833 buf = append(buf, "struct {"...)
834 for i, f := range t.Fields().Slice() {
835 if i != 0 {
836 buf = append(buf, ';')
837 }
838 buf = append(buf, ' ')
839 buf = append(buf, fldconv(f, FmtLong, mode, depth, funarg)...)
840 }
841 if t.NumFields() != 0 {
842 buf = append(buf, ' ')
843 }
844 buf = append(buf, '}')
845 }
846 return string(buf)
847
848 case TFORW:
849 if t.Sym != nil {
850 return "undefined " + smodeString(t.Sym, mode)
851 }
852 return "undefined"
853
854 case TUNSAFEPTR:
855 return "unsafe.Pointer"
856
857 case TDDDFIELD:
858 return mode.Sprintf("%v <%v> %v", t.Etype, t.Sym, t.DDDField())
859
860 case Txxx:
861 return "Txxx"
862 }
863
864
865 return mode.Sprintf("%v <%v>", t.Etype, t.Sym)
866 }
867
868
869 func stmtwithinit(op Op) bool {
870 switch op {
871 case OIF, OFOR, OFORUNTIL, OSWITCH:
872 return true
873 }
874
875 return false
876 }
877
878 func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
879
880
881
882
883
884
885 simpleinit := n.Ninit.Len() == 1 && n.Ninit.First().Ninit.Len() == 0 && stmtwithinit(n.Op)
886
887
888 complexinit := n.Ninit.Len() != 0 && !simpleinit && (mode != FErr)
889
890
891 extrablock := complexinit && stmtwithinit(n.Op)
892
893 if extrablock {
894 fmt.Fprint(s, "{")
895 }
896
897 if complexinit {
898 mode.Fprintf(s, " %v; ", n.Ninit)
899 }
900
901 switch n.Op {
902 case ODCL:
903 mode.Fprintf(s, "var %v %v", n.Left.Sym, n.Left.Type)
904
905 case ODCLFIELD:
906 if n.Sym != nil {
907 mode.Fprintf(s, "%v %v", n.Sym, n.Left)
908 } else {
909 mode.Fprintf(s, "%v", n.Left)
910 }
911
912
913
914
915 case OAS:
916 if n.Colas() && !complexinit {
917 mode.Fprintf(s, "%v := %v", n.Left, n.Right)
918 } else {
919 mode.Fprintf(s, "%v = %v", n.Left, n.Right)
920 }
921
922 case OASOP:
923 if n.Implicit() {
924 if n.SubOp() == OADD {
925 mode.Fprintf(s, "%v++", n.Left)
926 } else {
927 mode.Fprintf(s, "%v--", n.Left)
928 }
929 break
930 }
931
932 mode.Fprintf(s, "%v %#v= %v", n.Left, n.SubOp(), n.Right)
933
934 case OAS2:
935 if n.Colas() && !complexinit {
936 mode.Fprintf(s, "%.v := %.v", n.List, n.Rlist)
937 break
938 }
939 fallthrough
940
941 case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
942 mode.Fprintf(s, "%.v = %.v", n.List, n.Rlist)
943
944 case ORETURN:
945 mode.Fprintf(s, "return %.v", n.List)
946
947 case ORETJMP:
948 mode.Fprintf(s, "retjmp %v", n.Sym)
949
950 case OINLMARK:
951 mode.Fprintf(s, "inlmark %d", n.Xoffset)
952
953 case OGO:
954 mode.Fprintf(s, "go %v", n.Left)
955
956 case ODEFER:
957 mode.Fprintf(s, "defer %v", n.Left)
958
959 case OIF:
960 if simpleinit {
961 mode.Fprintf(s, "if %v; %v { %v }", n.Ninit.First(), n.Left, n.Nbody)
962 } else {
963 mode.Fprintf(s, "if %v { %v }", n.Left, n.Nbody)
964 }
965 if n.Rlist.Len() != 0 {
966 mode.Fprintf(s, " else { %v }", n.Rlist)
967 }
968
969 case OFOR, OFORUNTIL:
970 opname := "for"
971 if n.Op == OFORUNTIL {
972 opname = "foruntil"
973 }
974 if mode == FErr {
975 fmt.Fprintf(s, "%s loop", opname)
976 break
977 }
978
979 fmt.Fprint(s, opname)
980 if simpleinit {
981 mode.Fprintf(s, " %v;", n.Ninit.First())
982 } else if n.Right != nil {
983 fmt.Fprint(s, " ;")
984 }
985
986 if n.Left != nil {
987 mode.Fprintf(s, " %v", n.Left)
988 }
989
990 if n.Right != nil {
991 mode.Fprintf(s, "; %v", n.Right)
992 } else if simpleinit {
993 fmt.Fprint(s, ";")
994 }
995
996 if n.Op == OFORUNTIL && n.List.Len() != 0 {
997 mode.Fprintf(s, "; %v", n.List)
998 }
999
1000 mode.Fprintf(s, " { %v }", n.Nbody)
1001
1002 case ORANGE:
1003 if mode == FErr {
1004 fmt.Fprint(s, "for loop")
1005 break
1006 }
1007
1008 if n.List.Len() == 0 {
1009 mode.Fprintf(s, "for range %v { %v }", n.Right, n.Nbody)
1010 break
1011 }
1012
1013 mode.Fprintf(s, "for %.v = range %v { %v }", n.List, n.Right, n.Nbody)
1014
1015 case OSELECT, OSWITCH:
1016 if mode == FErr {
1017 mode.Fprintf(s, "%v statement", n.Op)
1018 break
1019 }
1020
1021 mode.Fprintf(s, "%#v", n.Op)
1022 if simpleinit {
1023 mode.Fprintf(s, " %v;", n.Ninit.First())
1024 }
1025 if n.Left != nil {
1026 mode.Fprintf(s, " %v ", n.Left)
1027 }
1028
1029 mode.Fprintf(s, " { %v }", n.List)
1030
1031 case OXCASE:
1032 if n.List.Len() != 0 {
1033 mode.Fprintf(s, "case %.v", n.List)
1034 } else {
1035 fmt.Fprint(s, "default")
1036 }
1037 mode.Fprintf(s, ": %v", n.Nbody)
1038
1039 case OCASE:
1040 switch {
1041 case n.Left != nil:
1042
1043 mode.Fprintf(s, "case %v", n.Left)
1044 case n.List.Len() > 0:
1045
1046 if n.List.Len() != 2 {
1047 Fatalf("bad OCASE list length %d", n.List.Len())
1048 }
1049 mode.Fprintf(s, "case %v..%v", n.List.First(), n.List.Second())
1050 default:
1051 fmt.Fprint(s, "default")
1052 }
1053 mode.Fprintf(s, ": %v", n.Nbody)
1054
1055 case OBREAK, OCONTINUE, OGOTO, OFALL:
1056 if n.Sym != nil {
1057 mode.Fprintf(s, "%#v %v", n.Op, n.Sym)
1058 } else {
1059 mode.Fprintf(s, "%#v", n.Op)
1060 }
1061
1062 case OEMPTY:
1063 break
1064
1065 case OLABEL:
1066 mode.Fprintf(s, "%v: ", n.Sym)
1067 }
1068
1069 if extrablock {
1070 fmt.Fprint(s, "}")
1071 }
1072 }
1073
1074 var opprec = []int{
1075 OALIGNOF: 8,
1076 OAPPEND: 8,
1077 OBYTES2STR: 8,
1078 OARRAYLIT: 8,
1079 OSLICELIT: 8,
1080 ORUNES2STR: 8,
1081 OCALLFUNC: 8,
1082 OCALLINTER: 8,
1083 OCALLMETH: 8,
1084 OCALL: 8,
1085 OCAP: 8,
1086 OCLOSE: 8,
1087 OCONVIFACE: 8,
1088 OCONVNOP: 8,
1089 OCONV: 8,
1090 OCOPY: 8,
1091 ODELETE: 8,
1092 OGETG: 8,
1093 OLEN: 8,
1094 OLITERAL: 8,
1095 OMAKESLICE: 8,
1096 OMAKE: 8,
1097 OMAPLIT: 8,
1098 ONAME: 8,
1099 ONEW: 8,
1100 ONONAME: 8,
1101 OOFFSETOF: 8,
1102 OPACK: 8,
1103 OPANIC: 8,
1104 OPAREN: 8,
1105 OPRINTN: 8,
1106 OPRINT: 8,
1107 ORUNESTR: 8,
1108 OSIZEOF: 8,
1109 OSTR2BYTES: 8,
1110 OSTR2RUNES: 8,
1111 OSTRUCTLIT: 8,
1112 OTARRAY: 8,
1113 OTCHAN: 8,
1114 OTFUNC: 8,
1115 OTINTER: 8,
1116 OTMAP: 8,
1117 OTSTRUCT: 8,
1118 OINDEXMAP: 8,
1119 OINDEX: 8,
1120 OSLICE: 8,
1121 OSLICESTR: 8,
1122 OSLICEARR: 8,
1123 OSLICE3: 8,
1124 OSLICE3ARR: 8,
1125 OSLICEHEADER: 8,
1126 ODOTINTER: 8,
1127 ODOTMETH: 8,
1128 ODOTPTR: 8,
1129 ODOTTYPE2: 8,
1130 ODOTTYPE: 8,
1131 ODOT: 8,
1132 OXDOT: 8,
1133 OCALLPART: 8,
1134 OPLUS: 7,
1135 ONOT: 7,
1136 OBITNOT: 7,
1137 ONEG: 7,
1138 OADDR: 7,
1139 ODEREF: 7,
1140 ORECV: 7,
1141 OMUL: 6,
1142 ODIV: 6,
1143 OMOD: 6,
1144 OLSH: 6,
1145 ORSH: 6,
1146 OAND: 6,
1147 OANDNOT: 6,
1148 OADD: 5,
1149 OSUB: 5,
1150 OOR: 5,
1151 OXOR: 5,
1152 OEQ: 4,
1153 OLT: 4,
1154 OLE: 4,
1155 OGE: 4,
1156 OGT: 4,
1157 ONE: 4,
1158 OSEND: 3,
1159 OANDAND: 2,
1160 OOROR: 1,
1161
1162
1163 OAS: -1,
1164 OAS2: -1,
1165 OAS2DOTTYPE: -1,
1166 OAS2FUNC: -1,
1167 OAS2MAPR: -1,
1168 OAS2RECV: -1,
1169 OASOP: -1,
1170 OBREAK: -1,
1171 OCASE: -1,
1172 OCONTINUE: -1,
1173 ODCL: -1,
1174 ODCLFIELD: -1,
1175 ODEFER: -1,
1176 OEMPTY: -1,
1177 OFALL: -1,
1178 OFOR: -1,
1179 OFORUNTIL: -1,
1180 OGOTO: -1,
1181 OIF: -1,
1182 OLABEL: -1,
1183 OGO: -1,
1184 ORANGE: -1,
1185 ORETURN: -1,
1186 OSELECT: -1,
1187 OSWITCH: -1,
1188 OXCASE: -1,
1189
1190 OEND: 0,
1191 }
1192
1193 func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
1194 for n != nil && n.Implicit() && (n.Op == ODEREF || n.Op == OADDR) {
1195 n = n.Left
1196 }
1197
1198 if n == nil {
1199 fmt.Fprint(s, "<N>")
1200 return
1201 }
1202
1203 nprec := opprec[n.Op]
1204 if n.Op == OTYPE && n.Sym != nil {
1205 nprec = 8
1206 }
1207
1208 if prec > nprec {
1209 mode.Fprintf(s, "(%v)", n)
1210 return
1211 }
1212
1213 switch n.Op {
1214 case OPAREN:
1215 mode.Fprintf(s, "(%v)", n.Left)
1216
1217 case ODDDARG:
1218 fmt.Fprint(s, "... argument")
1219
1220 case OLITERAL:
1221 if mode == FErr {
1222 if n.Orig != nil && n.Orig != n {
1223 n.Orig.exprfmt(s, prec, mode)
1224 return
1225 }
1226 if n.Sym != nil {
1227 fmt.Fprint(s, smodeString(n.Sym, mode))
1228 return
1229 }
1230 }
1231 if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n {
1232 n.Orig.exprfmt(s, prec, mode)
1233 return
1234 }
1235 if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != types.Idealbool && n.Type != types.Idealstring {
1236
1237
1238 if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == types.Crecv) {
1239 mode.Fprintf(s, "(%v)(%v)", n.Type, n.Val())
1240 return
1241 } else {
1242 mode.Fprintf(s, "%v(%v)", n.Type, n.Val())
1243 return
1244 }
1245 }
1246
1247 mode.Fprintf(s, "%v", n.Val())
1248
1249
1250
1251 case ONAME:
1252 if mode == FErr && n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
1253 fmt.Fprint(s, "_")
1254 return
1255 }
1256 fallthrough
1257 case OPACK, ONONAME:
1258 fmt.Fprint(s, smodeString(n.Sym, mode))
1259
1260 case OTYPE:
1261 if n.Type == nil && n.Sym != nil {
1262 fmt.Fprint(s, smodeString(n.Sym, mode))
1263 return
1264 }
1265 mode.Fprintf(s, "%v", n.Type)
1266
1267 case OTARRAY:
1268 if n.Left != nil {
1269 mode.Fprintf(s, "[%v]%v", n.Left, n.Right)
1270 return
1271 }
1272 mode.Fprintf(s, "[]%v", n.Right)
1273
1274 case OTMAP:
1275 mode.Fprintf(s, "map[%v]%v", n.Left, n.Right)
1276
1277 case OTCHAN:
1278 switch n.TChanDir() {
1279 case types.Crecv:
1280 mode.Fprintf(s, "<-chan %v", n.Left)
1281
1282 case types.Csend:
1283 mode.Fprintf(s, "chan<- %v", n.Left)
1284
1285 default:
1286 if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && n.Left.TChanDir() == types.Crecv {
1287 mode.Fprintf(s, "chan (%v)", n.Left)
1288 } else {
1289 mode.Fprintf(s, "chan %v", n.Left)
1290 }
1291 }
1292
1293 case OTSTRUCT:
1294 fmt.Fprint(s, "<struct>")
1295
1296 case OTINTER:
1297 fmt.Fprint(s, "<inter>")
1298
1299 case OTFUNC:
1300 fmt.Fprint(s, "<func>")
1301
1302 case OCLOSURE:
1303 if mode == FErr {
1304 fmt.Fprint(s, "func literal")
1305 return
1306 }
1307 if n.Nbody.Len() != 0 {
1308 mode.Fprintf(s, "%v { %v }", n.Type, n.Nbody)
1309 return
1310 }
1311 mode.Fprintf(s, "%v { %v }", n.Type, n.Func.Closure.Nbody)
1312
1313 case OCOMPLIT:
1314 if mode == FErr {
1315 if n.Right != nil && n.Right.Type != nil && !n.Implicit() {
1316 if n.Right.Implicit() && n.Right.Type.IsPtr() {
1317 mode.Fprintf(s, "&%v literal", n.Right.Type.Elem())
1318 return
1319 }
1320 mode.Fprintf(s, "%v literal", n.Right.Type)
1321 return
1322 }
1323
1324 fmt.Fprint(s, "composite literal")
1325 return
1326 }
1327 mode.Fprintf(s, "(%v{ %.v })", n.Right, n.List)
1328
1329 case OPTRLIT:
1330 mode.Fprintf(s, "&%v", n.Left)
1331
1332 case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
1333 if mode == FErr {
1334 mode.Fprintf(s, "%v literal", n.Type)
1335 return
1336 }
1337 mode.Fprintf(s, "(%v{ %.v })", n.Type, n.List)
1338
1339 case OKEY:
1340 if n.Left != nil && n.Right != nil {
1341 mode.Fprintf(s, "%v:%v", n.Left, n.Right)
1342 return
1343 }
1344
1345 if n.Left == nil && n.Right != nil {
1346 mode.Fprintf(s, ":%v", n.Right)
1347 return
1348 }
1349 if n.Left != nil && n.Right == nil {
1350 mode.Fprintf(s, "%v:", n.Left)
1351 return
1352 }
1353 fmt.Fprint(s, ":")
1354
1355 case OSTRUCTKEY:
1356 mode.Fprintf(s, "%v:%v", n.Sym, n.Left)
1357
1358 case OCALLPART:
1359 n.Left.exprfmt(s, nprec, mode)
1360 if n.Right == nil || n.Right.Sym == nil {
1361 fmt.Fprint(s, ".<nil>")
1362 return
1363 }
1364 mode.Fprintf(s, ".%0S", n.Right.Sym)
1365
1366 case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
1367 n.Left.exprfmt(s, nprec, mode)
1368 if n.Sym == nil {
1369 fmt.Fprint(s, ".<nil>")
1370 return
1371 }
1372 mode.Fprintf(s, ".%0S", n.Sym)
1373
1374 case ODOTTYPE, ODOTTYPE2:
1375 n.Left.exprfmt(s, nprec, mode)
1376 if n.Right != nil {
1377 mode.Fprintf(s, ".(%v)", n.Right)
1378 return
1379 }
1380 mode.Fprintf(s, ".(%v)", n.Type)
1381
1382 case OINDEX, OINDEXMAP:
1383 n.Left.exprfmt(s, nprec, mode)
1384 mode.Fprintf(s, "[%v]", n.Right)
1385
1386 case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
1387 n.Left.exprfmt(s, nprec, mode)
1388 fmt.Fprint(s, "[")
1389 low, high, max := n.SliceBounds()
1390 if low != nil {
1391 fmt.Fprint(s, low.modeString(mode))
1392 }
1393 fmt.Fprint(s, ":")
1394 if high != nil {
1395 fmt.Fprint(s, high.modeString(mode))
1396 }
1397 if n.Op.IsSlice3() {
1398 fmt.Fprint(s, ":")
1399 if max != nil {
1400 fmt.Fprint(s, max.modeString(mode))
1401 }
1402 }
1403 fmt.Fprint(s, "]")
1404
1405 case OSLICEHEADER:
1406 if n.List.Len() != 2 {
1407 Fatalf("bad OSLICEHEADER list length %d", n.List.Len())
1408 }
1409 mode.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left, n.List.First(), n.List.Second())
1410
1411 case OCOMPLEX, OCOPY:
1412 if n.Left != nil {
1413 mode.Fprintf(s, "%#v(%v, %v)", n.Op, n.Left, n.Right)
1414 } else {
1415 mode.Fprintf(s, "%#v(%.v)", n.Op, n.List)
1416 }
1417
1418 case OCONV,
1419 OCONVIFACE,
1420 OCONVNOP,
1421 OBYTES2STR,
1422 ORUNES2STR,
1423 OSTR2BYTES,
1424 OSTR2RUNES,
1425 ORUNESTR:
1426 if n.Type == nil || n.Type.Sym == nil {
1427 mode.Fprintf(s, "(%v)", n.Type)
1428 } else {
1429 mode.Fprintf(s, "%v", n.Type)
1430 }
1431 if n.Left != nil {
1432 mode.Fprintf(s, "(%v)", n.Left)
1433 } else {
1434 mode.Fprintf(s, "(%.v)", n.List)
1435 }
1436
1437 case OREAL,
1438 OIMAG,
1439 OAPPEND,
1440 OCAP,
1441 OCLOSE,
1442 ODELETE,
1443 OLEN,
1444 OMAKE,
1445 ONEW,
1446 OPANIC,
1447 ORECOVER,
1448 OALIGNOF,
1449 OOFFSETOF,
1450 OSIZEOF,
1451 OPRINT,
1452 OPRINTN:
1453 if n.Left != nil {
1454 mode.Fprintf(s, "%#v(%v)", n.Op, n.Left)
1455 return
1456 }
1457 if n.IsDDD() {
1458 mode.Fprintf(s, "%#v(%.v...)", n.Op, n.List)
1459 return
1460 }
1461 mode.Fprintf(s, "%#v(%.v)", n.Op, n.List)
1462
1463 case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
1464 n.Left.exprfmt(s, nprec, mode)
1465 if n.IsDDD() {
1466 mode.Fprintf(s, "(%.v...)", n.List)
1467 return
1468 }
1469 mode.Fprintf(s, "(%.v)", n.List)
1470
1471 case OMAKEMAP, OMAKECHAN, OMAKESLICE:
1472 if n.List.Len() != 0 {
1473 mode.Fprintf(s, "make(%v, %.v)", n.Type, n.List)
1474 return
1475 }
1476 if n.Right != nil {
1477 mode.Fprintf(s, "make(%v, %v, %v)", n.Type, n.Left, n.Right)
1478 return
1479 }
1480 if n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()) {
1481 mode.Fprintf(s, "make(%v, %v)", n.Type, n.Left)
1482 return
1483 }
1484 mode.Fprintf(s, "make(%v)", n.Type)
1485
1486 case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
1487
1488 mode.Fprintf(s, "%#v", n.Op)
1489 if n.Left != nil && n.Left.Op == n.Op {
1490 fmt.Fprint(s, " ")
1491 }
1492 n.Left.exprfmt(s, nprec+1, mode)
1493
1494
1495 case OADD,
1496 OAND,
1497 OANDAND,
1498 OANDNOT,
1499 ODIV,
1500 OEQ,
1501 OGE,
1502 OGT,
1503 OLE,
1504 OLT,
1505 OLSH,
1506 OMOD,
1507 OMUL,
1508 ONE,
1509 OOR,
1510 OOROR,
1511 ORSH,
1512 OSEND,
1513 OSUB,
1514 OXOR:
1515 n.Left.exprfmt(s, nprec, mode)
1516 mode.Fprintf(s, " %#v ", n.Op)
1517 n.Right.exprfmt(s, nprec+1, mode)
1518
1519 case OADDSTR:
1520 for i, n1 := range n.List.Slice() {
1521 if i != 0 {
1522 fmt.Fprint(s, " + ")
1523 }
1524 n1.exprfmt(s, nprec, mode)
1525 }
1526
1527 default:
1528 mode.Fprintf(s, "<node %v>", n.Op)
1529 }
1530 }
1531
1532 func (n *Node) nodefmt(s fmt.State, flag FmtFlag, mode fmtMode) {
1533 t := n.Type
1534
1535
1536
1537 if n.Op != OLITERAL && n.Orig != nil {
1538 n = n.Orig
1539 }
1540
1541 if flag&FmtLong != 0 && t != nil {
1542 if t.Etype == TNIL {
1543 fmt.Fprint(s, "nil")
1544 } else if n.Op == ONAME && n.Name.AutoTemp() {
1545 mode.Fprintf(s, "%v value", t)
1546 } else {
1547 mode.Fprintf(s, "%v (type %v)", n, t)
1548 }
1549 return
1550 }
1551
1552
1553
1554 if opprec[n.Op] < 0 {
1555 n.stmtfmt(s, mode)
1556 return
1557 }
1558
1559 n.exprfmt(s, 0, mode)
1560 }
1561
1562 func (n *Node) nodedump(s fmt.State, flag FmtFlag, mode fmtMode) {
1563 recur := flag&FmtShort == 0
1564
1565 if recur {
1566 indent(s)
1567 if dumpdepth > 40 {
1568 fmt.Fprint(s, "...")
1569 return
1570 }
1571
1572 if n.Ninit.Len() != 0 {
1573 mode.Fprintf(s, "%v-init%v", n.Op, n.Ninit)
1574 indent(s)
1575 }
1576 }
1577
1578 switch n.Op {
1579 default:
1580 mode.Fprintf(s, "%v%j", n.Op, n)
1581
1582 case OLITERAL:
1583 mode.Fprintf(s, "%v-%v%j", n.Op, n.Val(), n)
1584
1585 case ONAME, ONONAME:
1586 if n.Sym != nil {
1587 mode.Fprintf(s, "%v-%v%j", n.Op, n.Sym, n)
1588 } else {
1589 mode.Fprintf(s, "%v%j", n.Op, n)
1590 }
1591 if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil {
1592 indent(s)
1593 mode.Fprintf(s, "%v-ntype%v", n.Op, n.Name.Param.Ntype)
1594 }
1595
1596 case OASOP:
1597 mode.Fprintf(s, "%v-%v%j", n.Op, n.SubOp(), n)
1598
1599 case OTYPE:
1600 mode.Fprintf(s, "%v %v%j type=%v", n.Op, n.Sym, n, n.Type)
1601 if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil {
1602 indent(s)
1603 mode.Fprintf(s, "%v-ntype%v", n.Op, n.Name.Param.Ntype)
1604 }
1605 }
1606
1607 if n.Sym != nil && n.Op != ONAME {
1608 mode.Fprintf(s, " %v", n.Sym)
1609 }
1610
1611 if n.Type != nil {
1612 mode.Fprintf(s, " %v", n.Type)
1613 }
1614
1615 if recur {
1616 if n.Left != nil {
1617 mode.Fprintf(s, "%v", n.Left)
1618 }
1619 if n.Right != nil {
1620 mode.Fprintf(s, "%v", n.Right)
1621 }
1622 if n.List.Len() != 0 {
1623 indent(s)
1624 mode.Fprintf(s, "%v-list%v", n.Op, n.List)
1625 }
1626
1627 if n.Rlist.Len() != 0 {
1628 indent(s)
1629 mode.Fprintf(s, "%v-rlist%v", n.Op, n.Rlist)
1630 }
1631
1632 if n.Nbody.Len() != 0 {
1633 indent(s)
1634 mode.Fprintf(s, "%v-body%v", n.Op, n.Nbody)
1635 }
1636 }
1637 }
1638
1639
1640 func symFormat(s *types.Sym, f fmt.State, verb rune, mode fmtMode) {
1641 switch verb {
1642 case 'v', 'S':
1643 fmt.Fprint(f, sconv(s, fmtFlag(f, verb), mode))
1644
1645 default:
1646 fmt.Fprintf(f, "%%!%c(*types.Sym=%p)", verb, s)
1647 }
1648 }
1649
1650 func smodeString(s *types.Sym, mode fmtMode) string { return sconv(s, 0, mode) }
1651
1652
1653 func sconv(s *types.Sym, flag FmtFlag, mode fmtMode) string {
1654 if flag&FmtLong != 0 {
1655 panic("linksymfmt")
1656 }
1657
1658 if s == nil {
1659 return "<S>"
1660 }
1661
1662 if s.Name == "_" {
1663 return "_"
1664 }
1665
1666 flag, mode = flag.update(mode)
1667 return symfmt(s, flag, mode)
1668 }
1669
1670 func tmodeString(t *types.Type, mode fmtMode, depth int) string {
1671 return tconv(t, 0, mode, depth)
1672 }
1673
1674 func fldconv(f *types.Field, flag FmtFlag, mode fmtMode, depth int, funarg types.Funarg) string {
1675 if f == nil {
1676 return "<T>"
1677 }
1678
1679 flag, mode = flag.update(mode)
1680 if mode == FTypeIdName {
1681 flag |= FmtUnsigned
1682 }
1683
1684 var name string
1685 if flag&FmtShort == 0 {
1686 s := f.Sym
1687
1688
1689 if mode == FErr {
1690 s = origSym(s)
1691 }
1692
1693 if s != nil && f.Embedded == 0 {
1694 if funarg != types.FunargNone {
1695 name = asNode(f.Nname).modeString(mode)
1696 } else if flag&FmtLong != 0 {
1697 name = mode.Sprintf("%0S", s)
1698 if !types.IsExported(name) && flag&FmtUnsigned == 0 {
1699 name = smodeString(s, mode)
1700 }
1701 } else {
1702 name = smodeString(s, mode)
1703 }
1704 }
1705 }
1706
1707 var typ string
1708 if f.IsDDD() {
1709 var et *types.Type
1710 if f.Type != nil {
1711 et = f.Type.Elem()
1712 }
1713 typ = "..." + tmodeString(et, mode, depth)
1714 } else {
1715 typ = tmodeString(f.Type, mode, depth)
1716 }
1717
1718 str := typ
1719 if name != "" {
1720 str = name + " " + typ
1721 }
1722
1723 if flag&FmtShort == 0 && funarg == types.FunargNone && f.Note != "" {
1724 str += " " + strconv.Quote(f.Note)
1725 }
1726
1727 return str
1728 }
1729
1730
1731
1732 func typeFormat(t *types.Type, s fmt.State, verb rune, mode fmtMode) {
1733 switch verb {
1734 case 'v', 'S', 'L':
1735
1736
1737 fmt.Fprint(s, tconv(t, fmtFlag(s, verb), mode, 0))
1738
1739 default:
1740 fmt.Fprintf(s, "%%!%c(*Type=%p)", verb, t)
1741 }
1742 }
1743
1744
1745 func tconv(t *types.Type, flag FmtFlag, mode fmtMode, depth int) string {
1746 if t == nil {
1747 return "<T>"
1748 }
1749 if t.Etype == types.TSSA {
1750 return t.Extra.(string)
1751 }
1752 if t.Etype == types.TTUPLE {
1753 return t.FieldType(0).String() + "," + t.FieldType(1).String()
1754 }
1755
1756
1757
1758
1759
1760 if depth > 250 {
1761 return "<...>"
1762 }
1763
1764 flag, mode = flag.update(mode)
1765 if mode == FTypeIdName {
1766 flag |= FmtUnsigned
1767 }
1768
1769 str := typefmt(t, flag, mode, depth+1)
1770
1771 return str
1772 }
1773
1774 func (n *Node) String() string { return fmt.Sprint(n) }
1775 func (n *Node) modeString(mode fmtMode) string { return mode.Sprint(n) }
1776
1777
1778
1779 func (n *Node) nconv(s fmt.State, flag FmtFlag, mode fmtMode) {
1780 if n == nil {
1781 fmt.Fprint(s, "<N>")
1782 return
1783 }
1784
1785 flag, mode = flag.update(mode)
1786
1787 switch mode {
1788 case FErr:
1789 n.nodefmt(s, flag, mode)
1790
1791 case FDbg:
1792 dumpdepth++
1793 n.nodedump(s, flag, mode)
1794 dumpdepth--
1795
1796 default:
1797 Fatalf("unhandled %%N mode: %d", mode)
1798 }
1799 }
1800
1801 func (l Nodes) format(s fmt.State, verb rune, mode fmtMode) {
1802 switch verb {
1803 case 'v':
1804 l.hconv(s, fmtFlag(s, verb), mode)
1805
1806 default:
1807 fmt.Fprintf(s, "%%!%c(Nodes)", verb)
1808 }
1809 }
1810
1811 func (n Nodes) String() string {
1812 return fmt.Sprint(n)
1813 }
1814
1815
1816 func (l Nodes) hconv(s fmt.State, flag FmtFlag, mode fmtMode) {
1817 if l.Len() == 0 && mode == FDbg {
1818 fmt.Fprint(s, "<nil>")
1819 return
1820 }
1821
1822 flag, mode = flag.update(mode)
1823 sep := "; "
1824 if mode == FDbg {
1825 sep = "\n"
1826 } else if flag&FmtComma != 0 {
1827 sep = ", "
1828 }
1829
1830 for i, n := range l.Slice() {
1831 fmt.Fprint(s, n.modeString(mode))
1832 if i+1 < l.Len() {
1833 fmt.Fprint(s, sep)
1834 }
1835 }
1836 }
1837
1838 func dumplist(s string, l Nodes) {
1839 fmt.Printf("%s%+v\n", s, l)
1840 }
1841
1842 func fdumplist(w io.Writer, s string, l Nodes) {
1843 fmt.Fprintf(w, "%s%+v\n", s, l)
1844 }
1845
1846 func Dump(s string, n *Node) {
1847 fmt.Printf("%s [%p]%+v\n", s, n, n)
1848 }
1849
1850
1851 var dumpdepth int
1852
1853
1854 func indent(s fmt.State) {
1855 fmt.Fprint(s, "\n")
1856 for i := 0; i < dumpdepth; i++ {
1857 fmt.Fprint(s, ". ")
1858 }
1859 }
1860
View as plain text