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 5package typecheck 6 7import ( 8 "go/constant" 9 10 "cmd/compile/internal/ir" 11 "cmd/compile/internal/types" 12 "cmd/internal/src" 13) 14 15var ( 16 okfor [ir.OEND][]bool 17) 18 19var ( 20 okforeq [types.NTYPE]bool 21 okforadd [types.NTYPE]bool 22 okforand [types.NTYPE]bool 23 okfornone [types.NTYPE]bool 24 okforbool [types.NTYPE]bool 25 okforcap [types.NTYPE]bool 26 okforlen [types.NTYPE]bool 27 okforarith [types.NTYPE]bool 28) 29 30var builtinFuncs = [...]struct { 31 name string 32 op ir.Op 33}{ 34 {"append", ir.OAPPEND}, 35 {"cap", ir.OCAP}, 36 {"clear", ir.OCLEAR}, 37 {"close", ir.OCLOSE}, 38 {"complex", ir.OCOMPLEX}, 39 {"copy", ir.OCOPY}, 40 {"delete", ir.ODELETE}, 41 {"imag", ir.OIMAG}, 42 {"len", ir.OLEN}, 43 {"make", ir.OMAKE}, 44 {"max", ir.OMAX}, 45 {"min", ir.OMIN}, 46 {"new", ir.ONEW}, 47 {"panic", ir.OPANIC}, 48 {"print", ir.OPRINT}, 49 {"println", ir.OPRINTLN}, 50 {"real", ir.OREAL}, 51 {"recover", ir.ORECOVER}, 52} 53 54var unsafeFuncs = [...]struct { 55 name string 56 op ir.Op 57}{ 58 {"Add", ir.OUNSAFEADD}, 59 {"Slice", ir.OUNSAFESLICE}, 60 {"SliceData", ir.OUNSAFESLICEDATA}, 61 {"String", ir.OUNSAFESTRING}, 62 {"StringData", ir.OUNSAFESTRINGDATA}, 63} 64 65// InitUniverse initializes the universe block. 66func InitUniverse() { 67 types.InitTypes(func(sym *types.Sym, typ *types.Type) types.Object { 68 n := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, sym) 69 n.SetType(typ) 70 n.SetTypecheck(1) 71 sym.Def = n 72 return n 73 }) 74 75 for _, s := range &builtinFuncs { 76 ir.NewBuiltin(types.BuiltinPkg.Lookup(s.name), s.op) 77 } 78 79 for _, s := range &unsafeFuncs { 80 ir.NewBuiltin(types.UnsafePkg.Lookup(s.name), s.op) 81 } 82 83 s := types.BuiltinPkg.Lookup("true") 84 s.Def = ir.NewConstAt(src.NoXPos, s, types.UntypedBool, constant.MakeBool(true)) 85 86 s = types.BuiltinPkg.Lookup("false") 87 s.Def = ir.NewConstAt(src.NoXPos, s, types.UntypedBool, constant.MakeBool(false)) 88 89 s = Lookup("_") 90 types.BlankSym = s 91 ir.BlankNode = ir.NewNameAt(src.NoXPos, s, types.Types[types.TBLANK]) 92 s.Def = ir.BlankNode 93 94 s = types.BuiltinPkg.Lookup("_") 95 s.Def = ir.NewNameAt(src.NoXPos, s, types.Types[types.TBLANK]) 96 97 s = types.BuiltinPkg.Lookup("nil") 98 s.Def = NodNil() 99 100 // initialize okfor 101 for et := types.Kind(0); et < types.NTYPE; et++ { 102 if types.IsInt[et] || et == types.TIDEAL { 103 okforeq[et] = true 104 types.IsOrdered[et] = true 105 okforarith[et] = true 106 okforadd[et] = true 107 okforand[et] = true 108 ir.OKForConst[et] = true 109 types.IsSimple[et] = true 110 } 111 112 if types.IsFloat[et] { 113 okforeq[et] = true 114 types.IsOrdered[et] = true 115 okforadd[et] = true 116 okforarith[et] = true 117 ir.OKForConst[et] = true 118 types.IsSimple[et] = true 119 } 120 121 if types.IsComplex[et] { 122 okforeq[et] = true 123 okforadd[et] = true 124 okforarith[et] = true 125 ir.OKForConst[et] = true 126 types.IsSimple[et] = true 127 } 128 } 129 130 types.IsSimple[types.TBOOL] = true 131 132 okforadd[types.TSTRING] = true 133 134 okforbool[types.TBOOL] = true 135 136 okforcap[types.TARRAY] = true 137 okforcap[types.TCHAN] = true 138 okforcap[types.TSLICE] = true 139 140 ir.OKForConst[types.TBOOL] = true 141 ir.OKForConst[types.TSTRING] = true 142 143 okforlen[types.TARRAY] = true 144 okforlen[types.TCHAN] = true 145 okforlen[types.TMAP] = true 146 okforlen[types.TSLICE] = true 147 okforlen[types.TSTRING] = true 148 149 okforeq[types.TPTR] = true 150 okforeq[types.TUNSAFEPTR] = true 151 okforeq[types.TINTER] = true 152 okforeq[types.TCHAN] = true 153 okforeq[types.TSTRING] = true 154 okforeq[types.TBOOL] = true 155 okforeq[types.TMAP] = true // nil only; refined in typecheck 156 okforeq[types.TFUNC] = true // nil only; refined in typecheck 157 okforeq[types.TSLICE] = true // nil only; refined in typecheck 158 okforeq[types.TARRAY] = true // only if element type is comparable; refined in typecheck 159 okforeq[types.TSTRUCT] = true // only if all struct fields are comparable; refined in typecheck 160 161 types.IsOrdered[types.TSTRING] = true 162 163 for i := range okfor { 164 okfor[i] = okfornone[:] 165 } 166 167 // binary 168 okfor[ir.OADD] = okforadd[:] 169 okfor[ir.OAND] = okforand[:] 170 okfor[ir.OANDAND] = okforbool[:] 171 okfor[ir.OANDNOT] = okforand[:] 172 okfor[ir.ODIV] = okforarith[:] 173 okfor[ir.OEQ] = okforeq[:] 174 okfor[ir.OGE] = types.IsOrdered[:] 175 okfor[ir.OGT] = types.IsOrdered[:] 176 okfor[ir.OLE] = types.IsOrdered[:] 177 okfor[ir.OLT] = types.IsOrdered[:] 178 okfor[ir.OMOD] = okforand[:] 179 okfor[ir.OMUL] = okforarith[:] 180 okfor[ir.ONE] = okforeq[:] 181 okfor[ir.OOR] = okforand[:] 182 okfor[ir.OOROR] = okforbool[:] 183 okfor[ir.OSUB] = okforarith[:] 184 okfor[ir.OXOR] = okforand[:] 185 okfor[ir.OLSH] = okforand[:] 186 okfor[ir.ORSH] = okforand[:] 187 188 // unary 189 okfor[ir.OBITNOT] = okforand[:] 190 okfor[ir.ONEG] = okforarith[:] 191 okfor[ir.ONOT] = okforbool[:] 192 okfor[ir.OPLUS] = okforarith[:] 193 194 // special 195 okfor[ir.OCAP] = okforcap[:] 196 okfor[ir.OLEN] = okforlen[:] 197} 198