1
2
3
4
5
6
7
8 package types2
9
10 import (
11 "cmd/compile/internal/syntax"
12 "go/constant"
13 )
14
15 func (check *Checker) record(x *operand) {
16
17
18 var typ Type
19 var val constant.Value
20 switch x.mode {
21 case invalid:
22 typ = Typ[Invalid]
23 case novalue:
24 typ = (*Tuple)(nil)
25 case constant_:
26 typ = x.typ
27 val = x.val
28 default:
29 typ = x.typ
30 }
31 assert(x.expr != nil && typ != nil)
32
33 if isUntyped(typ) {
34
35
36 check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
37 } else {
38 check.recordTypeAndValue(x.expr, x.mode, typ, val)
39 }
40 }
41
42 func (check *Checker) recordUntyped() {
43 if !debug && !check.recordTypes() {
44 return
45 }
46
47 for x, info := range check.untyped {
48 if debug && isTyped(info.typ) {
49 check.dump("%v: %s (type %s) is typed", atPos(x), x, info.typ)
50 panic("unreachable")
51 }
52 check.recordTypeAndValue(x, info.mode, info.typ, info.val)
53 }
54 }
55
56 func (check *Checker) recordTypeAndValue(x syntax.Expr, mode operandMode, typ Type, val constant.Value) {
57 assert(x != nil)
58 assert(typ != nil)
59 if mode == invalid {
60 return
61 }
62 if mode == constant_ {
63 assert(val != nil)
64
65
66 assert(!isValid(typ) || allBasic(typ, IsConstType))
67 }
68 if m := check.Types; m != nil {
69 m[x] = TypeAndValue{mode, typ, val}
70 }
71 check.recordTypeAndValueInSyntax(x, mode, typ, val)
72 }
73
74 func (check *Checker) recordBuiltinType(f syntax.Expr, sig *Signature) {
75
76
77
78
79 for {
80 check.recordTypeAndValue(f, builtin, sig, nil)
81 switch p := f.(type) {
82 case *syntax.Name, *syntax.SelectorExpr:
83 return
84 case *syntax.ParenExpr:
85 f = p.X
86 default:
87 panic("unreachable")
88 }
89 }
90 }
91
92
93
94 func (check *Checker) recordCommaOkTypes(x syntax.Expr, a []*operand) {
95 assert(x != nil)
96 assert(len(a) == 2)
97 if a[0].mode == invalid {
98 return
99 }
100 t0, t1 := a[0].typ, a[1].typ
101 assert(isTyped(t0) && isTyped(t1) && (allBoolean(t1) || t1 == universeError))
102 if m := check.Types; m != nil {
103 for {
104 tv := m[x]
105 assert(tv.Type != nil)
106 pos := x.Pos()
107 tv.Type = NewTuple(
108 NewVar(pos, check.pkg, "", t0),
109 NewVar(pos, check.pkg, "", t1),
110 )
111 m[x] = tv
112
113 p, _ := x.(*syntax.ParenExpr)
114 if p == nil {
115 break
116 }
117 x = p.X
118 }
119 }
120 check.recordCommaOkTypesInSyntax(x, t0, t1)
121 }
122
123
124
125
126
127
128
129 func (check *Checker) recordInstance(expr syntax.Expr, targs []Type, typ Type) {
130 ident := instantiatedIdent(expr)
131 assert(ident != nil)
132 assert(typ != nil)
133 if m := check.Instances; m != nil {
134 m[ident] = Instance{newTypeList(targs), typ}
135 }
136 }
137
138 func (check *Checker) recordDef(id *syntax.Name, obj Object) {
139 assert(id != nil)
140 if m := check.Defs; m != nil {
141 m[id] = obj
142 }
143 }
144
145 func (check *Checker) recordUse(id *syntax.Name, obj Object) {
146 assert(id != nil)
147 assert(obj != nil)
148 if m := check.Uses; m != nil {
149 m[id] = obj
150 }
151 }
152
153 func (check *Checker) recordImplicit(node syntax.Node, obj Object) {
154 assert(node != nil)
155 assert(obj != nil)
156 if m := check.Implicits; m != nil {
157 m[node] = obj
158 }
159 }
160
161 func (check *Checker) recordSelection(x *syntax.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) {
162 assert(obj != nil && (recv == nil || len(index) > 0))
163 check.recordUse(x.Sel, obj)
164 if m := check.Selections; m != nil {
165 m[x] = &Selection{kind, recv, obj, index, indirect}
166 }
167 }
168
169 func (check *Checker) recordScope(node syntax.Node, scope *Scope) {
170 assert(node != nil)
171 assert(scope != nil)
172 if m := check.Scopes; m != nil {
173 m[node] = scope
174 }
175 }
176
View as plain text