1
2
3
4
5 package typecheck
6
7 import (
8 "go/constant"
9
10 "cmd/compile/internal/base"
11 "cmd/compile/internal/ir"
12 "cmd/compile/internal/types"
13 "cmd/internal/src"
14 )
15
16 var (
17 okfor [ir.OEND][]bool
18 iscmp [ir.OEND]bool
19 )
20
21 var (
22 okforeq [types.NTYPE]bool
23 okforadd [types.NTYPE]bool
24 okforand [types.NTYPE]bool
25 okfornone [types.NTYPE]bool
26 okforbool [types.NTYPE]bool
27 okforcap [types.NTYPE]bool
28 okforlen [types.NTYPE]bool
29 okforarith [types.NTYPE]bool
30 )
31
32 var basicTypes = [...]struct {
33 name string
34 etype types.Kind
35 }{
36 {"int8", types.TINT8},
37 {"int16", types.TINT16},
38 {"int32", types.TINT32},
39 {"int64", types.TINT64},
40 {"uint8", types.TUINT8},
41 {"uint16", types.TUINT16},
42 {"uint32", types.TUINT32},
43 {"uint64", types.TUINT64},
44 {"float32", types.TFLOAT32},
45 {"float64", types.TFLOAT64},
46 {"complex64", types.TCOMPLEX64},
47 {"complex128", types.TCOMPLEX128},
48 {"bool", types.TBOOL},
49 {"string", types.TSTRING},
50 }
51
52 var typedefs = [...]struct {
53 name string
54 etype types.Kind
55 sameas32 types.Kind
56 sameas64 types.Kind
57 }{
58 {"int", types.TINT, types.TINT32, types.TINT64},
59 {"uint", types.TUINT, types.TUINT32, types.TUINT64},
60 {"uintptr", types.TUINTPTR, types.TUINT32, types.TUINT64},
61 }
62
63 var builtinFuncs = [...]struct {
64 name string
65 op ir.Op
66 }{
67 {"append", ir.OAPPEND},
68 {"cap", ir.OCAP},
69 {"close", ir.OCLOSE},
70 {"complex", ir.OCOMPLEX},
71 {"copy", ir.OCOPY},
72 {"delete", ir.ODELETE},
73 {"imag", ir.OIMAG},
74 {"len", ir.OLEN},
75 {"make", ir.OMAKE},
76 {"new", ir.ONEW},
77 {"panic", ir.OPANIC},
78 {"print", ir.OPRINT},
79 {"println", ir.OPRINTN},
80 {"real", ir.OREAL},
81 {"recover", ir.ORECOVER},
82 }
83
84 var unsafeFuncs = [...]struct {
85 name string
86 op ir.Op
87 }{
88 {"Add", ir.OUNSAFEADD},
89 {"Alignof", ir.OALIGNOF},
90 {"Offsetof", ir.OOFFSETOF},
91 {"Sizeof", ir.OSIZEOF},
92 {"Slice", ir.OUNSAFESLICE},
93 }
94
95
96 func InitUniverse() {
97 if types.PtrSize == 0 {
98 base.Fatalf("typeinit before betypeinit")
99 }
100
101 types.SlicePtrOffset = 0
102 types.SliceLenOffset = types.Rnd(types.SlicePtrOffset+int64(types.PtrSize), int64(types.PtrSize))
103 types.SliceCapOffset = types.Rnd(types.SliceLenOffset+int64(types.PtrSize), int64(types.PtrSize))
104 types.SliceSize = types.Rnd(types.SliceCapOffset+int64(types.PtrSize), int64(types.PtrSize))
105
106
107 types.StringSize = types.Rnd(types.SliceLenOffset+int64(types.PtrSize), int64(types.PtrSize))
108
109 for et := types.Kind(0); et < types.NTYPE; et++ {
110 types.SimType[et] = et
111 }
112
113 types.Types[types.TANY] = types.New(types.TANY)
114 types.Types[types.TINTER] = types.NewInterface(types.LocalPkg, nil)
115
116 defBasic := func(kind types.Kind, pkg *types.Pkg, name string) *types.Type {
117 sym := pkg.Lookup(name)
118 n := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, sym)
119 t := types.NewBasic(kind, n)
120 n.SetType(t)
121 sym.Def = n
122 if kind != types.TANY {
123 types.CalcSize(t)
124 }
125 return t
126 }
127
128 for _, s := range &basicTypes {
129 types.Types[s.etype] = defBasic(s.etype, types.BuiltinPkg, s.name)
130 }
131
132 for _, s := range &typedefs {
133 sameas := s.sameas32
134 if types.PtrSize == 8 {
135 sameas = s.sameas64
136 }
137 types.SimType[s.etype] = sameas
138
139 types.Types[s.etype] = defBasic(s.etype, types.BuiltinPkg, s.name)
140 }
141
142
143
144
145
146
147
148
149 types.ByteType = defBasic(types.TUINT8, types.BuiltinPkg, "byte")
150 types.RuneType = defBasic(types.TINT32, types.BuiltinPkg, "rune")
151
152
153 s := types.BuiltinPkg.Lookup("error")
154 n := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, s)
155 types.ErrorType = types.NewNamed(n)
156 types.ErrorType.SetUnderlying(makeErrorInterface())
157 n.SetType(types.ErrorType)
158 s.Def = n
159 types.CalcSize(types.ErrorType)
160
161 types.Types[types.TUNSAFEPTR] = defBasic(types.TUNSAFEPTR, ir.Pkgs.Unsafe, "Pointer")
162
163
164 types.SimType[types.TMAP] = types.TPTR
165 types.SimType[types.TCHAN] = types.TPTR
166 types.SimType[types.TFUNC] = types.TPTR
167 types.SimType[types.TUNSAFEPTR] = types.TPTR
168
169 for _, s := range &builtinFuncs {
170 s2 := types.BuiltinPkg.Lookup(s.name)
171 def := NewName(s2)
172 def.BuiltinOp = s.op
173 s2.Def = def
174 }
175
176 for _, s := range &unsafeFuncs {
177 s2 := ir.Pkgs.Unsafe.Lookup(s.name)
178 def := NewName(s2)
179 def.BuiltinOp = s.op
180 s2.Def = def
181 }
182
183 s = types.BuiltinPkg.Lookup("true")
184 s.Def = ir.NewConstAt(src.NoXPos, s, types.UntypedBool, constant.MakeBool(true))
185
186 s = types.BuiltinPkg.Lookup("false")
187 s.Def = ir.NewConstAt(src.NoXPos, s, types.UntypedBool, constant.MakeBool(false))
188
189 s = Lookup("_")
190 types.BlankSym = s
191 s.Block = -100
192 s.Def = NewName(s)
193 types.Types[types.TBLANK] = types.New(types.TBLANK)
194 ir.AsNode(s.Def).SetType(types.Types[types.TBLANK])
195 ir.BlankNode = ir.AsNode(s.Def)
196 ir.BlankNode.SetTypecheck(1)
197
198 s = types.BuiltinPkg.Lookup("_")
199 s.Block = -100
200 s.Def = NewName(s)
201 types.Types[types.TBLANK] = types.New(types.TBLANK)
202 ir.AsNode(s.Def).SetType(types.Types[types.TBLANK])
203
204 types.Types[types.TNIL] = types.New(types.TNIL)
205 s = types.BuiltinPkg.Lookup("nil")
206 nnil := NodNil()
207 nnil.(*ir.NilExpr).SetSym(s)
208 s.Def = nnil
209
210 s = types.BuiltinPkg.Lookup("iota")
211 s.Def = ir.NewIota(base.Pos, s)
212
213 for et := types.TINT8; et <= types.TUINT64; et++ {
214 types.IsInt[et] = true
215 }
216 types.IsInt[types.TINT] = true
217 types.IsInt[types.TUINT] = true
218 types.IsInt[types.TUINTPTR] = true
219
220 types.IsFloat[types.TFLOAT32] = true
221 types.IsFloat[types.TFLOAT64] = true
222
223 types.IsComplex[types.TCOMPLEX64] = true
224 types.IsComplex[types.TCOMPLEX128] = true
225
226
227 for et := types.Kind(0); et < types.NTYPE; et++ {
228 if types.IsInt[et] || et == types.TIDEAL {
229 okforeq[et] = true
230 types.IsOrdered[et] = true
231 okforarith[et] = true
232 okforadd[et] = true
233 okforand[et] = true
234 ir.OKForConst[et] = true
235 types.IsSimple[et] = true
236 }
237
238 if types.IsFloat[et] {
239 okforeq[et] = true
240 types.IsOrdered[et] = true
241 okforadd[et] = true
242 okforarith[et] = true
243 ir.OKForConst[et] = true
244 types.IsSimple[et] = true
245 }
246
247 if types.IsComplex[et] {
248 okforeq[et] = true
249 okforadd[et] = true
250 okforarith[et] = true
251 ir.OKForConst[et] = true
252 types.IsSimple[et] = true
253 }
254 }
255
256 types.IsSimple[types.TBOOL] = true
257
258 okforadd[types.TSTRING] = true
259
260 okforbool[types.TBOOL] = true
261
262 okforcap[types.TARRAY] = true
263 okforcap[types.TCHAN] = true
264 okforcap[types.TSLICE] = true
265
266 ir.OKForConst[types.TBOOL] = true
267 ir.OKForConst[types.TSTRING] = true
268
269 okforlen[types.TARRAY] = true
270 okforlen[types.TCHAN] = true
271 okforlen[types.TMAP] = true
272 okforlen[types.TSLICE] = true
273 okforlen[types.TSTRING] = true
274
275 okforeq[types.TPTR] = true
276 okforeq[types.TUNSAFEPTR] = true
277 okforeq[types.TINTER] = true
278 okforeq[types.TCHAN] = true
279 okforeq[types.TSTRING] = true
280 okforeq[types.TBOOL] = true
281 okforeq[types.TMAP] = true
282 okforeq[types.TFUNC] = true
283 okforeq[types.TSLICE] = true
284 okforeq[types.TARRAY] = true
285 okforeq[types.TSTRUCT] = true
286
287 types.IsOrdered[types.TSTRING] = true
288
289 for i := range okfor {
290 okfor[i] = okfornone[:]
291 }
292
293
294 okfor[ir.OADD] = okforadd[:]
295 okfor[ir.OAND] = okforand[:]
296 okfor[ir.OANDAND] = okforbool[:]
297 okfor[ir.OANDNOT] = okforand[:]
298 okfor[ir.ODIV] = okforarith[:]
299 okfor[ir.OEQ] = okforeq[:]
300 okfor[ir.OGE] = types.IsOrdered[:]
301 okfor[ir.OGT] = types.IsOrdered[:]
302 okfor[ir.OLE] = types.IsOrdered[:]
303 okfor[ir.OLT] = types.IsOrdered[:]
304 okfor[ir.OMOD] = okforand[:]
305 okfor[ir.OMUL] = okforarith[:]
306 okfor[ir.ONE] = okforeq[:]
307 okfor[ir.OOR] = okforand[:]
308 okfor[ir.OOROR] = okforbool[:]
309 okfor[ir.OSUB] = okforarith[:]
310 okfor[ir.OXOR] = okforand[:]
311 okfor[ir.OLSH] = okforand[:]
312 okfor[ir.ORSH] = okforand[:]
313
314
315 okfor[ir.OBITNOT] = okforand[:]
316 okfor[ir.ONEG] = okforarith[:]
317 okfor[ir.ONOT] = okforbool[:]
318 okfor[ir.OPLUS] = okforarith[:]
319
320
321 okfor[ir.OCAP] = okforcap[:]
322 okfor[ir.OLEN] = okforlen[:]
323
324
325 iscmp[ir.OLT] = true
326 iscmp[ir.OGT] = true
327 iscmp[ir.OGE] = true
328 iscmp[ir.OLE] = true
329 iscmp[ir.OEQ] = true
330 iscmp[ir.ONE] = true
331 }
332
333 func makeErrorInterface() *types.Type {
334 sig := types.NewSignature(types.NoPkg, fakeRecvField(), nil, nil, []*types.Field{
335 types.NewField(src.NoXPos, nil, types.Types[types.TSTRING]),
336 })
337 method := types.NewField(src.NoXPos, Lookup("Error"), sig)
338 return types.NewInterface(types.NoPkg, []*types.Field{method})
339 }
340
341
342 func DeclareUniverse() {
343
344
345
346
347 for _, s := range types.BuiltinPkg.Syms {
348 if s.Def == nil {
349 continue
350 }
351 s1 := Lookup(s.Name)
352 if s1.Def != nil {
353 continue
354 }
355
356 s1.Def = s.Def
357 s1.Block = s.Block
358 }
359 }
360
View as plain text