github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/go/types/universe.go (about) 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 types 8 9 import ( 10 "go/constant" 11 "go/token" 12 "strings" 13 ) 14 15 var ( 16 Universe *Scope 17 Unsafe *Package 18 universeIota *Const 19 universeByte *Basic // uint8 alias, but has name "byte" 20 universeRune *Basic // int32 alias, but has name "rune" 21 ) 22 23 // Typ contains the predeclared *Basic types indexed by their 24 // corresponding BasicKind. 25 // 26 // The *Basic type for Typ[Byte] will have the name "uint8". 27 // Use Universe.Lookup("byte").Type() to obtain the specific 28 // alias basic type named "byte" (and analogous for "rune"). 29 var Typ = []*Basic{ 30 Invalid: {Invalid, 0, "invalid type"}, 31 32 Bool: {Bool, IsBoolean, "bool"}, 33 Int: {Int, IsInteger, "int"}, 34 Int8: {Int8, IsInteger, "int8"}, 35 Int16: {Int16, IsInteger, "int16"}, 36 Int32: {Int32, IsInteger, "int32"}, 37 Int64: {Int64, IsInteger, "int64"}, 38 Uint: {Uint, IsInteger | IsUnsigned, "uint"}, 39 Uint8: {Uint8, IsInteger | IsUnsigned, "uint8"}, 40 Uint16: {Uint16, IsInteger | IsUnsigned, "uint16"}, 41 Uint32: {Uint32, IsInteger | IsUnsigned, "uint32"}, 42 Uint64: {Uint64, IsInteger | IsUnsigned, "uint64"}, 43 Uintptr: {Uintptr, IsInteger | IsUnsigned, "uintptr"}, 44 Float32: {Float32, IsFloat, "float32"}, 45 Float64: {Float64, IsFloat, "float64"}, 46 Complex64: {Complex64, IsComplex, "complex64"}, 47 Complex128: {Complex128, IsComplex, "complex128"}, 48 String: {String, IsString, "string"}, 49 UnsafePointer: {UnsafePointer, 0, "Pointer"}, 50 51 UntypedBool: {UntypedBool, IsBoolean | IsUntyped, "untyped bool"}, 52 UntypedInt: {UntypedInt, IsInteger | IsUntyped, "untyped int"}, 53 UntypedRune: {UntypedRune, IsInteger | IsUntyped, "untyped rune"}, 54 UntypedFloat: {UntypedFloat, IsFloat | IsUntyped, "untyped float"}, 55 UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"}, 56 UntypedString: {UntypedString, IsString | IsUntyped, "untyped string"}, 57 UntypedNil: {UntypedNil, IsUntyped, "untyped nil"}, 58 } 59 60 var aliases = [...]*Basic{ 61 {Byte, IsInteger | IsUnsigned, "byte"}, 62 {Rune, IsInteger, "rune"}, 63 } 64 65 func defPredeclaredTypes() { 66 for _, t := range Typ { 67 def(NewTypeName(token.NoPos, nil, t.name, t)) 68 } 69 for _, t := range aliases { 70 def(NewTypeName(token.NoPos, nil, t.name, t)) 71 } 72 73 // Error has a nil package in its qualified name since it is in no package 74 res := NewVar(token.NoPos, nil, "", Typ[String]) 75 sig := &Signature{results: NewTuple(res)} 76 err := NewFunc(token.NoPos, nil, "Error", sig) 77 typ := &Named{underlying: NewInterface([]*Func{err}, nil).Complete()} 78 sig.recv = NewVar(token.NoPos, nil, "", typ) 79 def(NewTypeName(token.NoPos, nil, "error", typ)) 80 } 81 82 var predeclaredConsts = [...]struct { 83 name string 84 kind BasicKind 85 val constant.Value 86 }{ 87 {"true", UntypedBool, constant.MakeBool(true)}, 88 {"false", UntypedBool, constant.MakeBool(false)}, 89 {"iota", UntypedInt, constant.MakeInt64(0)}, 90 } 91 92 func defPredeclaredConsts() { 93 for _, c := range predeclaredConsts { 94 def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val)) 95 } 96 } 97 98 func defPredeclaredNil() { 99 def(&Nil{object{name: "nil", typ: Typ[UntypedNil]}}) 100 } 101 102 // A builtinId is the id of a builtin function. 103 type builtinId int 104 105 const ( 106 // universe scope 107 _Append builtinId = iota 108 _Cap 109 _Close 110 _Complex 111 _Copy 112 _Delete 113 _Imag 114 _Len 115 _Make 116 _New 117 _Panic 118 _Print 119 _Println 120 _Real 121 _Recover 122 123 // package unsafe 124 _Alignof 125 _Offsetof 126 _Sizeof 127 128 // testing support 129 _Assert 130 _Trace 131 ) 132 133 var predeclaredFuncs = [...]struct { 134 name string 135 nargs int 136 variadic bool 137 kind exprKind 138 }{ 139 _Append: {"append", 1, true, expression}, 140 _Cap: {"cap", 1, false, expression}, 141 _Close: {"close", 1, false, statement}, 142 _Complex: {"complex", 2, false, expression}, 143 _Copy: {"copy", 2, false, statement}, 144 _Delete: {"delete", 2, false, statement}, 145 _Imag: {"imag", 1, false, expression}, 146 _Len: {"len", 1, false, expression}, 147 _Make: {"make", 1, true, expression}, 148 _New: {"new", 1, false, expression}, 149 _Panic: {"panic", 1, false, statement}, 150 _Print: {"print", 0, true, statement}, 151 _Println: {"println", 0, true, statement}, 152 _Real: {"real", 1, false, expression}, 153 _Recover: {"recover", 0, false, statement}, 154 155 _Alignof: {"Alignof", 1, false, expression}, 156 _Offsetof: {"Offsetof", 1, false, expression}, 157 _Sizeof: {"Sizeof", 1, false, expression}, 158 159 _Assert: {"assert", 1, false, statement}, 160 _Trace: {"trace", 0, true, statement}, 161 } 162 163 func defPredeclaredFuncs() { 164 for i := range predeclaredFuncs { 165 id := builtinId(i) 166 if id == _Assert || id == _Trace { 167 continue // only define these in testing environment 168 } 169 def(newBuiltin(id)) 170 } 171 } 172 173 // DefPredeclaredTestFuncs defines the assert and trace built-ins. 174 // These built-ins are intended for debugging and testing of this 175 // package only. 176 func DefPredeclaredTestFuncs() { 177 if Universe.Lookup("assert") != nil { 178 return // already defined 179 } 180 def(newBuiltin(_Assert)) 181 def(newBuiltin(_Trace)) 182 } 183 184 func init() { 185 Universe = NewScope(nil, token.NoPos, token.NoPos, "universe") 186 Unsafe = NewPackage("unsafe", "unsafe") 187 Unsafe.complete = true 188 189 defPredeclaredTypes() 190 defPredeclaredConsts() 191 defPredeclaredNil() 192 defPredeclaredFuncs() 193 194 universeIota = Universe.Lookup("iota").(*Const) 195 universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic) 196 universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic) 197 } 198 199 // Objects with names containing blanks are internal and not entered into 200 // a scope. Objects with exported names are inserted in the unsafe package 201 // scope; other objects are inserted in the universe scope. 202 // 203 func def(obj Object) { 204 name := obj.Name() 205 if strings.Contains(name, " ") { 206 return // nothing to do 207 } 208 // fix Obj link for named types 209 if typ, ok := obj.Type().(*Named); ok { 210 typ.obj = obj.(*TypeName) 211 } 212 // exported identifiers go into package unsafe 213 scope := Universe 214 if obj.Exported() { 215 scope = Unsafe.scope 216 // set Pkg field 217 switch obj := obj.(type) { 218 case *TypeName: 219 obj.pkg = Unsafe 220 case *Builtin: 221 obj.pkg = Unsafe 222 default: 223 unreachable() 224 } 225 } 226 if scope.Insert(obj) != nil { 227 panic("internal error: double declaration") 228 } 229 }