blob: 4c4487c649cc83382f190432e7c069a9babf9f7c [file] [log] [blame]
// 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 typecheck
import (
"go/constant"
"cmd/compile/internal/ir"
"cmd/compile/internal/types"
"cmd/internal/src"
)
var (
okfor [ir.OEND][]bool
)
var (
okforeq [types.NTYPE]bool
okforadd [types.NTYPE]bool
okforand [types.NTYPE]bool
okfornone [types.NTYPE]bool
okforbool [types.NTYPE]bool
okforcap [types.NTYPE]bool
okforlen [types.NTYPE]bool
okforarith [types.NTYPE]bool
)
var builtinFuncs = [...]struct {
name string
op ir.Op
}{
{"append", ir.OAPPEND},
{"cap", ir.OCAP},
{"clear", ir.OCLEAR},
{"close", ir.OCLOSE},
{"complex", ir.OCOMPLEX},
{"copy", ir.OCOPY},
{"delete", ir.ODELETE},
{"imag", ir.OIMAG},
{"len", ir.OLEN},
{"make", ir.OMAKE},
{"max", ir.OMAX},
{"min", ir.OMIN},
{"new", ir.ONEW},
{"panic", ir.OPANIC},
{"print", ir.OPRINT},
{"println", ir.OPRINTLN},
{"real", ir.OREAL},
{"recover", ir.ORECOVER},
}
var unsafeFuncs = [...]struct {
name string
op ir.Op
}{
{"Add", ir.OUNSAFEADD},
{"Slice", ir.OUNSAFESLICE},
{"SliceData", ir.OUNSAFESLICEDATA},
{"String", ir.OUNSAFESTRING},
{"StringData", ir.OUNSAFESTRINGDATA},
}
// InitUniverse initializes the universe block.
func InitUniverse() {
types.InitTypes(func(sym *types.Sym, typ *types.Type) types.Object {
n := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, sym)
n.SetType(typ)
n.SetTypecheck(1)
sym.Def = n
return n
})
for _, s := range &builtinFuncs {
ir.NewBuiltin(types.BuiltinPkg.Lookup(s.name), s.op)
}
for _, s := range &unsafeFuncs {
ir.NewBuiltin(types.UnsafePkg.Lookup(s.name), s.op)
}
s := types.BuiltinPkg.Lookup("true")
s.Def = ir.NewConstAt(src.NoXPos, s, types.UntypedBool, constant.MakeBool(true))
s = types.BuiltinPkg.Lookup("false")
s.Def = ir.NewConstAt(src.NoXPos, s, types.UntypedBool, constant.MakeBool(false))
s = Lookup("_")
types.BlankSym = s
ir.BlankNode = ir.NewNameAt(src.NoXPos, s, types.Types[types.TBLANK])
s.Def = ir.BlankNode
s = types.BuiltinPkg.Lookup("_")
s.Def = ir.NewNameAt(src.NoXPos, s, types.Types[types.TBLANK])
s = types.BuiltinPkg.Lookup("nil")
s.Def = NodNil()
// initialize okfor
for et := types.Kind(0); et < types.NTYPE; et++ {
if types.IsInt[et] || et == types.TIDEAL {
okforeq[et] = true
types.IsOrdered[et] = true
okforarith[et] = true
okforadd[et] = true
okforand[et] = true
ir.OKForConst[et] = true
types.IsSimple[et] = true
}
if types.IsFloat[et] {
okforeq[et] = true
types.IsOrdered[et] = true
okforadd[et] = true
okforarith[et] = true
ir.OKForConst[et] = true
types.IsSimple[et] = true
}
if types.IsComplex[et] {
okforeq[et] = true
okforadd[et] = true
okforarith[et] = true
ir.OKForConst[et] = true
types.IsSimple[et] = true
}
}
types.IsSimple[types.TBOOL] = true
okforadd[types.TSTRING] = true
okforbool[types.TBOOL] = true
okforcap[types.TARRAY] = true
okforcap[types.TCHAN] = true
okforcap[types.TSLICE] = true
ir.OKForConst[types.TBOOL] = true
ir.OKForConst[types.TSTRING] = true
okforlen[types.TARRAY] = true
okforlen[types.TCHAN] = true
okforlen[types.TMAP] = true
okforlen[types.TSLICE] = true
okforlen[types.TSTRING] = true
okforeq[types.TPTR] = true
okforeq[types.TUNSAFEPTR] = true
okforeq[types.TINTER] = true
okforeq[types.TCHAN] = true
okforeq[types.TSTRING] = true
okforeq[types.TBOOL] = true
okforeq[types.TMAP] = true // nil only; refined in typecheck
okforeq[types.TFUNC] = true // nil only; refined in typecheck
okforeq[types.TSLICE] = true // nil only; refined in typecheck
okforeq[types.TARRAY] = true // only if element type is comparable; refined in typecheck
okforeq[types.TSTRUCT] = true // only if all struct fields are comparable; refined in typecheck
types.IsOrdered[types.TSTRING] = true
for i := range okfor {
okfor[i] = okfornone[:]
}
// binary
okfor[ir.OADD] = okforadd[:]
okfor[ir.OAND] = okforand[:]
okfor[ir.OANDAND] = okforbool[:]
okfor[ir.OANDNOT] = okforand[:]
okfor[ir.ODIV] = okforarith[:]
okfor[ir.OEQ] = okforeq[:]
okfor[ir.OGE] = types.IsOrdered[:]
okfor[ir.OGT] = types.IsOrdered[:]
okfor[ir.OLE] = types.IsOrdered[:]
okfor[ir.OLT] = types.IsOrdered[:]
okfor[ir.OMOD] = okforand[:]
okfor[ir.OMUL] = okforarith[:]
okfor[ir.ONE] = okforeq[:]
okfor[ir.OOR] = okforand[:]
okfor[ir.OOROR] = okforbool[:]
okfor[ir.OSUB] = okforarith[:]
okfor[ir.OXOR] = okforand[:]
okfor[ir.OLSH] = okforand[:]
okfor[ir.ORSH] = okforand[:]
// unary
okfor[ir.OBITNOT] = okforand[:]
okfor[ir.ONEG] = okforarith[:]
okfor[ir.ONOT] = okforbool[:]
okfor[ir.OPLUS] = okforarith[:]
// special
okfor[ir.OCAP] = okforcap[:]
okfor[ir.OLEN] = okforlen[:]
}