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

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

View as plain text