github.com/bir3/gocompiler@v0.3.205/src/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 "github.com/bir3/gocompiler/src/go/constant" 11 "github.com/bir3/gocompiler/src/go/token" 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 universeByte Type // uint8 alias, but has name "byte" 26 universeRune Type // int32 alias, but has name "rune" 27 universeAny Object 28 universeError Type 29 universeComparable Object 30 ) 31 32 // Typ contains the predeclared *Basic types indexed by their 33 // corresponding BasicKind. 34 // 35 // The *Basic type for Typ[Byte] will have the name "uint8". 36 // Use Universe.Lookup("byte").Type() to obtain the specific 37 // alias basic type named "byte" (and analogous for "rune"). 38 var Typ = []*Basic{ 39 Invalid: {Invalid, 0, "invalid type"}, 40 41 Bool: {Bool, IsBoolean, "bool"}, 42 Int: {Int, IsInteger, "int"}, 43 Int8: {Int8, IsInteger, "int8"}, 44 Int16: {Int16, IsInteger, "int16"}, 45 Int32: {Int32, IsInteger, "int32"}, 46 Int64: {Int64, IsInteger, "int64"}, 47 Uint: {Uint, IsInteger | IsUnsigned, "uint"}, 48 Uint8: {Uint8, IsInteger | IsUnsigned, "uint8"}, 49 Uint16: {Uint16, IsInteger | IsUnsigned, "uint16"}, 50 Uint32: {Uint32, IsInteger | IsUnsigned, "uint32"}, 51 Uint64: {Uint64, IsInteger | IsUnsigned, "uint64"}, 52 Uintptr: {Uintptr, IsInteger | IsUnsigned, "uintptr"}, 53 Float32: {Float32, IsFloat, "float32"}, 54 Float64: {Float64, IsFloat, "float64"}, 55 Complex64: {Complex64, IsComplex, "complex64"}, 56 Complex128: {Complex128, IsComplex, "complex128"}, 57 String: {String, IsString, "string"}, 58 UnsafePointer: {UnsafePointer, 0, "Pointer"}, 59 60 UntypedBool: {UntypedBool, IsBoolean | IsUntyped, "untyped bool"}, 61 UntypedInt: {UntypedInt, IsInteger | IsUntyped, "untyped int"}, 62 UntypedRune: {UntypedRune, IsInteger | IsUntyped, "untyped rune"}, 63 UntypedFloat: {UntypedFloat, IsFloat | IsUntyped, "untyped float"}, 64 UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"}, 65 UntypedString: {UntypedString, IsString | IsUntyped, "untyped string"}, 66 UntypedNil: {UntypedNil, IsUntyped, "untyped nil"}, 67 } 68 69 var aliases = [...]*Basic{ 70 {Byte, IsInteger | IsUnsigned, "byte"}, 71 {Rune, IsInteger, "rune"}, 72 } 73 74 func defPredeclaredTypes() { 75 for _, t := range Typ { 76 def(NewTypeName(token.NoPos, nil, t.name, t)) 77 } 78 for _, t := range aliases { 79 def(NewTypeName(token.NoPos, nil, t.name, t)) 80 } 81 82 // type any = interface{} 83 // Note: don't use &emptyInterface for the type of any. Using a unique 84 // pointer allows us to detect any and format it as "any" rather than 85 // interface{}, which clarifies user-facing error messages significantly. 86 def(NewTypeName(token.NoPos, nil, "any", &Interface{complete: true, tset: &topTypeSet})) 87 88 // type error interface{ Error() string } 89 { 90 obj := NewTypeName(token.NoPos, nil, "error", nil) 91 obj.setColor(black) 92 typ := NewNamed(obj, nil, nil) 93 94 // error.Error() string 95 recv := NewVar(token.NoPos, nil, "", typ) 96 res := NewVar(token.NoPos, nil, "", Typ[String]) 97 sig := NewSignatureType(recv, nil, nil, nil, NewTuple(res), false) 98 err := NewFunc(token.NoPos, nil, "Error", sig) 99 100 // interface{ Error() string } 101 ityp := &Interface{methods: []*Func{err}, complete: true} 102 computeInterfaceTypeSet(nil, token.NoPos, ityp) // prevent races due to lazy computation of tset 103 104 typ.SetUnderlying(ityp) 105 def(obj) 106 } 107 108 // type comparable interface{} // marked as comparable 109 { 110 obj := NewTypeName(token.NoPos, nil, "comparable", nil) 111 obj.setColor(black) 112 typ := NewNamed(obj, nil, nil) 113 114 // interface{} // marked as comparable 115 ityp := &Interface{complete: true, tset: &_TypeSet{nil, allTermlist, true}} 116 117 typ.SetUnderlying(ityp) 118 def(obj) 119 } 120 } 121 122 var predeclaredConsts = [...]struct { 123 name string 124 kind BasicKind 125 val constant.Value 126 }{ 127 {"true", UntypedBool, constant.MakeBool(true)}, 128 {"false", UntypedBool, constant.MakeBool(false)}, 129 {"iota", UntypedInt, constant.MakeInt64(0)}, 130 } 131 132 func defPredeclaredConsts() { 133 for _, c := range predeclaredConsts { 134 def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val)) 135 } 136 } 137 138 func defPredeclaredNil() { 139 def(&Nil{object{name: "nil", typ: Typ[UntypedNil], color_: black}}) 140 } 141 142 // A builtinId is the id of a builtin function. 143 type builtinId int 144 145 const ( 146 // universe scope 147 _Append builtinId = iota 148 _Cap 149 _Clear 150 _Close 151 _Complex 152 _Copy 153 _Delete 154 _Imag 155 _Len 156 _Make 157 _New 158 _Panic 159 _Print 160 _Println 161 _Real 162 _Recover 163 164 // package unsafe 165 _Add 166 _Alignof 167 _Offsetof 168 _Sizeof 169 _Slice 170 _SliceData 171 _String 172 _StringData 173 174 // testing support 175 _Assert 176 _Trace 177 ) 178 179 var predeclaredFuncs = [...]struct { 180 name string 181 nargs int 182 variadic bool 183 kind exprKind 184 }{ 185 _Append: {"append", 1, true, expression}, 186 _Cap: {"cap", 1, false, expression}, 187 _Clear: {"clear", 1, false, statement}, 188 _Close: {"close", 1, false, statement}, 189 _Complex: {"complex", 2, false, expression}, 190 _Copy: {"copy", 2, false, statement}, 191 _Delete: {"delete", 2, false, statement}, 192 _Imag: {"imag", 1, false, expression}, 193 _Len: {"len", 1, false, expression}, 194 _Make: {"make", 1, true, expression}, 195 _New: {"new", 1, false, expression}, 196 _Panic: {"panic", 1, false, statement}, 197 _Print: {"print", 0, true, statement}, 198 _Println: {"println", 0, true, statement}, 199 _Real: {"real", 1, false, expression}, 200 _Recover: {"recover", 0, false, statement}, 201 202 _Add: {"Add", 2, false, expression}, 203 _Alignof: {"Alignof", 1, false, expression}, 204 _Offsetof: {"Offsetof", 1, false, expression}, 205 _Sizeof: {"Sizeof", 1, false, expression}, 206 _Slice: {"Slice", 2, false, expression}, 207 _SliceData: {"SliceData", 1, false, expression}, 208 _String: {"String", 2, false, expression}, 209 _StringData: {"StringData", 1, false, expression}, 210 211 _Assert: {"assert", 1, false, statement}, 212 _Trace: {"trace", 0, true, statement}, 213 } 214 215 func defPredeclaredFuncs() { 216 for i := range predeclaredFuncs { 217 id := builtinId(i) 218 if id == _Assert || id == _Trace { 219 continue // only define these in testing environment 220 } 221 def(newBuiltin(id)) 222 } 223 } 224 225 // DefPredeclaredTestFuncs defines the assert and trace built-ins. 226 // These built-ins are intended for debugging and testing of this 227 // package only. 228 func DefPredeclaredTestFuncs() { 229 if Universe.Lookup("assert") != nil { 230 return // already defined 231 } 232 def(newBuiltin(_Assert)) 233 def(newBuiltin(_Trace)) 234 } 235 236 func init() { 237 Universe = NewScope(nil, token.NoPos, token.NoPos, "universe") 238 Unsafe = NewPackage("unsafe", "unsafe") 239 Unsafe.complete = true 240 241 defPredeclaredTypes() 242 defPredeclaredConsts() 243 defPredeclaredNil() 244 defPredeclaredFuncs() 245 246 universeIota = Universe.Lookup("iota") 247 universeByte = Universe.Lookup("byte").Type() 248 universeRune = Universe.Lookup("rune").Type() 249 universeAny = Universe.Lookup("any") 250 universeError = Universe.Lookup("error").Type() 251 universeComparable = Universe.Lookup("comparable") 252 } 253 254 // Objects with names containing blanks are internal and not entered into 255 // a scope. Objects with exported names are inserted in the unsafe package 256 // scope; other objects are inserted in the universe scope. 257 func def(obj Object) { 258 assert(obj.color() == black) 259 name := obj.Name() 260 if strings.Contains(name, " ") { 261 return // nothing to do 262 } 263 // fix Obj link for named types 264 if typ, _ := obj.Type().(*Named); typ != nil { 265 typ.obj = obj.(*TypeName) 266 } 267 // exported identifiers go into package unsafe 268 scope := Universe 269 if obj.Exported() { 270 scope = Unsafe.scope 271 // set Pkg field 272 switch obj := obj.(type) { 273 case *TypeName: 274 obj.pkg = Unsafe 275 case *Builtin: 276 obj.pkg = Unsafe 277 default: 278 unreachable() 279 } 280 } 281 if scope.Insert(obj) != nil { 282 panic("double declaration of predeclared identifier") 283 } 284 }