universe.go raw

   1  // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
   2  // Source: ../../cmd/compile/internal/types2/universe.go
   3  
   4  // Copyright 2011 The Go Authors. All rights reserved.
   5  // Use of this source code is governed by a BSD-style
   6  // license that can be found in the LICENSE file.
   7  
   8  // This file sets up the universe scope and the unsafe package.
   9  
  10  package types
  11  
  12  import (
  13  	"go/constant"
  14  	"strings"
  15  )
  16  
  17  // The Universe scope contains all predeclared objects of Go.
  18  // It is the outermost scope of any chain of nested scopes.
  19  var Universe *Scope
  20  
  21  // The Unsafe package is the package returned by an importer
  22  // for the import path "unsafe".
  23  var Unsafe *Package
  24  
  25  var (
  26  	universeIota       Object
  27  	universeBool       Type
  28  	universeByte       Type // uint8 alias, but has name "byte"
  29  	universeRune       Type // int32 alias, but has name "rune"
  30  	universeAnyNoAlias *TypeName
  31  	universeAnyAlias   *TypeName
  32  	universeError      Type
  33  	universeComparable Object
  34  )
  35  
  36  // Typ contains the predeclared *Basic types indexed by their
  37  // corresponding BasicKind.
  38  //
  39  // The *Basic type for Typ[Byte] will have the name "uint8".
  40  // Use Universe.Lookup("byte").Type() to obtain the specific
  41  // alias basic type named "byte" (and analogous for "rune").
  42  var Typ = []*Basic{
  43  	Invalid: {Invalid, 0, "invalid type"},
  44  
  45  	Bool:          {Bool, IsBoolean, "bool"},
  46  	Int:           {Int, IsInteger, "int"},
  47  	Int8:          {Int8, IsInteger, "int8"},
  48  	Int16:         {Int16, IsInteger, "int16"},
  49  	Int32:         {Int32, IsInteger, "int32"},
  50  	Int64:         {Int64, IsInteger, "int64"},
  51  	Uint:          {Uint, IsInteger | IsUnsigned, "uint"},
  52  	Uint8:         {Uint8, IsInteger | IsUnsigned, "uint8"},
  53  	Uint16:        {Uint16, IsInteger | IsUnsigned, "uint16"},
  54  	Uint32:        {Uint32, IsInteger | IsUnsigned, "uint32"},
  55  	Uint64:        {Uint64, IsInteger | IsUnsigned, "uint64"},
  56  	Uintptr:       {Uintptr, IsInteger | IsUnsigned, "uintptr"},
  57  	Float32:       {Float32, IsFloat, "float32"},
  58  	Float64:       {Float64, IsFloat, "float64"},
  59  	Complex64:     {Complex64, IsComplex, "complex64"},
  60  	Complex128:    {Complex128, IsComplex, "complex128"},
  61  	String:        {String, IsString, "string"},
  62  	UnsafePointer: {UnsafePointer, 0, "Pointer"},
  63  
  64  	UntypedBool:    {UntypedBool, IsBoolean | IsUntyped, "untyped bool"},
  65  	UntypedInt:     {UntypedInt, IsInteger | IsUntyped, "untyped int"},
  66  	UntypedRune:    {UntypedRune, IsInteger | IsUntyped, "untyped rune"},
  67  	UntypedFloat:   {UntypedFloat, IsFloat | IsUntyped, "untyped float"},
  68  	UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"},
  69  	UntypedString:  {UntypedString, IsString | IsUntyped, "untyped string"},
  70  	UntypedNil:     {UntypedNil, IsUntyped, "untyped nil"},
  71  }
  72  
  73  var basicAliases = [...]*Basic{
  74  	{Byte, IsInteger | IsUnsigned, "byte"},
  75  	{Rune, IsInteger, "rune"},
  76  }
  77  
  78  func defPredeclaredTypes() {
  79  	for _, t := range Typ {
  80  		def(NewTypeName(nopos, nil, t.name, t))
  81  	}
  82  	for _, t := range basicAliases {
  83  		def(NewTypeName(nopos, nil, t.name, t))
  84  	}
  85  
  86  	// type any = interface{}
  87  	//
  88  	// Implement two representations of any: one for the legacy gotypesalias=0,
  89  	// and one for gotypesalias=1. This is necessary for consistent
  90  	// representation of interface aliases during type checking, and is
  91  	// implemented via hijacking [Scope.Lookup] for the [Universe] scope.
  92  	//
  93  	// Both representations use the same distinguished pointer for their RHS
  94  	// interface type, allowing us to detect any (even with the legacy
  95  	// representation), and format it as "any" rather than interface{}, which
  96  	// clarifies user-facing error messages significantly.
  97  	//
  98  	// TODO(rfindley): once the gotypesalias GODEBUG variable is obsolete (and we
  99  	// consistently use the Alias node), we should be able to clarify user facing
 100  	// error messages without using a distinguished pointer for the any
 101  	// interface.
 102  	{
 103  		universeAnyNoAlias = NewTypeName(nopos, nil, "any", &Interface{complete: true, tset: &topTypeSet})
 104  		universeAnyNoAlias.setColor(black)
 105  		// ensure that the any TypeName reports a consistent Parent, after
 106  		// hijacking Universe.Lookup with gotypesalias=0.
 107  		universeAnyNoAlias.setParent(Universe)
 108  
 109  		// It shouldn't matter which representation of any is actually inserted
 110  		// into the Universe, but we lean toward the future and insert the Alias
 111  		// representation.
 112  		universeAnyAlias = NewTypeName(nopos, nil, "any", nil)
 113  		universeAnyAlias.setColor(black)
 114  		_ = NewAlias(universeAnyAlias, universeAnyNoAlias.Type().Underlying()) // Link TypeName and Alias
 115  		def(universeAnyAlias)
 116  	}
 117  
 118  	// type error interface{ Error() string }
 119  	{
 120  		obj := NewTypeName(nopos, nil, "error", nil)
 121  		obj.setColor(black)
 122  		typ := NewNamed(obj, nil, nil)
 123  
 124  		// error.Error() string
 125  		recv := newVar(RecvVar, nopos, nil, "", typ)
 126  		res := newVar(ResultVar, nopos, nil, "", Typ[String])
 127  		sig := NewSignatureType(recv, nil, nil, nil, NewTuple(res), false)
 128  		err := NewFunc(nopos, nil, "Error", sig)
 129  
 130  		// interface{ Error() string }
 131  		ityp := &Interface{methods: []*Func{err}, complete: true}
 132  		computeInterfaceTypeSet(nil, nopos, ityp) // prevent races due to lazy computation of tset
 133  
 134  		typ.SetUnderlying(ityp)
 135  		def(obj)
 136  	}
 137  
 138  	// type comparable interface{} // marked as comparable
 139  	{
 140  		obj := NewTypeName(nopos, nil, "comparable", nil)
 141  		obj.setColor(black)
 142  		typ := NewNamed(obj, nil, nil)
 143  
 144  		// interface{} // marked as comparable
 145  		ityp := &Interface{complete: true, tset: &_TypeSet{nil, allTermlist, true}}
 146  
 147  		typ.SetUnderlying(ityp)
 148  		def(obj)
 149  	}
 150  }
 151  
 152  var predeclaredConsts = [...]struct {
 153  	name string
 154  	kind BasicKind
 155  	val  constant.Value
 156  }{
 157  	{"true", UntypedBool, constant.MakeBool(true)},
 158  	{"false", UntypedBool, constant.MakeBool(false)},
 159  	{"iota", UntypedInt, constant.MakeInt64(0)},
 160  }
 161  
 162  func defPredeclaredConsts() {
 163  	for _, c := range predeclaredConsts {
 164  		def(NewConst(nopos, nil, c.name, Typ[c.kind], c.val))
 165  	}
 166  }
 167  
 168  func defPredeclaredNil() {
 169  	def(&Nil{object{name: "nil", typ: Typ[UntypedNil], color_: black}})
 170  }
 171  
 172  // A builtinId is the id of a builtin function.
 173  type builtinId int
 174  
 175  const (
 176  	// universe scope
 177  	_Append builtinId = iota
 178  	_Cap
 179  	_Clear
 180  	_Close
 181  	_Complex
 182  	_Copy
 183  	_Delete
 184  	_Imag
 185  	_Len
 186  	_Make
 187  	_Max
 188  	_Min
 189  	_New
 190  	_Panic
 191  	_Print
 192  	_Println
 193  	_Real
 194  	_Recover
 195  	_Spawn
 196  	_Free
 197  
 198  	// package unsafe
 199  	_Add
 200  	_Alignof
 201  	_Offsetof
 202  	_Sizeof
 203  	_Slice
 204  	_SliceData
 205  	_String
 206  	_StringData
 207  
 208  	// testing support
 209  	_Assert
 210  	_Trace
 211  )
 212  
 213  var predeclaredFuncs = [...]struct {
 214  	name     string
 215  	nargs    int
 216  	variadic bool
 217  	kind     exprKind
 218  }{
 219  	_Append:  {"append", 1, true, expression},
 220  	_Cap:     {"cap", 1, false, expression},
 221  	_Clear:   {"clear", 1, false, statement},
 222  	_Close:   {"close", 1, false, statement},
 223  	_Complex: {"complex", 2, false, expression},
 224  	_Copy:    {"copy", 2, false, statement},
 225  	_Delete:  {"delete", 2, false, statement},
 226  	_Imag:    {"imag", 1, false, expression},
 227  	_Len:     {"len", 1, false, expression},
 228  	_Make:    {"make", 1, true, expression},
 229  	// To disable max/min, remove the next two lines.
 230  	_Max:     {"max", 1, true, expression},
 231  	_Min:     {"min", 1, true, expression},
 232  	_New:     {"new", 1, false, expression},
 233  	_Panic:   {"panic", 1, false, statement},
 234  	_Print:   {"print", 0, true, statement},
 235  	_Println: {"println", 0, true, statement},
 236  	_Real:    {"real", 1, false, expression},
 237  	_Recover: {"recover", 0, false, statement},
 238  	_Spawn:   {"spawn", 1, true, statement},
 239  	_Free:    {"free", 1, false, statement},
 240  
 241  	_Add:        {"Add", 2, false, expression},
 242  	_Alignof:    {"Alignof", 1, false, expression},
 243  	_Offsetof:   {"Offsetof", 1, false, expression},
 244  	_Sizeof:     {"Sizeof", 1, false, expression},
 245  	_Slice:      {"Slice", 2, false, expression},
 246  	_SliceData:  {"SliceData", 1, false, expression},
 247  	_String:     {"String", 2, false, expression},
 248  	_StringData: {"StringData", 1, false, expression},
 249  
 250  	_Assert: {"assert", 1, false, statement},
 251  	_Trace:  {"trace", 0, true, statement},
 252  }
 253  
 254  func defPredeclaredFuncs() {
 255  	for i := range predeclaredFuncs {
 256  		id := builtinId(i)
 257  		if id == _Assert || id == _Trace {
 258  			continue // only define these in testing environment
 259  		}
 260  		def(newBuiltin(id))
 261  	}
 262  }
 263  
 264  // DefPredeclaredTestFuncs defines the assert and trace built-ins.
 265  // These built-ins are intended for debugging and testing of this
 266  // package only.
 267  func DefPredeclaredTestFuncs() {
 268  	if Universe.Lookup("assert") != nil {
 269  		return // already defined
 270  	}
 271  	def(newBuiltin(_Assert))
 272  	def(newBuiltin(_Trace))
 273  }
 274  
 275  func init() {
 276  	Universe = NewScope(nil, nopos, nopos, "universe")
 277  	Unsafe = NewPackage("unsafe", "unsafe")
 278  	Unsafe.complete = true
 279  
 280  	defPredeclaredTypes()
 281  	defPredeclaredConsts()
 282  	defPredeclaredNil()
 283  	defPredeclaredFuncs()
 284  
 285  	universeIota = Universe.Lookup("iota")
 286  	universeBool = Universe.Lookup("bool").Type()
 287  	universeByte = Universe.Lookup("byte").Type()
 288  	universeRune = Universe.Lookup("rune").Type()
 289  	universeError = Universe.Lookup("error").Type()
 290  	universeComparable = Universe.Lookup("comparable")
 291  }
 292  
 293  // Objects with names containing blanks are internal and not entered into
 294  // a scope. Objects with exported names are inserted in the unsafe package
 295  // scope; other objects are inserted in the universe scope.
 296  func def(obj Object) {
 297  	assert(obj.color() == black)
 298  	name := obj.Name()
 299  	if strings.Contains(name, " ") {
 300  		return // nothing to do
 301  	}
 302  	// fix Obj link for named types
 303  	if typ := asNamed(obj.Type()); typ != nil {
 304  		typ.obj = obj.(*TypeName)
 305  	}
 306  	// exported identifiers go into package unsafe
 307  	scope := Universe
 308  	if obj.Exported() {
 309  		scope = Unsafe.scope
 310  		// set Pkg field
 311  		switch obj := obj.(type) {
 312  		case *TypeName:
 313  			obj.pkg = Unsafe
 314  		case *Builtin:
 315  			obj.pkg = Unsafe
 316  		default:
 317  			panic("unreachable")
 318  		}
 319  	}
 320  	if scope.Insert(obj) != nil {
 321  		panic("double declaration of predeclared identifier")
 322  	}
 323  }
 324