1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // TODO(gri) This file should probably become part of package types. 6 7 package gc 8 9 import "cmd/compile/internal/types" 10 11 // builtinpkg is a fake package that declares the universe block. 12 var builtinpkg *types.Pkg 13 14 var itable *types.Type // distinguished *byte 15 16 var basicTypes = [...]struct { 17 name string 18 etype types.EType 19 }{ 20 {"int8", TINT8}, 21 {"int16", TINT16}, 22 {"int32", TINT32}, 23 {"int64", TINT64}, 24 {"uint8", TUINT8}, 25 {"uint16", TUINT16}, 26 {"uint32", TUINT32}, 27 {"uint64", TUINT64}, 28 {"float32", TFLOAT32}, 29 {"float64", TFLOAT64}, 30 {"complex64", TCOMPLEX64}, 31 {"complex128", TCOMPLEX128}, 32 {"bool", TBOOL}, 33 {"string", TSTRING}, 34 } 35 36 var typedefs = [...]struct { 37 name string 38 etype types.EType 39 sameas32 types.EType 40 sameas64 types.EType 41 }{ 42 {"int", TINT, TINT32, TINT64}, 43 {"uint", TUINT, TUINT32, TUINT64}, 44 {"uintptr", TUINTPTR, TUINT32, TUINT64}, 45 } 46 47 var builtinFuncs = [...]struct { 48 name string 49 op Op 50 }{ 51 {"append", OAPPEND}, 52 {"cap", OCAP}, 53 {"close", OCLOSE}, 54 {"complex", OCOMPLEX}, 55 {"copy", OCOPY}, 56 {"delete", ODELETE}, 57 {"imag", OIMAG}, 58 {"len", OLEN}, 59 {"make", OMAKE}, 60 {"new", ONEW}, 61 {"panic", OPANIC}, 62 {"print", OPRINT}, 63 {"println", OPRINTN}, 64 {"real", OREAL}, 65 {"recover", ORECOVER}, 66 } 67 68 var unsafeFuncs = [...]struct { 69 name string 70 op Op 71 }{ 72 {"Alignof", OALIGNOF}, 73 {"Offsetof", OOFFSETOF}, 74 {"Sizeof", OSIZEOF}, 75 } 76 77 // initUniverse initializes the universe block. 78 func initUniverse() { 79 lexinit() 80 typeinit() 81 lexinit1() 82 } 83 84 // lexinit initializes known symbols and the basic types. 85 func lexinit() { 86 for _, s := range basicTypes { 87 etype := s.etype 88 if int(etype) >= len(types.Types) { 89 Fatalf("lexinit: %s bad etype", s.name) 90 } 91 s2 := builtinpkg.Lookup(s.name) 92 t := types.Types[etype] 93 if t == nil { 94 t = types.New(etype) 95 t.Sym = s2 96 if etype != TANY && etype != TSTRING { 97 dowidth(t) 98 } 99 types.Types[etype] = t 100 } 101 s2.Def = asTypesNode(typenod(t)) 102 asNode(s2.Def).Name = new(Name) 103 } 104 105 for _, s := range builtinFuncs { 106 // TODO(marvin): Fix Node.EType type union. 107 s2 := builtinpkg.Lookup(s.name) 108 s2.Def = asTypesNode(newname(s2)) 109 asNode(s2.Def).Etype = types.EType(s.op) 110 } 111 112 for _, s := range unsafeFuncs { 113 s2 := unsafepkg.Lookup(s.name) 114 s2.Def = asTypesNode(newname(s2)) 115 asNode(s2.Def).Etype = types.EType(s.op) 116 } 117 118 types.Idealstring = types.New(TSTRING) 119 types.Idealbool = types.New(TBOOL) 120 types.Types[TANY] = types.New(TANY) 121 122 s := builtinpkg.Lookup("true") 123 s.Def = asTypesNode(nodbool(true)) 124 asNode(s.Def).Sym = lookup("true") 125 asNode(s.Def).Name = new(Name) 126 asNode(s.Def).Type = types.Idealbool 127 128 s = builtinpkg.Lookup("false") 129 s.Def = asTypesNode(nodbool(false)) 130 asNode(s.Def).Sym = lookup("false") 131 asNode(s.Def).Name = new(Name) 132 asNode(s.Def).Type = types.Idealbool 133 134 s = lookup("_") 135 s.Block = -100 136 s.Def = asTypesNode(newname(s)) 137 types.Types[TBLANK] = types.New(TBLANK) 138 asNode(s.Def).Type = types.Types[TBLANK] 139 nblank = asNode(s.Def) 140 141 s = builtinpkg.Lookup("_") 142 s.Block = -100 143 s.Def = asTypesNode(newname(s)) 144 types.Types[TBLANK] = types.New(TBLANK) 145 asNode(s.Def).Type = types.Types[TBLANK] 146 147 types.Types[TNIL] = types.New(TNIL) 148 s = builtinpkg.Lookup("nil") 149 var v Val 150 v.U = new(NilVal) 151 s.Def = asTypesNode(nodlit(v)) 152 asNode(s.Def).Sym = s 153 asNode(s.Def).Name = new(Name) 154 155 s = builtinpkg.Lookup("iota") 156 s.Def = asTypesNode(nod(OIOTA, nil, nil)) 157 asNode(s.Def).Sym = s 158 asNode(s.Def).Name = new(Name) 159 } 160 161 func typeinit() { 162 if Widthptr == 0 { 163 Fatalf("typeinit before betypeinit") 164 } 165 166 for et := types.EType(0); et < NTYPE; et++ { 167 simtype[et] = et 168 } 169 170 types.Types[TPTR32] = types.New(TPTR32) 171 dowidth(types.Types[TPTR32]) 172 173 types.Types[TPTR64] = types.New(TPTR64) 174 dowidth(types.Types[TPTR64]) 175 176 t := types.New(TUNSAFEPTR) 177 types.Types[TUNSAFEPTR] = t 178 t.Sym = unsafepkg.Lookup("Pointer") 179 t.Sym.Def = asTypesNode(typenod(t)) 180 asNode(t.Sym.Def).Name = new(Name) 181 dowidth(types.Types[TUNSAFEPTR]) 182 183 types.Tptr = TPTR32 184 if Widthptr == 8 { 185 types.Tptr = TPTR64 186 } 187 188 for et := TINT8; et <= TUINT64; et++ { 189 isInt[et] = true 190 } 191 isInt[TINT] = true 192 isInt[TUINT] = true 193 isInt[TUINTPTR] = true 194 195 isFloat[TFLOAT32] = true 196 isFloat[TFLOAT64] = true 197 198 isComplex[TCOMPLEX64] = true 199 isComplex[TCOMPLEX128] = true 200 201 isforw[TFORW] = true 202 203 // initialize okfor 204 for et := types.EType(0); et < NTYPE; et++ { 205 if isInt[et] || et == TIDEAL { 206 okforeq[et] = true 207 okforcmp[et] = true 208 okforarith[et] = true 209 okforadd[et] = true 210 okforand[et] = true 211 okforconst[et] = true 212 issimple[et] = true 213 minintval[et] = new(Mpint) 214 maxintval[et] = new(Mpint) 215 } 216 217 if isFloat[et] { 218 okforeq[et] = true 219 okforcmp[et] = true 220 okforadd[et] = true 221 okforarith[et] = true 222 okforconst[et] = true 223 issimple[et] = true 224 minfltval[et] = newMpflt() 225 maxfltval[et] = newMpflt() 226 } 227 228 if isComplex[et] { 229 okforeq[et] = true 230 okforadd[et] = true 231 okforarith[et] = true 232 okforconst[et] = true 233 issimple[et] = true 234 } 235 } 236 237 issimple[TBOOL] = true 238 239 okforadd[TSTRING] = true 240 241 okforbool[TBOOL] = true 242 243 okforcap[TARRAY] = true 244 okforcap[TCHAN] = true 245 okforcap[TSLICE] = true 246 247 okforconst[TBOOL] = true 248 okforconst[TSTRING] = true 249 250 okforlen[TARRAY] = true 251 okforlen[TCHAN] = true 252 okforlen[TMAP] = true 253 okforlen[TSLICE] = true 254 okforlen[TSTRING] = true 255 256 okforeq[TPTR32] = true 257 okforeq[TPTR64] = true 258 okforeq[TUNSAFEPTR] = true 259 okforeq[TINTER] = true 260 okforeq[TCHAN] = true 261 okforeq[TSTRING] = true 262 okforeq[TBOOL] = true 263 okforeq[TMAP] = true // nil only; refined in typecheck 264 okforeq[TFUNC] = true // nil only; refined in typecheck 265 okforeq[TSLICE] = true // nil only; refined in typecheck 266 okforeq[TARRAY] = true // only if element type is comparable; refined in typecheck 267 okforeq[TSTRUCT] = true // only if all struct fields are comparable; refined in typecheck 268 269 okforcmp[TSTRING] = true 270 271 var i int 272 for i = 0; i < len(okfor); i++ { 273 okfor[i] = okfornone[:] 274 } 275 276 // binary 277 okfor[OADD] = okforadd[:] 278 okfor[OAND] = okforand[:] 279 okfor[OANDAND] = okforbool[:] 280 okfor[OANDNOT] = okforand[:] 281 okfor[ODIV] = okforarith[:] 282 okfor[OEQ] = okforeq[:] 283 okfor[OGE] = okforcmp[:] 284 okfor[OGT] = okforcmp[:] 285 okfor[OLE] = okforcmp[:] 286 okfor[OLT] = okforcmp[:] 287 okfor[OMOD] = okforand[:] 288 okfor[OMUL] = okforarith[:] 289 okfor[ONE] = okforeq[:] 290 okfor[OOR] = okforand[:] 291 okfor[OOROR] = okforbool[:] 292 okfor[OSUB] = okforarith[:] 293 okfor[OXOR] = okforand[:] 294 okfor[OLSH] = okforand[:] 295 okfor[ORSH] = okforand[:] 296 297 // unary 298 okfor[OCOM] = okforand[:] 299 okfor[OMINUS] = okforarith[:] 300 okfor[ONOT] = okforbool[:] 301 okfor[OPLUS] = okforarith[:] 302 303 // special 304 okfor[OCAP] = okforcap[:] 305 okfor[OLEN] = okforlen[:] 306 307 // comparison 308 iscmp[OLT] = true 309 iscmp[OGT] = true 310 iscmp[OGE] = true 311 iscmp[OLE] = true 312 iscmp[OEQ] = true 313 iscmp[ONE] = true 314 315 maxintval[TINT8].SetString("0x7f") 316 minintval[TINT8].SetString("-0x80") 317 maxintval[TINT16].SetString("0x7fff") 318 minintval[TINT16].SetString("-0x8000") 319 maxintval[TINT32].SetString("0x7fffffff") 320 minintval[TINT32].SetString("-0x80000000") 321 maxintval[TINT64].SetString("0x7fffffffffffffff") 322 minintval[TINT64].SetString("-0x8000000000000000") 323 324 maxintval[TUINT8].SetString("0xff") 325 maxintval[TUINT16].SetString("0xffff") 326 maxintval[TUINT32].SetString("0xffffffff") 327 maxintval[TUINT64].SetString("0xffffffffffffffff") 328 329 // f is valid float if min < f < max. (min and max are not themselves valid.) 330 maxfltval[TFLOAT32].SetString("33554431p103") // 2^24-1 p (127-23) + 1/2 ulp 331 minfltval[TFLOAT32].SetString("-33554431p103") 332 maxfltval[TFLOAT64].SetString("18014398509481983p970") // 2^53-1 p (1023-52) + 1/2 ulp 333 minfltval[TFLOAT64].SetString("-18014398509481983p970") 334 335 maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32] 336 minfltval[TCOMPLEX64] = minfltval[TFLOAT32] 337 maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64] 338 minfltval[TCOMPLEX128] = minfltval[TFLOAT64] 339 340 // for walk to use in error messages 341 types.Types[TFUNC] = functype(nil, nil, nil) 342 343 // types used in front end 344 // types.Types[TNIL] got set early in lexinit 345 types.Types[TIDEAL] = types.New(TIDEAL) 346 347 types.Types[TINTER] = types.New(TINTER) 348 349 // simple aliases 350 simtype[TMAP] = types.Tptr 351 simtype[TCHAN] = types.Tptr 352 simtype[TFUNC] = types.Tptr 353 simtype[TUNSAFEPTR] = types.Tptr 354 355 array_array = int(Rnd(0, int64(Widthptr))) 356 array_nel = int(Rnd(int64(array_array)+int64(Widthptr), int64(Widthptr))) 357 array_cap = int(Rnd(int64(array_nel)+int64(Widthptr), int64(Widthptr))) 358 sizeof_Array = int(Rnd(int64(array_cap)+int64(Widthptr), int64(Widthptr))) 359 360 // string is same as slice wo the cap 361 sizeof_String = int(Rnd(int64(array_nel)+int64(Widthptr), int64(Widthptr))) 362 363 dowidth(types.Types[TSTRING]) 364 dowidth(types.Idealstring) 365 366 itable = types.NewPtr(types.Types[TUINT8]) 367 } 368 369 func makeErrorInterface() *types.Type { 370 field := types.NewField() 371 field.Type = types.Types[TSTRING] 372 f := functypefield(fakeRecvField(), nil, []*types.Field{field}) 373 374 field = types.NewField() 375 field.Sym = lookup("Error") 376 field.Type = f 377 378 t := types.New(TINTER) 379 t.SetInterface([]*types.Field{field}) 380 return t 381 } 382 383 func lexinit1() { 384 // error type 385 s := builtinpkg.Lookup("error") 386 types.Errortype = makeErrorInterface() 387 types.Errortype.Sym = s 388 types.Errortype.Orig = makeErrorInterface() 389 s.Def = asTypesNode(typenod(types.Errortype)) 390 391 // We create separate byte and rune types for better error messages 392 // rather than just creating type alias *types.Sym's for the uint8 and 393 // int32 types. Hence, (bytetype|runtype).Sym.isAlias() is false. 394 // TODO(gri) Should we get rid of this special case (at the cost 395 // of less informative error messages involving bytes and runes)? 396 // (Alternatively, we could introduce an OTALIAS node representing 397 // type aliases, albeit at the cost of having to deal with it everywhere). 398 399 // byte alias 400 s = builtinpkg.Lookup("byte") 401 types.Bytetype = types.New(TUINT8) 402 types.Bytetype.Sym = s 403 s.Def = asTypesNode(typenod(types.Bytetype)) 404 asNode(s.Def).Name = new(Name) 405 406 // rune alias 407 s = builtinpkg.Lookup("rune") 408 types.Runetype = types.New(TINT32) 409 types.Runetype.Sym = s 410 s.Def = asTypesNode(typenod(types.Runetype)) 411 asNode(s.Def).Name = new(Name) 412 413 // backend-dependent builtin types (e.g. int). 414 for _, s := range typedefs { 415 s1 := builtinpkg.Lookup(s.name) 416 417 sameas := s.sameas32 418 if Widthptr == 8 { 419 sameas = s.sameas64 420 } 421 422 simtype[s.etype] = sameas 423 minfltval[s.etype] = minfltval[sameas] 424 maxfltval[s.etype] = maxfltval[sameas] 425 minintval[s.etype] = minintval[sameas] 426 maxintval[s.etype] = maxintval[sameas] 427 428 t := types.New(s.etype) 429 t.Sym = s1 430 types.Types[s.etype] = t 431 s1.Def = asTypesNode(typenod(t)) 432 asNode(s1.Def).Name = new(Name) 433 s1.Origpkg = builtinpkg 434 435 dowidth(t) 436 } 437 } 438 439 // finishUniverse makes the universe block visible within the current package. 440 func finishUniverse() { 441 // Operationally, this is similar to a dot import of builtinpkg, except 442 // that we silently skip symbols that are already declared in the 443 // package block rather than emitting a redeclared symbol error. 444 445 for _, s := range builtinpkg.Syms { 446 if s.Def == nil { 447 continue 448 } 449 s1 := lookup(s.Name) 450 if s1.Def != nil { 451 continue 452 } 453 454 s1.Def = s.Def 455 s1.Block = s.Block 456 } 457 458 nodfp = newname(lookup(".fp")) 459 nodfp.Type = types.Types[TINT32] 460 nodfp.SetClass(PPARAM) 461 nodfp.Name.SetUsed(true) 462 } 463