1
2
3
4
5 package types
6
7 import (
8 "cmd/compile/internal/base"
9 "internal/abi"
10 "strings"
11 "sync"
12 )
13
14
15
16 const tflagComputed uint8 = 1 << 7
17
18 var tflagMu sync.Mutex
19
20
21
22 func (t *Type) TFlag() abi.TFlag {
23 tflagMu.Lock()
24 defer tflagMu.Unlock()
25 if t.tflag&tflagComputed != 0 {
26 return abi.TFlag(t.tflag &^ tflagComputed)
27 }
28 tflag := computeTFlag(t)
29 t.tflag = uint8(tflag) | tflagComputed
30 return tflag
31 }
32
33 func computeTFlag(t *Type) abi.TFlag {
34 var tflag abi.TFlag
35 if hasUncommon(t) {
36 tflag |= abi.TFlagUncommon
37 }
38 if t.Sym() != nil && t.Sym().Name != "" {
39 tflag |= abi.TFlagNamed
40 }
41 if t.alg == AMEM {
42 tflag |= abi.TFlagRegularMemory
43 }
44 if PtrDataSize(t)/int64(PtrSize) > abi.MaxPtrmaskBytes*8 {
45 tflag |= abi.TFlagGCMaskOnDemand
46 }
47 if !strings.HasPrefix(t.NameString(), "*") {
48 tflag |= abi.TFlagExtraStar
49 }
50 if IsDirectIface(t) {
51 tflag |= abi.TFlagDirectIface
52 }
53 return tflag
54 }
55
56
57
58 func hasUncommon(t *Type) bool {
59 if t.Sym() != nil {
60 return true
61 }
62 if t.HasShape() {
63 return false
64 }
65 mt := ReceiverBaseType(t)
66 if mt == nil {
67 return false
68 }
69 if !mt.MethodsComputed() {
70 base.Fatalf("hasUncommon: methods not computed on %v", mt)
71 }
72 for _, f := range mt.AllMethods() {
73 if f.Nointerface() {
74 continue
75 }
76 if !IsMethodApplicable(t, f) {
77 continue
78 }
79 return true
80 }
81 return false
82 }
83
View as plain text