go/src/cmd/compile/internal/gc/universe.go
Matthew Dempsky 0d2e92c2ca cmd/compile: add Fields field to Type
Switch TSTRUCT and TINTER to use Fields instead of Type, which wrings
out the remaining few direct uses of the latter.

Preparation for converting fields to use a separate "Field" type.

Passes toolstash/buildall.

Change-Id: I5a2ea7e159d0dde1be2c9afafc10a8f739d95743
Reviewed-on: https://go-review.googlesource.com/20675
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2016-03-14 20:44:45 +00:00

471 lines
10 KiB
Go

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
// builtinpkg is a fake package that declares the universe block.
var builtinpkg *Pkg
var itable *Type // distinguished *byte
var basicTypes = [...]struct {
name string
etype EType
}{
{"int8", TINT8},
{"int16", TINT16},
{"int32", TINT32},
{"int64", TINT64},
{"uint8", TUINT8},
{"uint16", TUINT16},
{"uint32", TUINT32},
{"uint64", TUINT64},
{"float32", TFLOAT32},
{"float64", TFLOAT64},
{"complex64", TCOMPLEX64},
{"complex128", TCOMPLEX128},
{"bool", TBOOL},
{"string", TSTRING},
{"any", TANY},
}
var typedefs = [...]struct {
name string
etype EType
width *int
sameas32 EType
sameas64 EType
}{
{"int", TINT, &Widthint, TINT32, TINT64},
{"uint", TUINT, &Widthint, TUINT32, TUINT64},
{"uintptr", TUINTPTR, &Widthptr, TUINT32, TUINT64},
}
var builtinFuncs = [...]struct {
name string
op Op
}{
{"append", OAPPEND},
{"cap", OCAP},
{"close", OCLOSE},
{"complex", OCOMPLEX},
{"copy", OCOPY},
{"delete", ODELETE},
{"imag", OIMAG},
{"len", OLEN},
{"make", OMAKE},
{"new", ONEW},
{"panic", OPANIC},
{"print", OPRINT},
{"println", OPRINTN},
{"real", OREAL},
{"recover", ORECOVER},
}
// initUniverse initializes the universe block.
func initUniverse() {
lexinit()
typeinit()
lexinit1()
}
// lexinit initializes known symbols and the basic types.
func lexinit() {
for _, s := range basicTypes {
etype := s.etype
if int(etype) >= len(Types) {
Fatalf("lexinit: %s bad etype", s.name)
}
s2 := Pkglookup(s.name, builtinpkg)
t := Types[etype]
if t == nil {
t = typ(etype)
t.Sym = s2
if etype != TANY && etype != TSTRING {
dowidth(t)
}
Types[etype] = t
}
s2.Def = typenod(t)
s2.Def.Name = new(Name)
}
for _, s := range builtinFuncs {
// TODO(marvin): Fix Node.EType type union.
s2 := Pkglookup(s.name, builtinpkg)
s2.Def = Nod(ONAME, nil, nil)
s2.Def.Sym = s2
s2.Def.Etype = EType(s.op)
}
idealstring = typ(TSTRING)
idealbool = typ(TBOOL)
s := Pkglookup("true", builtinpkg)
s.Def = Nodbool(true)
s.Def.Sym = Lookup("true")
s.Def.Name = new(Name)
s.Def.Type = idealbool
s = Pkglookup("false", builtinpkg)
s.Def = Nodbool(false)
s.Def.Sym = Lookup("false")
s.Def.Name = new(Name)
s.Def.Type = idealbool
s = Lookup("_")
s.Block = -100
s.Def = Nod(ONAME, nil, nil)
s.Def.Sym = s
Types[TBLANK] = typ(TBLANK)
s.Def.Type = Types[TBLANK]
nblank = s.Def
s = Pkglookup("_", builtinpkg)
s.Block = -100
s.Def = Nod(ONAME, nil, nil)
s.Def.Sym = s
Types[TBLANK] = typ(TBLANK)
s.Def.Type = Types[TBLANK]
Types[TNIL] = typ(TNIL)
s = Pkglookup("nil", builtinpkg)
var v Val
v.U = new(NilVal)
s.Def = nodlit(v)
s.Def.Sym = s
s.Def.Name = new(Name)
s = Pkglookup("iota", builtinpkg)
s.Def = Nod(OIOTA, nil, nil)
s.Def.Sym = s
s.Def.Name = new(Name)
}
func typeinit() {
if Widthptr == 0 {
Fatalf("typeinit before betypeinit")
}
for et := EType(0); et < NTYPE; et++ {
Simtype[et] = et
}
Types[TPTR32] = typ(TPTR32)
dowidth(Types[TPTR32])
Types[TPTR64] = typ(TPTR64)
dowidth(Types[TPTR64])
t := typ(TUNSAFEPTR)
Types[TUNSAFEPTR] = t
t.Sym = Pkglookup("Pointer", unsafepkg)
t.Sym.Def = typenod(t)
t.Sym.Def.Name = new(Name)
dowidth(Types[TUNSAFEPTR])
Tptr = TPTR32
if Widthptr == 8 {
Tptr = TPTR64
}
for et := TINT8; et <= TUINT64; et++ {
Isint[et] = true
}
Isint[TINT] = true
Isint[TUINT] = true
Isint[TUINTPTR] = true
Isfloat[TFLOAT32] = true
Isfloat[TFLOAT64] = true
Iscomplex[TCOMPLEX64] = true
Iscomplex[TCOMPLEX128] = true
Isptr[TPTR32] = true
Isptr[TPTR64] = true
isforw[TFORW] = true
Issigned[TINT] = true
Issigned[TINT8] = true
Issigned[TINT16] = true
Issigned[TINT32] = true
Issigned[TINT64] = true
// initialize okfor
for et := EType(0); et < NTYPE; et++ {
if Isint[et] || et == TIDEAL {
okforeq[et] = true
okforcmp[et] = true
okforarith[et] = true
okforadd[et] = true
okforand[et] = true
okforconst[et] = true
issimple[et] = true
Minintval[et] = new(Mpint)
Maxintval[et] = new(Mpint)
}
if Isfloat[et] {
okforeq[et] = true
okforcmp[et] = true
okforadd[et] = true
okforarith[et] = true
okforconst[et] = true
issimple[et] = true
minfltval[et] = newMpflt()
maxfltval[et] = newMpflt()
}
if Iscomplex[et] {
okforeq[et] = true
okforadd[et] = true
okforarith[et] = true
okforconst[et] = true
issimple[et] = true
}
}
issimple[TBOOL] = true
okforadd[TSTRING] = true
okforbool[TBOOL] = true
okforcap[TARRAY] = true
okforcap[TCHAN] = true
okforconst[TBOOL] = true
okforconst[TSTRING] = true
okforlen[TARRAY] = true
okforlen[TCHAN] = true
okforlen[TMAP] = true
okforlen[TSTRING] = true
okforeq[TPTR32] = true
okforeq[TPTR64] = true
okforeq[TUNSAFEPTR] = true
okforeq[TINTER] = true
okforeq[TCHAN] = true
okforeq[TSTRING] = true
okforeq[TBOOL] = true
okforeq[TMAP] = true // nil only; refined in typecheck
okforeq[TFUNC] = true // nil only; refined in typecheck
okforeq[TARRAY] = true // nil slice only; refined in typecheck
okforeq[TSTRUCT] = true // it's complicated; refined in typecheck
okforcmp[TSTRING] = true
var i int
for i = 0; i < len(okfor); i++ {
okfor[i] = okfornone[:]
}
// binary
okfor[OADD] = okforadd[:]
okfor[OAND] = okforand[:]
okfor[OANDAND] = okforbool[:]
okfor[OANDNOT] = okforand[:]
okfor[ODIV] = okforarith[:]
okfor[OEQ] = okforeq[:]
okfor[OGE] = okforcmp[:]
okfor[OGT] = okforcmp[:]
okfor[OLE] = okforcmp[:]
okfor[OLT] = okforcmp[:]
okfor[OMOD] = okforand[:]
okfor[OHMUL] = okforarith[:]
okfor[OMUL] = okforarith[:]
okfor[ONE] = okforeq[:]
okfor[OOR] = okforand[:]
okfor[OOROR] = okforbool[:]
okfor[OSUB] = okforarith[:]
okfor[OXOR] = okforand[:]
okfor[OLSH] = okforand[:]
okfor[ORSH] = okforand[:]
// unary
okfor[OCOM] = okforand[:]
okfor[OMINUS] = okforarith[:]
okfor[ONOT] = okforbool[:]
okfor[OPLUS] = okforarith[:]
// special
okfor[OCAP] = okforcap[:]
okfor[OLEN] = okforlen[:]
// comparison
iscmp[OLT] = true
iscmp[OGT] = true
iscmp[OGE] = true
iscmp[OLE] = true
iscmp[OEQ] = true
iscmp[ONE] = true
mpatofix(Maxintval[TINT8], "0x7f")
mpatofix(Minintval[TINT8], "-0x80")
mpatofix(Maxintval[TINT16], "0x7fff")
mpatofix(Minintval[TINT16], "-0x8000")
mpatofix(Maxintval[TINT32], "0x7fffffff")
mpatofix(Minintval[TINT32], "-0x80000000")
mpatofix(Maxintval[TINT64], "0x7fffffffffffffff")
mpatofix(Minintval[TINT64], "-0x8000000000000000")
mpatofix(Maxintval[TUINT8], "0xff")
mpatofix(Maxintval[TUINT16], "0xffff")
mpatofix(Maxintval[TUINT32], "0xffffffff")
mpatofix(Maxintval[TUINT64], "0xffffffffffffffff")
// f is valid float if min < f < max. (min and max are not themselves valid.)
mpatoflt(maxfltval[TFLOAT32], "33554431p103") // 2^24-1 p (127-23) + 1/2 ulp
mpatoflt(minfltval[TFLOAT32], "-33554431p103")
mpatoflt(maxfltval[TFLOAT64], "18014398509481983p970") // 2^53-1 p (1023-52) + 1/2 ulp
mpatoflt(minfltval[TFLOAT64], "-18014398509481983p970")
maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32]
minfltval[TCOMPLEX64] = minfltval[TFLOAT32]
maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64]
minfltval[TCOMPLEX128] = minfltval[TFLOAT64]
// for walk to use in error messages
Types[TFUNC] = functype(nil, nil, nil)
// types used in front end
// types[TNIL] got set early in lexinit
Types[TIDEAL] = typ(TIDEAL)
Types[TINTER] = typ(TINTER)
// simple aliases
Simtype[TMAP] = Tptr
Simtype[TCHAN] = Tptr
Simtype[TFUNC] = Tptr
Simtype[TUNSAFEPTR] = Tptr
Array_array = int(Rnd(0, int64(Widthptr)))
Array_nel = int(Rnd(int64(Array_array)+int64(Widthptr), int64(Widthint)))
Array_cap = int(Rnd(int64(Array_nel)+int64(Widthint), int64(Widthint)))
sizeof_Array = int(Rnd(int64(Array_cap)+int64(Widthint), int64(Widthptr)))
// string is same as slice wo the cap
sizeof_String = int(Rnd(int64(Array_nel)+int64(Widthint), int64(Widthptr)))
dowidth(Types[TSTRING])
dowidth(idealstring)
itable = typ(Tptr)
itable.Type = Types[TUINT8]
}
func lexinit1() {
// t = interface { Error() string }
rcvr := typ(TSTRUCT)
rcvr.Funarg = true
field := typ(TFIELD)
field.Type = Ptrto(typ(TSTRUCT))
rcvr.SetFields([]*Type{field})
in := typ(TSTRUCT)
in.Funarg = true
out := typ(TSTRUCT)
out.Funarg = true
field = typ(TFIELD)
field.Type = Types[TSTRING]
out.SetFields([]*Type{field})
f := typ(TFUNC)
*f.RecvsP() = rcvr
*f.ResultsP() = out
*f.ParamsP() = in
f.Thistuple = 1
f.Intuple = 0
f.Outnamed = false
f.Outtuple = 1
t := typ(TINTER)
field = typ(TFIELD)
field.Sym = Lookup("Error")
field.Type = f
t.SetFields([]*Type{field})
// error type
s := Pkglookup("error", builtinpkg)
errortype = t
errortype.Sym = s
s.Def = typenod(errortype)
// byte alias
s = Pkglookup("byte", builtinpkg)
bytetype = typ(TUINT8)
bytetype.Sym = s
s.Def = typenod(bytetype)
s.Def.Name = new(Name)
// rune alias
s = Pkglookup("rune", builtinpkg)
runetype = typ(TINT32)
runetype.Sym = s
s.Def = typenod(runetype)
s.Def.Name = new(Name)
// backend-dependent builtin types (e.g. int).
for _, s := range typedefs {
s1 := Pkglookup(s.name, builtinpkg)
sameas := s.sameas32
if *s.width == 8 {
sameas = s.sameas64
}
Simtype[s.etype] = sameas
minfltval[s.etype] = minfltval[sameas]
maxfltval[s.etype] = maxfltval[sameas]
Minintval[s.etype] = Minintval[sameas]
Maxintval[s.etype] = Maxintval[sameas]
t := typ(s.etype)
t.Sym = s1
Types[s.etype] = t
s1.Def = typenod(t)
s1.Def.Name = new(Name)
s1.Origpkg = builtinpkg
dowidth(t)
}
}
// finishUniverse makes the universe block visible within the current package.
func finishUniverse() {
// Operationally, this is similar to a dot import of builtinpkg, except
// that we silently skip symbols that are already declared in the
// package block rather than emitting a redeclared symbol error.
for _, s := range builtinpkg.Syms {
if s.Def == nil || (s.Name == "any" && Debug['A'] == 0) {
continue
}
s1 := Lookup(s.Name)
if s1.Def != nil {
continue
}
s1.Def = s.Def
s1.Block = s.Block
}
nodfp = Nod(ONAME, nil, nil)
nodfp.Type = Types[TINT32]
nodfp.Xoffset = 0
nodfp.Class = PPARAM
nodfp.Sym = Lookup(".fp")
}