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