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