Source file src/pkg/cmd/compile/internal/types/type.go
1
2
3
4
5 package types
6
7 import (
8 "cmd/internal/obj"
9 "cmd/internal/src"
10 "fmt"
11 )
12
13
14
15
16 type Node struct{ _ int }
17
18
19
20
21 type EType uint8
22
23 const (
24 Txxx EType = iota
25
26 TINT8
27 TUINT8
28 TINT16
29 TUINT16
30 TINT32
31 TUINT32
32 TINT64
33 TUINT64
34 TINT
35 TUINT
36 TUINTPTR
37
38 TCOMPLEX64
39 TCOMPLEX128
40
41 TFLOAT32
42 TFLOAT64
43
44 TBOOL
45
46 TPTR
47 TFUNC
48 TSLICE
49 TARRAY
50 TSTRUCT
51 TCHAN
52 TMAP
53 TINTER
54 TFORW
55 TANY
56 TSTRING
57 TUNSAFEPTR
58
59
60 TIDEAL
61 TNIL
62 TBLANK
63
64
65 TFUNCARGS
66 TCHANARGS
67
68
69 TDDDFIELD
70
71
72 TSSA
73 TTUPLE
74
75 NTYPE
76 )
77
78
79 type ChanDir uint8
80
81 func (c ChanDir) CanRecv() bool { return c&Crecv != 0 }
82 func (c ChanDir) CanSend() bool { return c&Csend != 0 }
83
84 const (
85
86
87 Crecv ChanDir = 1 << 0
88 Csend ChanDir = 1 << 1
89 Cboth ChanDir = Crecv | Csend
90 )
91
92
93
94
95
96
97
98
99
100 var Types [NTYPE]*Type
101
102 var (
103
104 Bytetype *Type
105 Runetype *Type
106
107
108 Errortype *Type
109
110
111 Idealstring *Type
112 Idealbool *Type
113
114
115
116
117 Idealint = New(TIDEAL)
118 Idealrune = New(TIDEAL)
119 Idealfloat = New(TIDEAL)
120 Idealcomplex = New(TIDEAL)
121 )
122
123
124 type Type struct {
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 Extra interface{}
142
143
144 Width int64
145
146 methods Fields
147 allMethods Fields
148
149 Nod *Node
150 Orig *Type
151
152
153 Cache struct {
154 ptr *Type
155 slice *Type
156 }
157
158 Sym *Sym
159 Vargen int32
160
161 Etype EType
162 Align uint8
163
164 flags bitset8
165 }
166
167 const (
168 typeNotInHeap = 1 << iota
169 typeBroke
170 typeNoalg
171 typeDeferwidth
172 typeRecur
173 )
174
175 func (t *Type) NotInHeap() bool { return t.flags&typeNotInHeap != 0 }
176 func (t *Type) Broke() bool { return t.flags&typeBroke != 0 }
177 func (t *Type) Noalg() bool { return t.flags&typeNoalg != 0 }
178 func (t *Type) Deferwidth() bool { return t.flags&typeDeferwidth != 0 }
179 func (t *Type) Recur() bool { return t.flags&typeRecur != 0 }
180
181 func (t *Type) SetNotInHeap(b bool) { t.flags.set(typeNotInHeap, b) }
182 func (t *Type) SetBroke(b bool) { t.flags.set(typeBroke, b) }
183 func (t *Type) SetNoalg(b bool) { t.flags.set(typeNoalg, b) }
184 func (t *Type) SetDeferwidth(b bool) { t.flags.set(typeDeferwidth, b) }
185 func (t *Type) SetRecur(b bool) { t.flags.set(typeRecur, b) }
186
187
188
189
190
191
192
193 func (t *Type) Pkg() *Pkg {
194 switch t.Etype {
195 case TFUNC:
196 return t.Extra.(*Func).pkg
197 case TSTRUCT:
198 return t.Extra.(*Struct).pkg
199 case TINTER:
200 return t.Extra.(*Interface).pkg
201 default:
202 Fatalf("Pkg: unexpected kind: %v", t)
203 return nil
204 }
205 }
206
207
208 func (t *Type) SetPkg(pkg *Pkg) {
209 switch t.Etype {
210 case TFUNC:
211 t.Extra.(*Func).pkg = pkg
212 case TSTRUCT:
213 t.Extra.(*Struct).pkg = pkg
214 case TINTER:
215 t.Extra.(*Interface).pkg = pkg
216 default:
217 Fatalf("Pkg: unexpected kind: %v", t)
218 }
219 }
220
221
222 type Map struct {
223 Key *Type
224 Elem *Type
225
226 Bucket *Type
227 Hmap *Type
228 Hiter *Type
229 }
230
231
232 func (t *Type) MapType() *Map {
233 t.wantEtype(TMAP)
234 return t.Extra.(*Map)
235 }
236
237
238 type Forward struct {
239 Copyto []*Node
240 Embedlineno src.XPos
241 }
242
243
244 func (t *Type) ForwardType() *Forward {
245 t.wantEtype(TFORW)
246 return t.Extra.(*Forward)
247 }
248
249
250 type Func struct {
251 Receiver *Type
252 Results *Type
253 Params *Type
254
255 Nname *Node
256 pkg *Pkg
257
258
259
260
261 Argwid int64
262
263 Outnamed bool
264 }
265
266
267 func (t *Type) FuncType() *Func {
268 t.wantEtype(TFUNC)
269 return t.Extra.(*Func)
270 }
271
272
273 type Struct struct {
274 fields Fields
275 pkg *Pkg
276
277
278
279 Map *Type
280
281 Funarg Funarg
282 }
283
284
285 type Funarg uint8
286
287 const (
288 FunargNone Funarg = iota
289 FunargRcvr
290 FunargParams
291 FunargResults
292 )
293
294
295 func (t *Type) StructType() *Struct {
296 t.wantEtype(TSTRUCT)
297 return t.Extra.(*Struct)
298 }
299
300
301 type Interface struct {
302 Fields Fields
303 pkg *Pkg
304 }
305
306
307 type Ptr struct {
308 Elem *Type
309 }
310
311
312 type DDDField struct {
313 T *Type
314 }
315
316
317 type ChanArgs struct {
318 T *Type
319 }
320
321
322 type FuncArgs struct {
323 T *Type
324 }
325
326
327 type Chan struct {
328 Elem *Type
329 Dir ChanDir
330 }
331
332
333 func (t *Type) ChanType() *Chan {
334 t.wantEtype(TCHAN)
335 return t.Extra.(*Chan)
336 }
337
338 type Tuple struct {
339 first *Type
340 second *Type
341
342 }
343
344
345 type Array struct {
346 Elem *Type
347 Bound int64
348 }
349
350
351 type Slice struct {
352 Elem *Type
353 }
354
355
356
357 type Field struct {
358 flags bitset8
359
360 Embedded uint8
361
362 Pos src.XPos
363 Sym *Sym
364 Type *Type
365 Note string
366
367
368
369 Nname *Node
370
371
372
373 Offset int64
374 }
375
376 const (
377 fieldIsDDD = 1 << iota
378 fieldBroke
379 fieldNointerface
380 )
381
382 func (f *Field) IsDDD() bool { return f.flags&fieldIsDDD != 0 }
383 func (f *Field) Broke() bool { return f.flags&fieldBroke != 0 }
384 func (f *Field) Nointerface() bool { return f.flags&fieldNointerface != 0 }
385
386 func (f *Field) SetIsDDD(b bool) { f.flags.set(fieldIsDDD, b) }
387 func (f *Field) SetBroke(b bool) { f.flags.set(fieldBroke, b) }
388 func (f *Field) SetNointerface(b bool) { f.flags.set(fieldNointerface, b) }
389
390
391 func (f *Field) End() int64 {
392 return f.Offset + f.Type.Width
393 }
394
395
396 func (f *Field) IsMethod() bool {
397 return f.Type.Etype == TFUNC && f.Type.Recv() != nil
398 }
399
400
401
402
403 type Fields struct {
404 s *[]*Field
405 }
406
407
408 func (f *Fields) Len() int {
409 if f.s == nil {
410 return 0
411 }
412 return len(*f.s)
413 }
414
415
416
417 func (f *Fields) Slice() []*Field {
418 if f.s == nil {
419 return nil
420 }
421 return *f.s
422 }
423
424
425
426 func (f *Fields) Index(i int) *Field {
427 return (*f.s)[i]
428 }
429
430
431
432 func (f *Fields) Set(s []*Field) {
433 if len(s) == 0 {
434 f.s = nil
435 } else {
436
437
438 t := s
439 f.s = &t
440 }
441 }
442
443
444 func (f *Fields) Append(s ...*Field) {
445 if f.s == nil {
446 f.s = new([]*Field)
447 }
448 *f.s = append(*f.s, s...)
449 }
450
451
452 func New(et EType) *Type {
453 t := &Type{
454 Etype: et,
455 Width: BADWIDTH,
456 }
457 t.Orig = t
458
459 switch t.Etype {
460 case TMAP:
461 t.Extra = new(Map)
462 case TFORW:
463 t.Extra = new(Forward)
464 case TFUNC:
465 t.Extra = new(Func)
466 case TSTRUCT:
467 t.Extra = new(Struct)
468 case TINTER:
469 t.Extra = new(Interface)
470 case TPTR:
471 t.Extra = Ptr{}
472 case TCHANARGS:
473 t.Extra = ChanArgs{}
474 case TFUNCARGS:
475 t.Extra = FuncArgs{}
476 case TDDDFIELD:
477 t.Extra = DDDField{}
478 case TCHAN:
479 t.Extra = new(Chan)
480 case TTUPLE:
481 t.Extra = new(Tuple)
482 }
483 return t
484 }
485
486
487 func NewArray(elem *Type, bound int64) *Type {
488 if bound < 0 {
489 Fatalf("NewArray: invalid bound %v", bound)
490 }
491 t := New(TARRAY)
492 t.Extra = &Array{Elem: elem, Bound: bound}
493 t.SetNotInHeap(elem.NotInHeap())
494 return t
495 }
496
497
498 func NewSlice(elem *Type) *Type {
499 if t := elem.Cache.slice; t != nil {
500 if t.Elem() != elem {
501 Fatalf("elem mismatch")
502 }
503 return t
504 }
505
506 t := New(TSLICE)
507 t.Extra = Slice{Elem: elem}
508 elem.Cache.slice = t
509 return t
510 }
511
512
513 func NewDDDArray(elem *Type) *Type {
514 t := New(TARRAY)
515 t.Extra = &Array{Elem: elem, Bound: -1}
516 t.SetNotInHeap(elem.NotInHeap())
517 return t
518 }
519
520
521 func NewChan(elem *Type, dir ChanDir) *Type {
522 t := New(TCHAN)
523 ct := t.ChanType()
524 ct.Elem = elem
525 ct.Dir = dir
526 return t
527 }
528
529 func NewTuple(t1, t2 *Type) *Type {
530 t := New(TTUPLE)
531 t.Extra.(*Tuple).first = t1
532 t.Extra.(*Tuple).second = t2
533 return t
534 }
535
536 func newSSA(name string) *Type {
537 t := New(TSSA)
538 t.Extra = name
539 return t
540 }
541
542
543 func NewMap(k, v *Type) *Type {
544 t := New(TMAP)
545 mt := t.MapType()
546 mt.Key = k
547 mt.Elem = v
548 return t
549 }
550
551
552
553
554 var NewPtrCacheEnabled = true
555
556
557 func NewPtr(elem *Type) *Type {
558 if elem == nil {
559 Fatalf("NewPtr: pointer to elem Type is nil")
560 }
561
562 if t := elem.Cache.ptr; t != nil {
563 if t.Elem() != elem {
564 Fatalf("NewPtr: elem mismatch")
565 }
566 return t
567 }
568
569 t := New(TPTR)
570 t.Extra = Ptr{Elem: elem}
571 t.Width = int64(Widthptr)
572 t.Align = uint8(Widthptr)
573 if NewPtrCacheEnabled {
574 elem.Cache.ptr = t
575 }
576 return t
577 }
578
579
580 func NewDDDField(s *Type) *Type {
581 t := New(TDDDFIELD)
582 t.Extra = DDDField{T: s}
583 return t
584 }
585
586
587 func NewChanArgs(c *Type) *Type {
588 t := New(TCHANARGS)
589 t.Extra = ChanArgs{T: c}
590 return t
591 }
592
593
594 func NewFuncArgs(f *Type) *Type {
595 t := New(TFUNCARGS)
596 t.Extra = FuncArgs{T: f}
597 return t
598 }
599
600 func NewField() *Field {
601 return &Field{
602 Offset: BADWIDTH,
603 }
604 }
605
606
607
608 func SubstAny(t *Type, types *[]*Type) *Type {
609 if t == nil {
610 return nil
611 }
612
613 switch t.Etype {
614 default:
615
616
617 case TANY:
618 if len(*types) == 0 {
619 Fatalf("substArgTypes: not enough argument types")
620 }
621 t = (*types)[0]
622 *types = (*types)[1:]
623
624 case TPTR:
625 elem := SubstAny(t.Elem(), types)
626 if elem != t.Elem() {
627 t = t.copy()
628 t.Extra = Ptr{Elem: elem}
629 }
630
631 case TARRAY:
632 elem := SubstAny(t.Elem(), types)
633 if elem != t.Elem() {
634 t = t.copy()
635 t.Extra.(*Array).Elem = elem
636 }
637
638 case TSLICE:
639 elem := SubstAny(t.Elem(), types)
640 if elem != t.Elem() {
641 t = t.copy()
642 t.Extra = Slice{Elem: elem}
643 }
644
645 case TCHAN:
646 elem := SubstAny(t.Elem(), types)
647 if elem != t.Elem() {
648 t = t.copy()
649 t.Extra.(*Chan).Elem = elem
650 }
651
652 case TMAP:
653 key := SubstAny(t.Key(), types)
654 elem := SubstAny(t.Elem(), types)
655 if key != t.Key() || elem != t.Elem() {
656 t = t.copy()
657 t.Extra.(*Map).Key = key
658 t.Extra.(*Map).Elem = elem
659 }
660
661 case TFUNC:
662 recvs := SubstAny(t.Recvs(), types)
663 params := SubstAny(t.Params(), types)
664 results := SubstAny(t.Results(), types)
665 if recvs != t.Recvs() || params != t.Params() || results != t.Results() {
666 t = t.copy()
667 t.FuncType().Receiver = recvs
668 t.FuncType().Results = results
669 t.FuncType().Params = params
670 }
671
672 case TSTRUCT:
673
674
675
676 fields := t.FieldSlice()
677 nfs := make([]*Field, len(fields))
678 for i, f := range fields {
679 nft := SubstAny(f.Type, types)
680 nfs[i] = f.Copy()
681 nfs[i].Type = nft
682 }
683 t = t.copy()
684 t.SetFields(nfs)
685 }
686
687 return t
688 }
689
690
691 func (t *Type) copy() *Type {
692 if t == nil {
693 return nil
694 }
695 nt := *t
696
697 switch t.Etype {
698 case TMAP:
699 x := *t.Extra.(*Map)
700 nt.Extra = &x
701 case TFORW:
702 x := *t.Extra.(*Forward)
703 nt.Extra = &x
704 case TFUNC:
705 x := *t.Extra.(*Func)
706 nt.Extra = &x
707 case TSTRUCT:
708 x := *t.Extra.(*Struct)
709 nt.Extra = &x
710 case TINTER:
711 x := *t.Extra.(*Interface)
712 nt.Extra = &x
713 case TCHAN:
714 x := *t.Extra.(*Chan)
715 nt.Extra = &x
716 case TARRAY:
717 x := *t.Extra.(*Array)
718 nt.Extra = &x
719 case TTUPLE, TSSA:
720 Fatalf("ssa types cannot be copied")
721 }
722
723 if t.Orig == t {
724 nt.Orig = &nt
725 }
726 return &nt
727 }
728
729 func (f *Field) Copy() *Field {
730 nf := *f
731 return &nf
732 }
733
734 func (t *Type) wantEtype(et EType) {
735 if t.Etype != et {
736 Fatalf("want %v, but have %v", et, t)
737 }
738 }
739
740 func (t *Type) Recvs() *Type { return t.FuncType().Receiver }
741 func (t *Type) Params() *Type { return t.FuncType().Params }
742 func (t *Type) Results() *Type { return t.FuncType().Results }
743
744 func (t *Type) NumRecvs() int { return t.FuncType().Receiver.NumFields() }
745 func (t *Type) NumParams() int { return t.FuncType().Params.NumFields() }
746 func (t *Type) NumResults() int { return t.FuncType().Results.NumFields() }
747
748
749 func (t *Type) IsVariadic() bool {
750 n := t.NumParams()
751 return n > 0 && t.Params().Field(n-1).IsDDD()
752 }
753
754
755 func (t *Type) Recv() *Field {
756 s := t.Recvs()
757 if s.NumFields() == 0 {
758 return nil
759 }
760 return s.Field(0)
761 }
762
763
764
765
766 var RecvsParamsResults = [3]func(*Type) *Type{
767 (*Type).Recvs, (*Type).Params, (*Type).Results,
768 }
769
770
771 var RecvsParams = [2]func(*Type) *Type{
772 (*Type).Recvs, (*Type).Params,
773 }
774
775
776 var ParamsResults = [2]func(*Type) *Type{
777 (*Type).Params, (*Type).Results,
778 }
779
780
781 func (t *Type) Key() *Type {
782 t.wantEtype(TMAP)
783 return t.Extra.(*Map).Key
784 }
785
786
787
788 func (t *Type) Elem() *Type {
789 switch t.Etype {
790 case TPTR:
791 return t.Extra.(Ptr).Elem
792 case TARRAY:
793 return t.Extra.(*Array).Elem
794 case TSLICE:
795 return t.Extra.(Slice).Elem
796 case TCHAN:
797 return t.Extra.(*Chan).Elem
798 case TMAP:
799 return t.Extra.(*Map).Elem
800 }
801 Fatalf("Type.Elem %s", t.Etype)
802 return nil
803 }
804
805
806 func (t *Type) DDDField() *Type {
807 t.wantEtype(TDDDFIELD)
808 return t.Extra.(DDDField).T
809 }
810
811
812 func (t *Type) ChanArgs() *Type {
813 t.wantEtype(TCHANARGS)
814 return t.Extra.(ChanArgs).T
815 }
816
817
818 func (t *Type) FuncArgs() *Type {
819 t.wantEtype(TFUNCARGS)
820 return t.Extra.(FuncArgs).T
821 }
822
823
824 func (t *Type) Nname() *Node {
825 switch t.Etype {
826 case TFUNC:
827 return t.Extra.(*Func).Nname
828 }
829 Fatalf("Type.Nname %v %v", t.Etype, t)
830 return nil
831 }
832
833
834 func (t *Type) SetNname(n *Node) {
835 switch t.Etype {
836 case TFUNC:
837 t.Extra.(*Func).Nname = n
838 default:
839 Fatalf("Type.SetNname %v %v", t.Etype, t)
840 }
841 }
842
843
844 func (t *Type) IsFuncArgStruct() bool {
845 return t.Etype == TSTRUCT && t.Extra.(*Struct).Funarg != FunargNone
846 }
847
848 func (t *Type) Methods() *Fields {
849
850 return &t.methods
851 }
852
853 func (t *Type) AllMethods() *Fields {
854
855 return &t.allMethods
856 }
857
858 func (t *Type) Fields() *Fields {
859 switch t.Etype {
860 case TSTRUCT:
861 return &t.Extra.(*Struct).fields
862 case TINTER:
863 Dowidth(t)
864 return &t.Extra.(*Interface).Fields
865 }
866 Fatalf("Fields: type %v does not have fields", t)
867 return nil
868 }
869
870
871 func (t *Type) Field(i int) *Field {
872 return t.Fields().Slice()[i]
873 }
874
875
876
877 func (t *Type) FieldSlice() []*Field {
878 return t.Fields().Slice()
879 }
880
881
882 func (t *Type) SetFields(fields []*Field) {
883
884
885
886
887
888
889 if t.WidthCalculated() {
890 Fatalf("SetFields of %v: width previously calculated", t)
891 }
892 t.wantEtype(TSTRUCT)
893 for _, f := range fields {
894
895
896
897
898
899 if f.Type != nil && f.Type.NotInHeap() {
900 t.SetNotInHeap(true)
901 break
902 }
903 }
904 t.Fields().Set(fields)
905 }
906
907 func (t *Type) SetInterface(methods []*Field) {
908 t.wantEtype(TINTER)
909 t.Methods().Set(methods)
910 }
911
912 func (t *Type) IsDDDArray() bool {
913 if t.Etype != TARRAY {
914 return false
915 }
916 return t.Extra.(*Array).Bound < 0
917 }
918
919 func (t *Type) WidthCalculated() bool {
920 return t.Align > 0
921 }
922
923
924
925 func (t *Type) ArgWidth() int64 {
926 t.wantEtype(TFUNC)
927 return t.Extra.(*Func).Argwid
928 }
929
930 func (t *Type) Size() int64 {
931 if t.Etype == TSSA {
932 if t == TypeInt128 {
933 return 16
934 }
935 return 0
936 }
937 Dowidth(t)
938 return t.Width
939 }
940
941 func (t *Type) Alignment() int64 {
942 Dowidth(t)
943 return int64(t.Align)
944 }
945
946 func (t *Type) SimpleString() string {
947 return t.Etype.String()
948 }
949
950
951
952
953
954 type Cmp int8
955
956 const (
957 CMPlt = Cmp(-1)
958 CMPeq = Cmp(0)
959 CMPgt = Cmp(1)
960 )
961
962
963
964
965
966
967
968 func (t *Type) Compare(x *Type) Cmp {
969 if x == t {
970 return CMPeq
971 }
972 return t.cmp(x)
973 }
974
975 func cmpForNe(x bool) Cmp {
976 if x {
977 return CMPlt
978 }
979 return CMPgt
980 }
981
982 func (r *Sym) cmpsym(s *Sym) Cmp {
983 if r == s {
984 return CMPeq
985 }
986 if r == nil {
987 return CMPlt
988 }
989 if s == nil {
990 return CMPgt
991 }
992
993 if len(r.Name) != len(s.Name) {
994 return cmpForNe(len(r.Name) < len(s.Name))
995 }
996 if r.Pkg != s.Pkg {
997 if len(r.Pkg.Prefix) != len(s.Pkg.Prefix) {
998 return cmpForNe(len(r.Pkg.Prefix) < len(s.Pkg.Prefix))
999 }
1000 if r.Pkg.Prefix != s.Pkg.Prefix {
1001 return cmpForNe(r.Pkg.Prefix < s.Pkg.Prefix)
1002 }
1003 }
1004 if r.Name != s.Name {
1005 return cmpForNe(r.Name < s.Name)
1006 }
1007 return CMPeq
1008 }
1009
1010
1011
1012
1013
1014
1015 func (t *Type) cmp(x *Type) Cmp {
1016
1017
1018
1019
1020
1021 if t == x {
1022 return CMPeq
1023 }
1024 if t == nil {
1025 return CMPlt
1026 }
1027 if x == nil {
1028 return CMPgt
1029 }
1030
1031 if t.Etype != x.Etype {
1032 return cmpForNe(t.Etype < x.Etype)
1033 }
1034
1035 if t.Sym != nil || x.Sym != nil {
1036
1037
1038 switch t.Etype {
1039 case TUINT8:
1040 if (t == Types[TUINT8] || t == Bytetype) && (x == Types[TUINT8] || x == Bytetype) {
1041 return CMPeq
1042 }
1043
1044 case TINT32:
1045 if (t == Types[Runetype.Etype] || t == Runetype) && (x == Types[Runetype.Etype] || x == Runetype) {
1046 return CMPeq
1047 }
1048 }
1049 }
1050
1051 if c := t.Sym.cmpsym(x.Sym); c != CMPeq {
1052 return c
1053 }
1054
1055 if x.Sym != nil {
1056
1057 if t.Vargen != x.Vargen {
1058 return cmpForNe(t.Vargen < x.Vargen)
1059 }
1060 return CMPeq
1061 }
1062
1063
1064 switch t.Etype {
1065 case TBOOL, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TUNSAFEPTR, TUINTPTR,
1066 TINT8, TINT16, TINT32, TINT64, TINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINT:
1067 return CMPeq
1068
1069 case TSSA:
1070 tname := t.Extra.(string)
1071 xname := t.Extra.(string)
1072
1073 if len(tname) == len(xname) {
1074 if tname == xname {
1075 return CMPeq
1076 }
1077 if tname < xname {
1078 return CMPlt
1079 }
1080 return CMPgt
1081 }
1082 if len(tname) > len(xname) {
1083 return CMPgt
1084 }
1085 return CMPlt
1086
1087 case TTUPLE:
1088 xtup := x.Extra.(*Tuple)
1089 ttup := t.Extra.(*Tuple)
1090 if c := ttup.first.Compare(xtup.first); c != CMPeq {
1091 return c
1092 }
1093 return ttup.second.Compare(xtup.second)
1094
1095 case TMAP:
1096 if c := t.Key().cmp(x.Key()); c != CMPeq {
1097 return c
1098 }
1099 return t.Elem().cmp(x.Elem())
1100
1101 case TPTR, TSLICE:
1102
1103
1104
1105 case TSTRUCT:
1106 if t.StructType().Map == nil {
1107 if x.StructType().Map != nil {
1108 return CMPlt
1109 }
1110
1111 } else if x.StructType().Map == nil {
1112 return CMPgt
1113 } else if t.StructType().Map.MapType().Bucket == t {
1114
1115
1116 if x.StructType().Map.MapType().Bucket != x {
1117 return CMPlt
1118 }
1119 return t.StructType().Map.cmp(x.StructType().Map)
1120 } else if x.StructType().Map.MapType().Bucket == x {
1121 return CMPgt
1122 }
1123
1124 tfs := t.FieldSlice()
1125 xfs := x.FieldSlice()
1126 for i := 0; i < len(tfs) && i < len(xfs); i++ {
1127 t1, x1 := tfs[i], xfs[i]
1128 if t1.Embedded != x1.Embedded {
1129 return cmpForNe(t1.Embedded < x1.Embedded)
1130 }
1131 if t1.Note != x1.Note {
1132 return cmpForNe(t1.Note < x1.Note)
1133 }
1134 if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
1135 return c
1136 }
1137 if c := t1.Type.cmp(x1.Type); c != CMPeq {
1138 return c
1139 }
1140 }
1141 if len(tfs) != len(xfs) {
1142 return cmpForNe(len(tfs) < len(xfs))
1143 }
1144 return CMPeq
1145
1146 case TINTER:
1147 tfs := t.FieldSlice()
1148 xfs := x.FieldSlice()
1149 for i := 0; i < len(tfs) && i < len(xfs); i++ {
1150 t1, x1 := tfs[i], xfs[i]
1151 if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
1152 return c
1153 }
1154 if c := t1.Type.cmp(x1.Type); c != CMPeq {
1155 return c
1156 }
1157 }
1158 if len(tfs) != len(xfs) {
1159 return cmpForNe(len(tfs) < len(xfs))
1160 }
1161 return CMPeq
1162
1163 case TFUNC:
1164 for _, f := range RecvsParamsResults {
1165
1166 tfs := f(t).FieldSlice()
1167 xfs := f(x).FieldSlice()
1168 for i := 0; i < len(tfs) && i < len(xfs); i++ {
1169 ta := tfs[i]
1170 tb := xfs[i]
1171 if ta.IsDDD() != tb.IsDDD() {
1172 return cmpForNe(!ta.IsDDD())
1173 }
1174 if c := ta.Type.cmp(tb.Type); c != CMPeq {
1175 return c
1176 }
1177 }
1178 if len(tfs) != len(xfs) {
1179 return cmpForNe(len(tfs) < len(xfs))
1180 }
1181 }
1182 return CMPeq
1183
1184 case TARRAY:
1185 if t.NumElem() != x.NumElem() {
1186 return cmpForNe(t.NumElem() < x.NumElem())
1187 }
1188
1189 case TCHAN:
1190 if t.ChanDir() != x.ChanDir() {
1191 return cmpForNe(t.ChanDir() < x.ChanDir())
1192 }
1193
1194 default:
1195 e := fmt.Sprintf("Do not know how to compare %v with %v", t, x)
1196 panic(e)
1197 }
1198
1199
1200 return t.Elem().cmp(x.Elem())
1201 }
1202
1203
1204 func (t *Type) IsKind(et EType) bool {
1205 return t != nil && t.Etype == et
1206 }
1207
1208 func (t *Type) IsBoolean() bool {
1209 return t.Etype == TBOOL
1210 }
1211
1212 var unsignedEType = [...]EType{
1213 TINT8: TUINT8,
1214 TUINT8: TUINT8,
1215 TINT16: TUINT16,
1216 TUINT16: TUINT16,
1217 TINT32: TUINT32,
1218 TUINT32: TUINT32,
1219 TINT64: TUINT64,
1220 TUINT64: TUINT64,
1221 TINT: TUINT,
1222 TUINT: TUINT,
1223 TUINTPTR: TUINTPTR,
1224 }
1225
1226
1227 func (t *Type) ToUnsigned() *Type {
1228 if !t.IsInteger() {
1229 Fatalf("unsignedType(%v)", t)
1230 }
1231 return Types[unsignedEType[t.Etype]]
1232 }
1233
1234 func (t *Type) IsInteger() bool {
1235 switch t.Etype {
1236 case TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64, TUINT64, TINT, TUINT, TUINTPTR:
1237 return true
1238 }
1239 return false
1240 }
1241
1242 func (t *Type) IsSigned() bool {
1243 switch t.Etype {
1244 case TINT8, TINT16, TINT32, TINT64, TINT:
1245 return true
1246 }
1247 return false
1248 }
1249
1250 func (t *Type) IsFloat() bool {
1251 return t.Etype == TFLOAT32 || t.Etype == TFLOAT64
1252 }
1253
1254 func (t *Type) IsComplex() bool {
1255 return t.Etype == TCOMPLEX64 || t.Etype == TCOMPLEX128
1256 }
1257
1258
1259
1260 func (t *Type) IsPtr() bool {
1261 return t.Etype == TPTR
1262 }
1263
1264
1265 func (t *Type) IsPtrElem() bool {
1266 return t.Cache.ptr != nil
1267 }
1268
1269
1270 func (t *Type) IsUnsafePtr() bool {
1271 return t.Etype == TUNSAFEPTR
1272 }
1273
1274
1275
1276
1277
1278
1279 func (t *Type) IsPtrShaped() bool {
1280 return t.Etype == TPTR || t.Etype == TUNSAFEPTR ||
1281 t.Etype == TMAP || t.Etype == TCHAN || t.Etype == TFUNC
1282 }
1283
1284 func (t *Type) IsString() bool {
1285 return t.Etype == TSTRING
1286 }
1287
1288 func (t *Type) IsMap() bool {
1289 return t.Etype == TMAP
1290 }
1291
1292 func (t *Type) IsChan() bool {
1293 return t.Etype == TCHAN
1294 }
1295
1296 func (t *Type) IsSlice() bool {
1297 return t.Etype == TSLICE
1298 }
1299
1300 func (t *Type) IsArray() bool {
1301 return t.Etype == TARRAY
1302 }
1303
1304 func (t *Type) IsStruct() bool {
1305 return t.Etype == TSTRUCT
1306 }
1307
1308 func (t *Type) IsInterface() bool {
1309 return t.Etype == TINTER
1310 }
1311
1312
1313 func (t *Type) IsEmptyInterface() bool {
1314 return t.IsInterface() && t.NumFields() == 0
1315 }
1316
1317 func (t *Type) PtrTo() *Type {
1318 return NewPtr(t)
1319 }
1320
1321 func (t *Type) NumFields() int {
1322 return t.Fields().Len()
1323 }
1324 func (t *Type) FieldType(i int) *Type {
1325 if t.Etype == TTUPLE {
1326 switch i {
1327 case 0:
1328 return t.Extra.(*Tuple).first
1329 case 1:
1330 return t.Extra.(*Tuple).second
1331 default:
1332 panic("bad tuple index")
1333 }
1334 }
1335 return t.Field(i).Type
1336 }
1337 func (t *Type) FieldOff(i int) int64 {
1338 return t.Field(i).Offset
1339 }
1340 func (t *Type) FieldName(i int) string {
1341 return t.Field(i).Sym.Name
1342 }
1343
1344 func (t *Type) NumElem() int64 {
1345 t.wantEtype(TARRAY)
1346 at := t.Extra.(*Array)
1347 if at.Bound < 0 {
1348 Fatalf("NumElem array %v does not have bound yet", t)
1349 }
1350 return at.Bound
1351 }
1352
1353
1354
1355
1356 func (t *Type) SetNumElem(n int64) {
1357 t.wantEtype(TARRAY)
1358 at := t.Extra.(*Array)
1359 if at.Bound >= 0 {
1360 Fatalf("SetNumElem array %v already has bound %d", t, at.Bound)
1361 }
1362 at.Bound = n
1363 }
1364
1365 type componentsIncludeBlankFields bool
1366
1367 const (
1368 IgnoreBlankFields componentsIncludeBlankFields = false
1369 CountBlankFields componentsIncludeBlankFields = true
1370 )
1371
1372
1373
1374
1375
1376
1377
1378 func (t *Type) NumComponents(countBlank componentsIncludeBlankFields) int64 {
1379 switch t.Etype {
1380 case TSTRUCT:
1381 if t.IsFuncArgStruct() {
1382 Fatalf("NumComponents func arg struct")
1383 }
1384 var n int64
1385 for _, f := range t.FieldSlice() {
1386 if countBlank == IgnoreBlankFields && f.Sym.IsBlank() {
1387 continue
1388 }
1389 n += f.Type.NumComponents(countBlank)
1390 }
1391 return n
1392 case TARRAY:
1393 return t.NumElem() * t.Elem().NumComponents(countBlank)
1394 }
1395 return 1
1396 }
1397
1398
1399
1400
1401 func (t *Type) SoleComponent() *Type {
1402 switch t.Etype {
1403 case TSTRUCT:
1404 if t.IsFuncArgStruct() {
1405 Fatalf("SoleComponent func arg struct")
1406 }
1407 if t.NumFields() != 1 {
1408 return nil
1409 }
1410 return t.Field(0).Type.SoleComponent()
1411 case TARRAY:
1412 if t.NumElem() != 1 {
1413 return nil
1414 }
1415 return t.Elem().SoleComponent()
1416 }
1417 return t
1418 }
1419
1420
1421
1422 func (t *Type) ChanDir() ChanDir {
1423 t.wantEtype(TCHAN)
1424 return t.Extra.(*Chan).Dir
1425 }
1426
1427 func (t *Type) IsMemory() bool {
1428 return t == TypeMem || t.Etype == TTUPLE && t.Extra.(*Tuple).second == TypeMem
1429 }
1430 func (t *Type) IsFlags() bool { return t == TypeFlags }
1431 func (t *Type) IsVoid() bool { return t == TypeVoid }
1432 func (t *Type) IsTuple() bool { return t.Etype == TTUPLE }
1433
1434
1435 func (t *Type) IsUntyped() bool {
1436 if t == nil {
1437 return false
1438 }
1439 if t == Idealstring || t == Idealbool {
1440 return true
1441 }
1442 switch t.Etype {
1443 case TNIL, TIDEAL:
1444 return true
1445 }
1446 return false
1447 }
1448
1449
1450
1451
1452 func Haspointers(t *Type) bool {
1453 return Haspointers1(t, false)
1454 }
1455
1456 func Haspointers1(t *Type, ignoreNotInHeap bool) bool {
1457 switch t.Etype {
1458 case TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64,
1459 TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL, TSSA:
1460 return false
1461
1462 case TARRAY:
1463 if t.NumElem() == 0 {
1464 return false
1465 }
1466 return Haspointers1(t.Elem(), ignoreNotInHeap)
1467
1468 case TSTRUCT:
1469 for _, t1 := range t.Fields().Slice() {
1470 if Haspointers1(t1.Type, ignoreNotInHeap) {
1471 return true
1472 }
1473 }
1474 return false
1475
1476 case TPTR, TSLICE:
1477 return !(ignoreNotInHeap && t.Elem().NotInHeap())
1478
1479 case TTUPLE:
1480 ttup := t.Extra.(*Tuple)
1481 return Haspointers1(ttup.first, ignoreNotInHeap) || Haspointers1(ttup.second, ignoreNotInHeap)
1482 }
1483
1484 return true
1485 }
1486
1487
1488
1489
1490 func (t *Type) HasHeapPointer() bool {
1491 return Haspointers1(t, true)
1492 }
1493
1494 func (t *Type) Symbol() *obj.LSym {
1495 return TypeLinkSym(t)
1496 }
1497
1498
1499
1500
1501 func (t *Type) Tie() byte {
1502 if t.IsEmptyInterface() {
1503 return 'E'
1504 }
1505 if t.IsInterface() {
1506 return 'I'
1507 }
1508 return 'T'
1509 }
1510
1511 var recvType *Type
1512
1513
1514 func FakeRecvType() *Type {
1515 if recvType == nil {
1516 recvType = NewPtr(New(TSTRUCT))
1517 }
1518 return recvType
1519 }
1520
1521 var (
1522
1523 TypeInvalid = newSSA("invalid")
1524 TypeMem = newSSA("mem")
1525 TypeFlags = newSSA("flags")
1526 TypeVoid = newSSA("void")
1527 TypeInt128 = newSSA("int128")
1528 )
1529
View as plain text