github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/gc/bexport.go (about) 1 // Copyright 2015 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 gc 6 7 import ( 8 "github.com/gagliardetto/golang-go/cmd/compile/internal/types" 9 ) 10 11 type exporter struct { 12 marked map[*types.Type]bool // types already seen by markType 13 } 14 15 // markType recursively visits types reachable from t to identify 16 // functions whose inline bodies may be needed. 17 func (p *exporter) markType(t *types.Type) { 18 if p.marked[t] { 19 return 20 } 21 p.marked[t] = true 22 23 // If this is a named type, mark all of its associated 24 // methods. Skip interface types because t.Methods contains 25 // only their unexpanded method set (i.e., exclusive of 26 // interface embeddings), and the switch statement below 27 // handles their full method set. 28 if t.Sym != nil && t.Etype != TINTER { 29 for _, m := range t.Methods().Slice() { 30 if types.IsExported(m.Sym.Name) { 31 p.markType(m.Type) 32 } 33 } 34 } 35 36 // Recursively mark any types that can be produced given a 37 // value of type t: dereferencing a pointer; indexing or 38 // iterating over an array, slice, or map; receiving from a 39 // channel; accessing a struct field or interface method; or 40 // calling a function. 41 // 42 // Notably, we don't mark function parameter types, because 43 // the user already needs some way to construct values of 44 // those types. 45 switch t.Etype { 46 case TPTR, TARRAY, TSLICE: 47 p.markType(t.Elem()) 48 49 case TCHAN: 50 if t.ChanDir().CanRecv() { 51 p.markType(t.Elem()) 52 } 53 54 case TMAP: 55 p.markType(t.Key()) 56 p.markType(t.Elem()) 57 58 case TSTRUCT: 59 for _, f := range t.FieldSlice() { 60 if types.IsExported(f.Sym.Name) || f.Embedded != 0 { 61 p.markType(f.Type) 62 } 63 } 64 65 case TFUNC: 66 // If t is the type of a function or method, then 67 // t.Nname() is its ONAME. Mark its inline body and 68 // any recursively called functions for export. 69 inlFlood(asNode(t.Nname())) 70 71 for _, f := range t.Results().FieldSlice() { 72 p.markType(f.Type) 73 } 74 75 case TINTER: 76 for _, f := range t.FieldSlice() { 77 if types.IsExported(f.Sym.Name) { 78 p.markType(f.Type) 79 } 80 } 81 } 82 } 83 84 // deltaNewFile is a magic line delta offset indicating a new file. 85 // We use -64 because it is rare; see issue 20080 and CL 41619. 86 // -64 is the smallest int that fits in a single byte as a varint. 87 const deltaNewFile = -64 88 89 // ---------------------------------------------------------------------------- 90 // Export format 91 92 // Tags. Must be < 0. 93 const ( 94 // Objects 95 packageTag = -(iota + 1) 96 constTag 97 typeTag 98 varTag 99 funcTag 100 endTag 101 102 // Types 103 namedTag 104 arrayTag 105 sliceTag 106 dddTag 107 structTag 108 pointerTag 109 signatureTag 110 interfaceTag 111 mapTag 112 chanTag 113 114 // Values 115 falseTag 116 trueTag 117 int64Tag 118 floatTag 119 fractionTag // not used by gc 120 complexTag 121 stringTag 122 nilTag 123 unknownTag // not used by gc (only appears in packages with errors) 124 125 // Type aliases 126 aliasTag 127 ) 128 129 // untype returns the "pseudo" untyped type for a Ctype (import/export use only). 130 // (we can't use a pre-initialized array because we must be sure all types are 131 // set up) 132 func untype(ctype Ctype) *types.Type { 133 switch ctype { 134 case CTINT: 135 return types.Idealint 136 case CTRUNE: 137 return types.Idealrune 138 case CTFLT: 139 return types.Idealfloat 140 case CTCPLX: 141 return types.Idealcomplex 142 case CTSTR: 143 return types.Idealstring 144 case CTBOOL: 145 return types.Idealbool 146 case CTNIL: 147 return types.Types[TNIL] 148 } 149 Fatalf("exporter: unknown Ctype") 150 return nil 151 } 152 153 var predecl []*types.Type // initialized lazily 154 155 func predeclared() []*types.Type { 156 if predecl == nil { 157 // initialize lazily to be sure that all 158 // elements have been initialized before 159 predecl = []*types.Type{ 160 // basic types 161 types.Types[TBOOL], 162 types.Types[TINT], 163 types.Types[TINT8], 164 types.Types[TINT16], 165 types.Types[TINT32], 166 types.Types[TINT64], 167 types.Types[TUINT], 168 types.Types[TUINT8], 169 types.Types[TUINT16], 170 types.Types[TUINT32], 171 types.Types[TUINT64], 172 types.Types[TUINTPTR], 173 types.Types[TFLOAT32], 174 types.Types[TFLOAT64], 175 types.Types[TCOMPLEX64], 176 types.Types[TCOMPLEX128], 177 types.Types[TSTRING], 178 179 // basic type aliases 180 types.Bytetype, 181 types.Runetype, 182 183 // error 184 types.Errortype, 185 186 // untyped types 187 untype(CTBOOL), 188 untype(CTINT), 189 untype(CTRUNE), 190 untype(CTFLT), 191 untype(CTCPLX), 192 untype(CTSTR), 193 untype(CTNIL), 194 195 // package unsafe 196 types.Types[TUNSAFEPTR], 197 198 // invalid type (package contains errors) 199 types.Types[Txxx], 200 201 // any type, for builtin export data 202 types.Types[TANY], 203 } 204 } 205 return predecl 206 }