Source file src/cmd/compile/internal/typecheck/universe.go

     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  package typecheck
     6  
     7  import (
     8  	"go/constant"
     9  
    10  	"cmd/compile/internal/ir"
    11  	"cmd/compile/internal/types"
    12  	"cmd/internal/src"
    13  )
    14  
    15  var (
    16  	okfor [ir.OEND][]bool
    17  )
    18  
    19  var (
    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  
    30  var 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  
    54  var 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.
    66  func 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  

View as plain text