1
2
3
4
5 package types
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/internal/objabi"
10 "cmd/internal/src"
11 "fmt"
12 "go/constant"
13 "internal/types/errors"
14 "sync"
15 )
16
17
18
19
20 type Object interface {
21 Pos() src.XPos
22 Sym() *Sym
23 Type() *Type
24 }
25
26
27
28
29 type Kind uint8
30
31 const (
32 Txxx Kind = iota
33
34 TINT8
35 TUINT8
36 TINT16
37 TUINT16
38 TINT32
39 TUINT32
40 TINT64
41 TUINT64
42 TINT
43 TUINT
44 TUINTPTR
45
46 TCOMPLEX64
47 TCOMPLEX128
48
49 TFLOAT32
50 TFLOAT64
51
52 TBOOL
53
54 TPTR
55 TFUNC
56 TSLICE
57 TARRAY
58 TSTRUCT
59 TCHAN
60 TMAP
61 TINTER
62 TFORW
63 TANY
64 TSTRING
65 TUNSAFEPTR
66
67
68 TIDEAL
69 TNIL
70 TBLANK
71
72
73 TFUNCARGS
74 TCHANARGS
75
76
77 TSSA
78 TTUPLE
79 TRESULTS
80
81 NTYPE
82 )
83
84
85 type ChanDir uint8
86
87 func (c ChanDir) CanRecv() bool { return c&Crecv != 0 }
88 func (c ChanDir) CanSend() bool { return c&Csend != 0 }
89
90 const (
91
92
93 Crecv ChanDir = 1 << 0
94 Csend ChanDir = 1 << 1
95 Cboth ChanDir = Crecv | Csend
96 )
97
98
99
100
101
102
103
104
105
106 var Types [NTYPE]*Type
107
108 var (
109
110
111
112 AnyType *Type
113 ByteType *Type
114 RuneType *Type
115
116
117 ErrorType *Type
118
119 ComparableType *Type
120
121
122 UntypedString = newType(TSTRING)
123 UntypedBool = newType(TBOOL)
124
125
126 UntypedInt = newType(TIDEAL)
127 UntypedRune = newType(TIDEAL)
128 UntypedFloat = newType(TIDEAL)
129 UntypedComplex = newType(TIDEAL)
130 )
131
132
133
134 var UntypedTypes = [...]*Type{
135 constant.Bool: UntypedBool,
136 constant.String: UntypedString,
137 constant.Int: UntypedInt,
138 constant.Float: UntypedFloat,
139 constant.Complex: UntypedComplex,
140 }
141
142
143 var DefaultKinds = [...]Kind{
144 constant.Bool: TBOOL,
145 constant.String: TSTRING,
146 constant.Int: TINT,
147 constant.Float: TFLOAT64,
148 constant.Complex: TCOMPLEX128,
149 }
150
151
152
153
154
155
156
157
158
159
160 type Type struct {
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 extra any
178
179
180 width int64
181
182
183 methods fields
184
185 allMethods fields
186
187
188 obj Object
189
190 underlying *Type
191
192
193 cache struct {
194 ptr *Type
195 slice *Type
196 }
197
198 kind Kind
199 align uint8
200
201 intRegs, floatRegs uint8
202
203 flags bitset8
204 alg AlgKind
205 isSIMDTag, isSIMD bool
206
207
208
209
210 ptrBytes int64
211 }
212
213
214
215
216
217
218
219 func (t *Type) Registers() (uint8, uint8) {
220 CalcSize(t)
221 return t.intRegs, t.floatRegs
222 }
223
224 func (*Type) CanBeAnSSAAux() {}
225
226 const (
227 typeNotInHeap = 1 << iota
228 typeNoalg
229 typeDeferwidth
230 typeRecur
231 typeIsShape
232 typeHasShape
233
234
235 typeIsFullyInstantiated
236 )
237
238 func (t *Type) NotInHeap() bool { return t.flags&typeNotInHeap != 0 }
239 func (t *Type) Noalg() bool { return t.flags&typeNoalg != 0 }
240 func (t *Type) Deferwidth() bool { return t.flags&typeDeferwidth != 0 }
241 func (t *Type) Recur() bool { return t.flags&typeRecur != 0 }
242 func (t *Type) IsShape() bool { return t.flags&typeIsShape != 0 }
243 func (t *Type) HasShape() bool { return t.flags&typeHasShape != 0 }
244 func (t *Type) IsFullyInstantiated() bool { return t.flags&typeIsFullyInstantiated != 0 }
245
246 func (t *Type) SetNotInHeap(b bool) { t.flags.set(typeNotInHeap, b) }
247 func (t *Type) SetNoalg(b bool) { t.flags.set(typeNoalg, b) }
248 func (t *Type) SetDeferwidth(b bool) { t.flags.set(typeDeferwidth, b) }
249 func (t *Type) SetRecur(b bool) { t.flags.set(typeRecur, b) }
250 func (t *Type) SetIsFullyInstantiated(b bool) { t.flags.set(typeIsFullyInstantiated, b) }
251
252
253 func (t *Type) SetIsShape(b bool) { t.flags.set(typeIsShape, b) }
254 func (t *Type) SetHasShape(b bool) { t.flags.set(typeHasShape, b) }
255
256
257 func (t *Type) Kind() Kind { return t.kind }
258
259
260 func (t *Type) Sym() *Sym {
261 if t.obj != nil {
262 return t.obj.Sym()
263 }
264 return nil
265 }
266
267
268 func (t *Type) Underlying() *Type { return t.underlying }
269
270
271
272 func (t *Type) Pos() src.XPos {
273 if t.obj != nil {
274 return t.obj.Pos()
275 }
276 return src.NoXPos
277 }
278
279
280 type Map struct {
281 Key *Type
282 Elem *Type
283
284 Group *Type
285 }
286
287
288 func (t *Type) MapType() *Map {
289 t.wantEtype(TMAP)
290 return t.extra.(*Map)
291 }
292
293
294 type Forward struct {
295 Copyto []*Type
296 Embedlineno src.XPos
297 }
298
299
300 func (t *Type) forwardType() *Forward {
301 t.wantEtype(TFORW)
302 return t.extra.(*Forward)
303 }
304
305
306 type Func struct {
307 allParams []*Field
308
309 startParams int
310 startResults int
311
312 resultsTuple *Type
313
314
315
316
317 Argwid int64
318 }
319
320 func (ft *Func) recvs() []*Field { return ft.allParams[:ft.startParams] }
321 func (ft *Func) params() []*Field { return ft.allParams[ft.startParams:ft.startResults] }
322 func (ft *Func) results() []*Field { return ft.allParams[ft.startResults:] }
323 func (ft *Func) recvParams() []*Field { return ft.allParams[:ft.startResults] }
324 func (ft *Func) paramsResults() []*Field { return ft.allParams[ft.startParams:] }
325
326
327 func (t *Type) funcType() *Func {
328 t.wantEtype(TFUNC)
329 return t.extra.(*Func)
330 }
331
332
333 type Struct struct {
334 fields fields
335
336
337
338 Map *Type
339
340 ParamTuple bool
341 }
342
343
344 func (t *Type) StructType() *Struct {
345 t.wantEtype(TSTRUCT)
346 return t.extra.(*Struct)
347 }
348
349
350 type Interface struct {
351 }
352
353
354 type Ptr struct {
355 Elem *Type
356 }
357
358
359 type ChanArgs struct {
360 T *Type
361 }
362
363
364 type FuncArgs struct {
365 T *Type
366 }
367
368
369 type Chan struct {
370 Elem *Type
371 Dir ChanDir
372 }
373
374
375 func (t *Type) chanType() *Chan {
376 t.wantEtype(TCHAN)
377 return t.extra.(*Chan)
378 }
379
380 type Tuple struct {
381 first *Type
382 second *Type
383
384 }
385
386
387 type Results struct {
388 Types []*Type
389 }
390
391
392 type Array struct {
393 Elem *Type
394 Bound int64
395 }
396
397
398 type Slice struct {
399 Elem *Type
400 }
401
402
403
404
405
406
407 type Field struct {
408 flags bitset8
409
410 Embedded uint8
411
412 Pos src.XPos
413
414
415
416 Sym *Sym
417 Type *Type
418 Note string
419
420
421
422
423 Nname Object
424
425
426
427 Offset int64
428 }
429
430 const (
431 fieldIsDDD = 1 << iota
432 fieldNointerface
433 )
434
435 func (f *Field) IsDDD() bool { return f.flags&fieldIsDDD != 0 }
436 func (f *Field) Nointerface() bool { return f.flags&fieldNointerface != 0 }
437
438 func (f *Field) SetIsDDD(b bool) { f.flags.set(fieldIsDDD, b) }
439 func (f *Field) SetNointerface(b bool) { f.flags.set(fieldNointerface, b) }
440
441
442 func (f *Field) End() int64 {
443 return f.Offset + f.Type.width
444 }
445
446
447 func (f *Field) IsMethod() bool {
448 return f.Type.kind == TFUNC && f.Type.Recv() != nil
449 }
450
451
452 func CompareFields(a, b *Field) int {
453 return CompareSyms(a.Sym, b.Sym)
454 }
455
456
457
458
459 type fields struct {
460 s *[]*Field
461 }
462
463
464
465 func (f *fields) Slice() []*Field {
466 if f.s == nil {
467 return nil
468 }
469 return *f.s
470 }
471
472
473
474 func (f *fields) Set(s []*Field) {
475 if len(s) == 0 {
476 f.s = nil
477 } else {
478
479
480 t := s
481 f.s = &t
482 }
483 }
484
485
486 func newType(et Kind) *Type {
487 t := &Type{
488 kind: et,
489 width: BADWIDTH,
490 }
491 t.underlying = t
492
493 switch t.kind {
494 case TMAP:
495 t.extra = new(Map)
496 case TFORW:
497 t.extra = new(Forward)
498 case TFUNC:
499 t.extra = new(Func)
500 case TSTRUCT:
501 t.extra = new(Struct)
502 case TINTER:
503 t.extra = new(Interface)
504 case TPTR:
505 t.extra = Ptr{}
506 case TCHANARGS:
507 t.extra = ChanArgs{}
508 case TFUNCARGS:
509 t.extra = FuncArgs{}
510 case TCHAN:
511 t.extra = new(Chan)
512 case TTUPLE:
513 t.extra = new(Tuple)
514 case TRESULTS:
515 t.extra = new(Results)
516 }
517 return t
518 }
519
520
521 func NewArray(elem *Type, bound int64) *Type {
522 if bound < 0 {
523 base.Fatalf("NewArray: invalid bound %v", bound)
524 }
525 t := newType(TARRAY)
526 t.extra = &Array{Elem: elem, Bound: bound}
527 if elem.HasShape() {
528 t.SetHasShape(true)
529 }
530 if elem.NotInHeap() {
531 t.SetNotInHeap(true)
532 }
533 return t
534 }
535
536
537 func NewSlice(elem *Type) *Type {
538 if t := elem.cache.slice; t != nil {
539 if t.Elem() != elem {
540 base.Fatalf("elem mismatch")
541 }
542 if elem.HasShape() != t.HasShape() {
543 base.Fatalf("Incorrect HasShape flag for cached slice type")
544 }
545 return t
546 }
547
548 t := newType(TSLICE)
549 t.extra = Slice{Elem: elem}
550 elem.cache.slice = t
551 if elem.HasShape() {
552 t.SetHasShape(true)
553 }
554 return t
555 }
556
557
558 func NewChan(elem *Type, dir ChanDir) *Type {
559 t := newType(TCHAN)
560 ct := t.chanType()
561 ct.Elem = elem
562 ct.Dir = dir
563 if elem.HasShape() {
564 t.SetHasShape(true)
565 }
566 return t
567 }
568
569 func NewTuple(t1, t2 *Type) *Type {
570 t := newType(TTUPLE)
571 t.extra.(*Tuple).first = t1
572 t.extra.(*Tuple).second = t2
573 if t1.HasShape() || t2.HasShape() {
574 t.SetHasShape(true)
575 }
576 return t
577 }
578
579 func newResults(types []*Type) *Type {
580 t := newType(TRESULTS)
581 t.extra.(*Results).Types = types
582 return t
583 }
584
585 func NewResults(types []*Type) *Type {
586 if len(types) == 1 && types[0] == TypeMem {
587 return TypeResultMem
588 }
589 return newResults(types)
590 }
591
592 func newSSA(name string) *Type {
593 t := newType(TSSA)
594 t.extra = name
595 return t
596 }
597
598 func newSIMD(name string) *Type {
599 t := newSSA(name)
600 t.isSIMD = true
601 return t
602 }
603
604
605 func NewMap(k, v *Type) *Type {
606 t := newType(TMAP)
607 mt := t.MapType()
608 mt.Key = k
609 mt.Elem = v
610 if k.HasShape() || v.HasShape() {
611 t.SetHasShape(true)
612 }
613 return t
614 }
615
616
617
618
619 var NewPtrCacheEnabled = true
620
621
622 func NewPtr(elem *Type) *Type {
623 if elem == nil {
624 base.Fatalf("NewPtr: pointer to elem Type is nil")
625 }
626
627 if t := elem.cache.ptr; t != nil {
628 if t.Elem() != elem {
629 base.Fatalf("NewPtr: elem mismatch")
630 }
631 if elem.HasShape() != t.HasShape() {
632 base.Fatalf("Incorrect HasShape flag for cached pointer type")
633 }
634 return t
635 }
636
637 t := newType(TPTR)
638 t.extra = Ptr{Elem: elem}
639 t.width = int64(PtrSize)
640 t.align = uint8(PtrSize)
641 t.intRegs = 1
642 if NewPtrCacheEnabled {
643 elem.cache.ptr = t
644 }
645 if elem.HasShape() {
646 t.SetHasShape(true)
647 }
648 t.alg = AMEM
649 if elem.Noalg() {
650 t.SetNoalg(true)
651 t.alg = ANOALG
652 }
653
654
655 t.ptrBytes = int64(PtrSize)
656 return t
657 }
658
659
660 func NewChanArgs(c *Type) *Type {
661 t := newType(TCHANARGS)
662 t.extra = ChanArgs{T: c}
663 return t
664 }
665
666
667 func NewFuncArgs(f *Type) *Type {
668 t := newType(TFUNCARGS)
669 t.extra = FuncArgs{T: f}
670 return t
671 }
672
673 func NewField(pos src.XPos, sym *Sym, typ *Type) *Field {
674 f := &Field{
675 Pos: pos,
676 Sym: sym,
677 Type: typ,
678 Offset: BADWIDTH,
679 }
680 if typ == nil {
681 base.Fatalf("typ is nil")
682 }
683 return f
684 }
685
686
687
688 func SubstAny(t *Type, types *[]*Type) *Type {
689 if t == nil {
690 return nil
691 }
692
693 switch t.kind {
694 default:
695
696
697 case TANY:
698 if len(*types) == 0 {
699 base.Fatalf("SubstArgTypes: not enough argument types")
700 }
701 t = (*types)[0]
702 *types = (*types)[1:]
703
704 case TPTR:
705 elem := SubstAny(t.Elem(), types)
706 if elem != t.Elem() {
707 t = t.copy()
708 t.extra = Ptr{Elem: elem}
709 }
710
711 case TARRAY:
712 elem := SubstAny(t.Elem(), types)
713 if elem != t.Elem() {
714 t = t.copy()
715 t.extra.(*Array).Elem = elem
716 }
717
718 case TSLICE:
719 elem := SubstAny(t.Elem(), types)
720 if elem != t.Elem() {
721 t = t.copy()
722 t.extra = Slice{Elem: elem}
723 }
724
725 case TCHAN:
726 elem := SubstAny(t.Elem(), types)
727 if elem != t.Elem() {
728 t = t.copy()
729 t.extra.(*Chan).Elem = elem
730 }
731
732 case TMAP:
733 key := SubstAny(t.Key(), types)
734 elem := SubstAny(t.Elem(), types)
735 if key != t.Key() || elem != t.Elem() {
736 t = t.copy()
737 t.extra.(*Map).Key = key
738 t.extra.(*Map).Elem = elem
739 }
740
741 case TFUNC:
742 ft := t.funcType()
743 allParams := substFields(ft.allParams, types)
744
745 t = t.copy()
746 ft = t.funcType()
747 ft.allParams = allParams
748
749 rt := ft.resultsTuple
750 rt = rt.copy()
751 ft.resultsTuple = rt
752 rt.setFields(t.Results())
753
754 case TSTRUCT:
755
756
757
758 nfs := substFields(t.Fields(), types)
759 t = t.copy()
760 t.setFields(nfs)
761 }
762
763 return t
764 }
765
766 func substFields(fields []*Field, types *[]*Type) []*Field {
767 nfs := make([]*Field, len(fields))
768 for i, f := range fields {
769 nft := SubstAny(f.Type, types)
770 nfs[i] = f.Copy()
771 nfs[i].Type = nft
772 }
773 return nfs
774 }
775
776
777 func (t *Type) copy() *Type {
778 if t == nil {
779 return nil
780 }
781 nt := *t
782
783 switch t.kind {
784 case TMAP:
785 x := *t.extra.(*Map)
786 nt.extra = &x
787 case TFORW:
788 x := *t.extra.(*Forward)
789 nt.extra = &x
790 case TFUNC:
791 x := *t.extra.(*Func)
792 nt.extra = &x
793 case TSTRUCT:
794 x := *t.extra.(*Struct)
795 nt.extra = &x
796 case TINTER:
797 x := *t.extra.(*Interface)
798 nt.extra = &x
799 case TCHAN:
800 x := *t.extra.(*Chan)
801 nt.extra = &x
802 case TARRAY:
803 x := *t.extra.(*Array)
804 nt.extra = &x
805 case TTUPLE, TSSA, TRESULTS:
806 base.Fatalf("ssa types cannot be copied")
807 }
808
809 if t.underlying == t {
810 nt.underlying = &nt
811 }
812 return &nt
813 }
814
815 func (f *Field) Copy() *Field {
816 nf := *f
817 return &nf
818 }
819
820 func (t *Type) wantEtype(et Kind) {
821 if t.kind != et {
822 base.Fatalf("want %v, but have %v", et, t)
823 }
824 }
825
826
827
828 func (t *Type) ResultsTuple() *Type { return t.funcType().resultsTuple }
829
830
831
832 func (t *Type) Recvs() []*Field { return t.funcType().recvs() }
833
834
835 func (t *Type) Params() []*Field { return t.funcType().params() }
836
837
838 func (t *Type) Results() []*Field { return t.funcType().results() }
839
840
841
842
843 func (t *Type) RecvParamsResults() []*Field { return t.funcType().allParams }
844
845
846
847 func (t *Type) RecvParams() []*Field { return t.funcType().recvParams() }
848
849
850
851 func (t *Type) ParamsResults() []*Field { return t.funcType().paramsResults() }
852
853 func (t *Type) NumRecvs() int { return len(t.Recvs()) }
854 func (t *Type) NumParams() int { return len(t.Params()) }
855 func (t *Type) NumResults() int { return len(t.Results()) }
856
857
858 func (t *Type) IsVariadic() bool {
859 n := t.NumParams()
860 return n > 0 && t.Param(n-1).IsDDD()
861 }
862
863
864 func (t *Type) Recv() *Field {
865 if s := t.Recvs(); len(s) == 1 {
866 return s[0]
867 }
868 return nil
869 }
870
871
872 func (t *Type) Param(i int) *Field { return t.Params()[i] }
873
874
875 func (t *Type) Result(i int) *Field { return t.Results()[i] }
876
877
878 func (t *Type) Key() *Type {
879 t.wantEtype(TMAP)
880 return t.extra.(*Map).Key
881 }
882
883
884
885 func (t *Type) Elem() *Type {
886 switch t.kind {
887 case TPTR:
888 return t.extra.(Ptr).Elem
889 case TARRAY:
890 return t.extra.(*Array).Elem
891 case TSLICE:
892 return t.extra.(Slice).Elem
893 case TCHAN:
894 return t.extra.(*Chan).Elem
895 case TMAP:
896 return t.extra.(*Map).Elem
897 }
898 base.Fatalf("Type.Elem %s", t.kind)
899 return nil
900 }
901
902
903 func (t *Type) ChanArgs() *Type {
904 t.wantEtype(TCHANARGS)
905 return t.extra.(ChanArgs).T
906 }
907
908
909 func (t *Type) FuncArgs() *Type {
910 t.wantEtype(TFUNCARGS)
911 return t.extra.(FuncArgs).T
912 }
913
914
915 func (t *Type) IsFuncArgStruct() bool {
916 return t.kind == TSTRUCT && t.extra.(*Struct).ParamTuple
917 }
918
919
920
921
922 func (t *Type) Methods() []*Field {
923 return t.methods.Slice()
924 }
925
926
927
928
929
930 func (t *Type) AllMethods() []*Field {
931 if t.kind == TINTER {
932
933
934 CalcSize(t)
935 }
936 return t.allMethods.Slice()
937 }
938
939
940
941 func (t *Type) SetMethods(fs []*Field) {
942 t.methods.Set(fs)
943 }
944
945
946
947 func (t *Type) SetAllMethods(fs []*Field) {
948 t.allMethods.Set(fs)
949 }
950
951
952 func (t *Type) fields() *fields {
953 t.wantEtype(TSTRUCT)
954 return &t.extra.(*Struct).fields
955 }
956
957
958 func (t *Type) Field(i int) *Field { return t.Fields()[i] }
959
960
961
962 func (t *Type) Fields() []*Field { return t.fields().Slice() }
963
964
965 func (t *Type) setFields(fields []*Field) {
966
967
968
969
970
971
972 if t.widthCalculated() {
973 base.Fatalf("SetFields of %v: width previously calculated", t)
974 }
975 t.wantEtype(TSTRUCT)
976 t.fields().Set(fields)
977 }
978
979
980 func (t *Type) SetInterface(methods []*Field) {
981 t.wantEtype(TINTER)
982 t.methods.Set(methods)
983 }
984
985
986
987 func (t *Type) ArgWidth() int64 {
988 t.wantEtype(TFUNC)
989 return t.extra.(*Func).Argwid
990 }
991
992
993 func (t *Type) Size() int64 {
994 if t.kind == TSSA {
995 return t.width
996 }
997 CalcSize(t)
998 return t.width
999 }
1000
1001
1002 func (t *Type) Alignment() int64 {
1003 CalcSize(t)
1004 return int64(t.align)
1005 }
1006
1007 func (t *Type) SimpleString() string {
1008 return t.kind.String()
1009 }
1010
1011
1012
1013
1014
1015
1016 type Cmp int8
1017
1018 const (
1019 CMPlt = Cmp(-1)
1020 CMPeq = Cmp(0)
1021 CMPgt = Cmp(1)
1022 )
1023
1024
1025
1026
1027
1028
1029
1030 func (t *Type) Compare(x *Type) Cmp {
1031 if x == t {
1032 return CMPeq
1033 }
1034 return t.cmp(x)
1035 }
1036
1037 func cmpForNe(x bool) Cmp {
1038 if x {
1039 return CMPlt
1040 }
1041 return CMPgt
1042 }
1043
1044 func (r *Sym) cmpsym(s *Sym) Cmp {
1045 if r == s {
1046 return CMPeq
1047 }
1048 if r == nil {
1049 return CMPlt
1050 }
1051 if s == nil {
1052 return CMPgt
1053 }
1054
1055 if len(r.Name) != len(s.Name) {
1056 return cmpForNe(len(r.Name) < len(s.Name))
1057 }
1058 if r.Pkg != s.Pkg {
1059 if len(r.Pkg.Prefix) != len(s.Pkg.Prefix) {
1060 return cmpForNe(len(r.Pkg.Prefix) < len(s.Pkg.Prefix))
1061 }
1062 if r.Pkg.Prefix != s.Pkg.Prefix {
1063 return cmpForNe(r.Pkg.Prefix < s.Pkg.Prefix)
1064 }
1065 }
1066 if r.Name != s.Name {
1067 return cmpForNe(r.Name < s.Name)
1068 }
1069 return CMPeq
1070 }
1071
1072
1073
1074
1075
1076
1077 func (t *Type) cmp(x *Type) Cmp {
1078
1079
1080
1081
1082
1083 if t == x {
1084 return CMPeq
1085 }
1086 if t == nil {
1087 return CMPlt
1088 }
1089 if x == nil {
1090 return CMPgt
1091 }
1092
1093 if t.kind != x.kind {
1094 return cmpForNe(t.kind < x.kind)
1095 }
1096
1097 if t.obj != nil || x.obj != nil {
1098
1099
1100 switch t.kind {
1101 case TUINT8:
1102 if (t == Types[TUINT8] || t == ByteType) && (x == Types[TUINT8] || x == ByteType) {
1103 return CMPeq
1104 }
1105
1106 case TINT32:
1107 if (t == Types[RuneType.kind] || t == RuneType) && (x == Types[RuneType.kind] || x == RuneType) {
1108 return CMPeq
1109 }
1110
1111 case TINTER:
1112
1113 if t == AnyType && x.IsEmptyInterface() || x == AnyType && t.IsEmptyInterface() {
1114 return CMPeq
1115 }
1116 }
1117 }
1118
1119 if c := t.Sym().cmpsym(x.Sym()); c != CMPeq {
1120 return c
1121 }
1122
1123 if x.obj != nil {
1124 return CMPeq
1125 }
1126
1127
1128 switch t.kind {
1129 case TBOOL, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TUNSAFEPTR, TUINTPTR,
1130 TINT8, TINT16, TINT32, TINT64, TINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINT:
1131 return CMPeq
1132
1133 case TSSA:
1134 tname := t.extra.(string)
1135 xname := x.extra.(string)
1136
1137 if len(tname) == len(xname) {
1138 if tname == xname {
1139 return CMPeq
1140 }
1141 if tname < xname {
1142 return CMPlt
1143 }
1144 return CMPgt
1145 }
1146 if len(tname) > len(xname) {
1147 return CMPgt
1148 }
1149 return CMPlt
1150
1151 case TTUPLE:
1152 xtup := x.extra.(*Tuple)
1153 ttup := t.extra.(*Tuple)
1154 if c := ttup.first.Compare(xtup.first); c != CMPeq {
1155 return c
1156 }
1157 return ttup.second.Compare(xtup.second)
1158
1159 case TRESULTS:
1160 xResults := x.extra.(*Results)
1161 tResults := t.extra.(*Results)
1162 xl, tl := len(xResults.Types), len(tResults.Types)
1163 if tl != xl {
1164 if tl < xl {
1165 return CMPlt
1166 }
1167 return CMPgt
1168 }
1169 for i := 0; i < tl; i++ {
1170 if c := tResults.Types[i].Compare(xResults.Types[i]); c != CMPeq {
1171 return c
1172 }
1173 }
1174 return CMPeq
1175
1176 case TMAP:
1177 if c := t.Key().cmp(x.Key()); c != CMPeq {
1178 return c
1179 }
1180 return t.Elem().cmp(x.Elem())
1181
1182 case TPTR, TSLICE:
1183
1184
1185
1186 case TSTRUCT:
1187
1188 if t.StructType().Map == nil {
1189 if x.StructType().Map != nil {
1190 return CMPlt
1191 }
1192
1193 } else if x.StructType().Map == nil {
1194 return CMPgt
1195 }
1196
1197
1198
1199
1200
1201
1202 tfs := t.Fields()
1203 xfs := x.Fields()
1204 for i := 0; i < len(tfs) && i < len(xfs); i++ {
1205 t1, x1 := tfs[i], xfs[i]
1206 if t1.Embedded != x1.Embedded {
1207 return cmpForNe(t1.Embedded < x1.Embedded)
1208 }
1209 if t1.Note != x1.Note {
1210 return cmpForNe(t1.Note < x1.Note)
1211 }
1212 if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
1213 return c
1214 }
1215 if c := t1.Type.cmp(x1.Type); c != CMPeq {
1216 return c
1217 }
1218 }
1219 if len(tfs) != len(xfs) {
1220 return cmpForNe(len(tfs) < len(xfs))
1221 }
1222 return CMPeq
1223
1224 case TINTER:
1225 tfs := t.AllMethods()
1226 xfs := x.AllMethods()
1227 for i := 0; i < len(tfs) && i < len(xfs); i++ {
1228 t1, x1 := tfs[i], xfs[i]
1229 if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
1230 return c
1231 }
1232 if c := t1.Type.cmp(x1.Type); c != CMPeq {
1233 return c
1234 }
1235 }
1236 if len(tfs) != len(xfs) {
1237 return cmpForNe(len(tfs) < len(xfs))
1238 }
1239 return CMPeq
1240
1241 case TFUNC:
1242 if tn, xn := t.NumRecvs(), x.NumRecvs(); tn != xn {
1243 return cmpForNe(tn < xn)
1244 }
1245 if tn, xn := t.NumParams(), x.NumParams(); tn != xn {
1246 return cmpForNe(tn < xn)
1247 }
1248 if tn, xn := t.NumResults(), x.NumResults(); tn != xn {
1249 return cmpForNe(tn < xn)
1250 }
1251 if tv, xv := t.IsVariadic(), x.IsVariadic(); tv != xv {
1252 return cmpForNe(!tv)
1253 }
1254
1255 tfs := t.RecvParamsResults()
1256 xfs := x.RecvParamsResults()
1257 for i, tf := range tfs {
1258 if c := tf.Type.cmp(xfs[i].Type); c != CMPeq {
1259 return c
1260 }
1261 }
1262 return CMPeq
1263
1264 case TARRAY:
1265 if t.NumElem() != x.NumElem() {
1266 return cmpForNe(t.NumElem() < x.NumElem())
1267 }
1268
1269 case TCHAN:
1270 if t.ChanDir() != x.ChanDir() {
1271 return cmpForNe(t.ChanDir() < x.ChanDir())
1272 }
1273
1274 default:
1275 e := fmt.Sprintf("Do not know how to compare %v with %v", t, x)
1276 panic(e)
1277 }
1278
1279
1280 return t.Elem().cmp(x.Elem())
1281 }
1282
1283
1284 func (t *Type) IsKind(et Kind) bool {
1285 return t != nil && t.kind == et
1286 }
1287
1288 func (t *Type) IsBoolean() bool {
1289 return t.kind == TBOOL
1290 }
1291
1292 var unsignedEType = [...]Kind{
1293 TINT8: TUINT8,
1294 TUINT8: TUINT8,
1295 TINT16: TUINT16,
1296 TUINT16: TUINT16,
1297 TINT32: TUINT32,
1298 TUINT32: TUINT32,
1299 TINT64: TUINT64,
1300 TUINT64: TUINT64,
1301 TINT: TUINT,
1302 TUINT: TUINT,
1303 TUINTPTR: TUINTPTR,
1304 }
1305
1306
1307 func (t *Type) ToUnsigned() *Type {
1308 if !t.IsInteger() {
1309 base.Fatalf("unsignedType(%v)", t)
1310 }
1311 return Types[unsignedEType[t.kind]]
1312 }
1313
1314 func (t *Type) IsInteger() bool {
1315 switch t.kind {
1316 case TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64, TUINT64, TINT, TUINT, TUINTPTR:
1317 return true
1318 }
1319 return t == UntypedInt || t == UntypedRune
1320 }
1321
1322 func (t *Type) IsSigned() bool {
1323 switch t.kind {
1324 case TINT8, TINT16, TINT32, TINT64, TINT:
1325 return true
1326 }
1327 return false
1328 }
1329
1330 func (t *Type) IsUnsigned() bool {
1331 switch t.kind {
1332 case TUINT8, TUINT16, TUINT32, TUINT64, TUINT, TUINTPTR:
1333 return true
1334 }
1335 return false
1336 }
1337
1338 func (t *Type) IsFloat() bool {
1339 return t.kind == TFLOAT32 || t.kind == TFLOAT64 || t == UntypedFloat
1340 }
1341
1342 func (t *Type) IsComplex() bool {
1343 return t.kind == TCOMPLEX64 || t.kind == TCOMPLEX128 || t == UntypedComplex
1344 }
1345
1346
1347
1348 func (t *Type) IsPtr() bool {
1349 return t.kind == TPTR
1350 }
1351
1352
1353 func (t *Type) IsPtrElem() bool {
1354 return t.cache.ptr != nil
1355 }
1356
1357
1358 func (t *Type) IsUnsafePtr() bool {
1359 return t.kind == TUNSAFEPTR
1360 }
1361
1362
1363 func (t *Type) IsUintptr() bool {
1364 return t.kind == TUINTPTR
1365 }
1366
1367
1368
1369
1370
1371
1372 func (t *Type) IsPtrShaped() bool {
1373 return t.kind == TPTR || t.kind == TUNSAFEPTR ||
1374 t.kind == TMAP || t.kind == TCHAN || t.kind == TFUNC
1375 }
1376
1377
1378 func (t *Type) HasNil() bool {
1379 switch t.kind {
1380 case TCHAN, TFUNC, TINTER, TMAP, TNIL, TPTR, TSLICE, TUNSAFEPTR:
1381 return true
1382 }
1383 return false
1384 }
1385
1386 func (t *Type) IsString() bool {
1387 return t.kind == TSTRING
1388 }
1389
1390 func (t *Type) IsMap() bool {
1391 return t.kind == TMAP
1392 }
1393
1394 func (t *Type) IsChan() bool {
1395 return t.kind == TCHAN
1396 }
1397
1398 func (t *Type) IsSlice() bool {
1399 return t.kind == TSLICE
1400 }
1401
1402 func (t *Type) IsArray() bool {
1403 return t.kind == TARRAY
1404 }
1405
1406 func (t *Type) IsStruct() bool {
1407 return t.kind == TSTRUCT
1408 }
1409
1410 func (t *Type) IsInterface() bool {
1411 return t.kind == TINTER
1412 }
1413
1414
1415 func (t *Type) IsEmptyInterface() bool {
1416 return t.IsInterface() && len(t.AllMethods()) == 0
1417 }
1418
1419
1420
1421
1422
1423 func (t *Type) IsScalar() bool {
1424 switch t.kind {
1425 case TBOOL, TINT8, TUINT8, TINT16, TUINT16, TINT32,
1426 TUINT32, TINT64, TUINT64, TINT, TUINT,
1427 TUINTPTR, TCOMPLEX64, TCOMPLEX128, TFLOAT32, TFLOAT64:
1428 return true
1429 }
1430 return false
1431 }
1432
1433 func (t *Type) PtrTo() *Type {
1434 return NewPtr(t)
1435 }
1436
1437 func (t *Type) NumFields() int {
1438 if t.kind == TRESULTS {
1439 return len(t.extra.(*Results).Types)
1440 }
1441 return len(t.Fields())
1442 }
1443 func (t *Type) FieldType(i int) *Type {
1444 if t.kind == TTUPLE {
1445 switch i {
1446 case 0:
1447 return t.extra.(*Tuple).first
1448 case 1:
1449 return t.extra.(*Tuple).second
1450 default:
1451 panic("bad tuple index")
1452 }
1453 }
1454 if t.kind == TRESULTS {
1455 return t.extra.(*Results).Types[i]
1456 }
1457 return t.Field(i).Type
1458 }
1459 func (t *Type) FieldOff(i int) int64 {
1460 return t.Field(i).Offset
1461 }
1462 func (t *Type) FieldName(i int) string {
1463 return t.Field(i).Sym.Name
1464 }
1465
1466
1467
1468 func (t *Type) OffsetOf(name string) int64 {
1469 if t.kind != TSTRUCT {
1470 base.Fatalf("can't call OffsetOf on non-struct %v", t)
1471 }
1472 for _, f := range t.Fields() {
1473 if f.Sym.Name == name {
1474 return f.Offset
1475 }
1476 }
1477 base.Fatalf("couldn't find field %s in %v", name, t)
1478 return -1
1479 }
1480
1481 func (t *Type) NumElem() int64 {
1482 t.wantEtype(TARRAY)
1483 return t.extra.(*Array).Bound
1484 }
1485
1486 type componentsIncludeBlankFields bool
1487
1488 const (
1489 IgnoreBlankFields componentsIncludeBlankFields = false
1490 CountBlankFields componentsIncludeBlankFields = true
1491 )
1492
1493
1494
1495
1496
1497
1498
1499 func (t *Type) NumComponents(countBlank componentsIncludeBlankFields) int64 {
1500 switch t.kind {
1501 case TSTRUCT:
1502 if t.IsFuncArgStruct() {
1503 base.Fatalf("NumComponents func arg struct")
1504 }
1505 var n int64
1506 for _, f := range t.Fields() {
1507 if countBlank == IgnoreBlankFields && f.Sym.IsBlank() {
1508 continue
1509 }
1510 n += f.Type.NumComponents(countBlank)
1511 }
1512 return n
1513 case TARRAY:
1514 return t.NumElem() * t.Elem().NumComponents(countBlank)
1515 }
1516 return 1
1517 }
1518
1519
1520
1521
1522
1523 func (t *Type) SoleComponent() *Type {
1524 switch t.kind {
1525 case TSTRUCT:
1526 if t.IsFuncArgStruct() {
1527 base.Fatalf("SoleComponent func arg struct")
1528 }
1529 if t.NumFields() != 1 {
1530 return nil
1531 }
1532 return t.Field(0).Type.SoleComponent()
1533 case TARRAY:
1534 if t.NumElem() != 1 {
1535 return nil
1536 }
1537 return t.Elem().SoleComponent()
1538 }
1539 return t
1540 }
1541
1542
1543
1544 func (t *Type) ChanDir() ChanDir {
1545 t.wantEtype(TCHAN)
1546 return t.extra.(*Chan).Dir
1547 }
1548
1549 func (t *Type) IsMemory() bool {
1550 if t == TypeMem || t.kind == TTUPLE && t.extra.(*Tuple).second == TypeMem {
1551 return true
1552 }
1553 if t.kind == TRESULTS {
1554 if types := t.extra.(*Results).Types; len(types) > 0 && types[len(types)-1] == TypeMem {
1555 return true
1556 }
1557 }
1558 return false
1559 }
1560 func (t *Type) IsFlags() bool { return t == TypeFlags }
1561 func (t *Type) IsVoid() bool { return t == TypeVoid }
1562 func (t *Type) IsTuple() bool { return t.kind == TTUPLE }
1563 func (t *Type) IsResults() bool { return t.kind == TRESULTS }
1564
1565
1566 func (t *Type) IsUntyped() bool {
1567 if t == nil {
1568 return false
1569 }
1570 if t == UntypedString || t == UntypedBool {
1571 return true
1572 }
1573 switch t.kind {
1574 case TNIL, TIDEAL:
1575 return true
1576 }
1577 return false
1578 }
1579
1580
1581
1582 func (t *Type) HasPointers() bool {
1583 return PtrDataSize(t) > 0
1584 }
1585
1586 var recvType *Type
1587
1588
1589 func FakeRecvType() *Type {
1590 if recvType == nil {
1591 recvType = NewPtr(newType(TSTRUCT))
1592 }
1593 return recvType
1594 }
1595
1596 func FakeRecv() *Field {
1597 return NewField(base.AutogeneratedPos, nil, FakeRecvType())
1598 }
1599
1600 var (
1601
1602 TypeInvalid = newSSA("invalid")
1603 TypeMem = newSSA("mem")
1604 TypeFlags = newSSA("flags")
1605 TypeVoid = newSSA("void")
1606 TypeInt128 = newSSA("int128")
1607 TypeVec128 = newSIMD("vec128")
1608 TypeVec256 = newSIMD("vec256")
1609 TypeVec512 = newSIMD("vec512")
1610 TypeMask = newSIMD("mask")
1611 TypeResultMem = newResults([]*Type{TypeMem})
1612 )
1613
1614 func init() {
1615 TypeInt128.width = 16
1616 TypeInt128.align = 8
1617
1618 TypeVec128.width = 16
1619 TypeVec128.align = 8
1620 TypeVec256.width = 32
1621 TypeVec256.align = 8
1622 TypeVec512.width = 64
1623 TypeVec512.align = 8
1624
1625 TypeMask.width = 8
1626 TypeMask.align = 8
1627 }
1628
1629
1630
1631
1632
1633
1634 func NewNamed(obj Object) *Type {
1635 t := newType(TFORW)
1636 t.obj = obj
1637 sym := obj.Sym()
1638 if sym.Pkg == ShapePkg {
1639 t.SetIsShape(true)
1640 t.SetHasShape(true)
1641 }
1642 if sym.Pkg.Path == "internal/runtime/sys" && sym.Name == "nih" {
1643
1644
1645
1646
1647 t.SetNotInHeap(true)
1648 }
1649 return t
1650 }
1651
1652
1653 func (t *Type) Obj() Object {
1654 return t.obj
1655 }
1656
1657
1658
1659
1660 func (t *Type) SetUnderlying(underlying *Type) {
1661 if underlying.kind == TFORW {
1662
1663 underlying.forwardType().Copyto = append(underlying.forwardType().Copyto, t)
1664 return
1665 }
1666
1667 ft := t.forwardType()
1668
1669
1670 t.kind = underlying.kind
1671 t.extra = underlying.extra
1672 t.width = underlying.width
1673 t.align = underlying.align
1674 t.alg = underlying.alg
1675 t.ptrBytes = underlying.ptrBytes
1676 t.intRegs = underlying.intRegs
1677 t.floatRegs = underlying.floatRegs
1678 t.underlying = underlying.underlying
1679
1680 if underlying.NotInHeap() {
1681 t.SetNotInHeap(true)
1682 }
1683 if underlying.HasShape() {
1684 t.SetHasShape(true)
1685 }
1686
1687
1688
1689
1690 if t.IsInterface() {
1691 t.methods = underlying.methods
1692 t.allMethods = underlying.allMethods
1693 }
1694
1695
1696 for _, w := range ft.Copyto {
1697 w.SetUnderlying(t)
1698 }
1699
1700
1701 if ft.Embedlineno.IsKnown() {
1702 if t.IsPtr() || t.IsUnsafePtr() {
1703 base.ErrorfAt(ft.Embedlineno, errors.InvalidPtrEmbed, "embedded type cannot be a pointer")
1704 }
1705 }
1706 }
1707
1708 func fieldsHasShape(fields []*Field) bool {
1709 for _, f := range fields {
1710 if f.Type != nil && f.Type.HasShape() {
1711 return true
1712 }
1713 }
1714 return false
1715 }
1716
1717
1718
1719 func NewInterface(methods []*Field) *Type {
1720 t := newType(TINTER)
1721 t.SetInterface(methods)
1722 for _, f := range methods {
1723
1724 if f.Type != nil && f.Type.HasShape() {
1725 t.SetHasShape(true)
1726 break
1727 }
1728 }
1729 return t
1730 }
1731
1732
1733
1734 func NewSignature(recv *Field, params, results []*Field) *Type {
1735 startParams := 0
1736 if recv != nil {
1737 startParams = 1
1738 }
1739 startResults := startParams + len(params)
1740
1741 allParams := make([]*Field, startResults+len(results))
1742 if recv != nil {
1743 allParams[0] = recv
1744 }
1745 copy(allParams[startParams:], params)
1746 copy(allParams[startResults:], results)
1747
1748 t := newType(TFUNC)
1749 ft := t.funcType()
1750
1751 funargs := func(fields []*Field) *Type {
1752 s := NewStruct(fields)
1753 s.StructType().ParamTuple = true
1754 return s
1755 }
1756
1757 ft.allParams = allParams
1758 ft.startParams = startParams
1759 ft.startResults = startResults
1760
1761 ft.resultsTuple = funargs(allParams[startResults:])
1762
1763 if fieldsHasShape(allParams) {
1764 t.SetHasShape(true)
1765 }
1766
1767 return t
1768 }
1769
1770
1771 func NewStruct(fields []*Field) *Type {
1772 t := newType(TSTRUCT)
1773 t.setFields(fields)
1774 if fieldsHasShape(fields) {
1775 t.SetHasShape(true)
1776 }
1777 for _, f := range fields {
1778 if f.Type.NotInHeap() {
1779 t.SetNotInHeap(true)
1780 break
1781 }
1782 }
1783
1784 return t
1785 }
1786
1787 var (
1788 IsInt [NTYPE]bool
1789 IsFloat [NTYPE]bool
1790 IsComplex [NTYPE]bool
1791 IsSimple [NTYPE]bool
1792 )
1793
1794 var IsOrdered [NTYPE]bool
1795
1796
1797
1798 func IsReflexive(t *Type) bool {
1799 switch t.Kind() {
1800 case TBOOL,
1801 TINT,
1802 TUINT,
1803 TINT8,
1804 TUINT8,
1805 TINT16,
1806 TUINT16,
1807 TINT32,
1808 TUINT32,
1809 TINT64,
1810 TUINT64,
1811 TUINTPTR,
1812 TPTR,
1813 TUNSAFEPTR,
1814 TSTRING,
1815 TCHAN:
1816 return true
1817
1818 case TFLOAT32,
1819 TFLOAT64,
1820 TCOMPLEX64,
1821 TCOMPLEX128,
1822 TINTER:
1823 return false
1824
1825 case TARRAY:
1826 return IsReflexive(t.Elem())
1827
1828 case TSTRUCT:
1829 for _, t1 := range t.Fields() {
1830 if !IsReflexive(t1.Type) {
1831 return false
1832 }
1833 }
1834 return true
1835
1836 default:
1837 base.Fatalf("bad type for map key: %v", t)
1838 return false
1839 }
1840 }
1841
1842
1843
1844 func IsDirectIface(t *Type) bool {
1845 return t.Size() == int64(PtrSize) && PtrDataSize(t) == int64(PtrSize)
1846 }
1847
1848
1849
1850
1851 func IsInterfaceMethod(f *Type) bool {
1852 return f.Recv().Type == FakeRecvType()
1853 }
1854
1855
1856
1857
1858
1859 func IsMethodApplicable(t *Type, m *Field) bool {
1860 return t.IsPtr() || !m.Type.Recv().Type.IsPtr() || IsInterfaceMethod(m.Type) || m.Embedded == 2
1861 }
1862
1863
1864
1865 func RuntimeSymName(s *Sym) string {
1866 if s.Pkg.Path == "runtime" {
1867 return s.Name
1868 }
1869 return ""
1870 }
1871
1872
1873
1874 func ReflectSymName(s *Sym) string {
1875 if s.Pkg.Path == "reflect" {
1876 return s.Name
1877 }
1878 return ""
1879 }
1880
1881
1882
1883 func IsNoInstrumentPkg(p *Pkg) bool {
1884 return objabi.LookupPkgSpecial(p.Path).NoInstrument
1885 }
1886
1887
1888
1889 func IsNoRacePkg(p *Pkg) bool {
1890 return objabi.LookupPkgSpecial(p.Path).NoRaceFunc
1891 }
1892
1893
1894 func IsRuntimePkg(p *Pkg) bool {
1895 return objabi.LookupPkgSpecial(p.Path).Runtime
1896 }
1897
1898
1899
1900
1901 func ReceiverBaseType(t *Type) *Type {
1902 if t == nil {
1903 return nil
1904 }
1905
1906
1907 if t.IsPtr() {
1908 if t.Sym() != nil {
1909 return nil
1910 }
1911 t = t.Elem()
1912 if t == nil {
1913 return nil
1914 }
1915 }
1916
1917
1918 if t.Sym() == nil && !t.IsStruct() {
1919 return nil
1920 }
1921
1922
1923 if IsSimple[t.Kind()] {
1924 return t
1925 }
1926 switch t.Kind() {
1927 case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT:
1928 return t
1929 }
1930 return nil
1931 }
1932
1933 func FloatForComplex(t *Type) *Type {
1934 switch t.Kind() {
1935 case TCOMPLEX64:
1936 return Types[TFLOAT32]
1937 case TCOMPLEX128:
1938 return Types[TFLOAT64]
1939 }
1940 base.Fatalf("unexpected type: %v", t)
1941 return nil
1942 }
1943
1944 func ComplexForFloat(t *Type) *Type {
1945 switch t.Kind() {
1946 case TFLOAT32:
1947 return Types[TCOMPLEX64]
1948 case TFLOAT64:
1949 return Types[TCOMPLEX128]
1950 }
1951 base.Fatalf("unexpected type: %v", t)
1952 return nil
1953 }
1954
1955 func TypeSym(t *Type) *Sym {
1956 return TypeSymLookup(TypeSymName(t))
1957 }
1958
1959 func TypeSymLookup(name string) *Sym {
1960 typepkgmu.Lock()
1961 s := typepkg.Lookup(name)
1962 typepkgmu.Unlock()
1963 return s
1964 }
1965
1966 func TypeSymName(t *Type) string {
1967 name := t.LinkString()
1968
1969 if TypeHasNoAlg(t) {
1970 name = "noalg." + name
1971 }
1972 return name
1973 }
1974
1975
1976
1977 var (
1978 typepkgmu sync.Mutex
1979 typepkg = NewPkg("type", "type")
1980 )
1981
1982 var SimType [NTYPE]Kind
1983
1984
1985 var ShapePkg = NewPkg("go.shape", "go.shape")
1986
1987 func (t *Type) IsSIMD() bool {
1988 return t.isSIMD
1989 }
1990
View as plain text