github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/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 "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, TCHAN: 47 // TODO(mdempsky): Skip marking element type for 48 // send-only channels? 49 p.markType(t.Elem()) 50 51 case TMAP: 52 p.markType(t.Key()) 53 p.markType(t.Elem()) 54 55 case TSTRUCT: 56 for _, f := range t.FieldSlice() { 57 if types.IsExported(f.Sym.Name) || f.Embedded != 0 { 58 p.markType(f.Type) 59 } 60 } 61 62 case TFUNC: 63 // If t is the type of a function or method, then 64 // t.Nname() is its ONAME. Mark its inline body and 65 // any recursively called functions for export. 66 inlFlood(asNode(t.Nname())) 67 68 for _, f := range t.Results().FieldSlice() { 69 p.markType(f.Type) 70 } 71 72 case TINTER: 73 for _, f := range t.FieldSlice() { 74 if types.IsExported(f.Sym.Name) { 75 p.markType(f.Type) 76 } 77 } 78 } 79 } 80 81 // deltaNewFile is a magic line delta offset indicating a new file. 82 // We use -64 because it is rare; see issue 20080 and CL 41619. 83 // -64 is the smallest int that fits in a single byte as a varint. 84 const deltaNewFile = -64 85 86 // ---------------------------------------------------------------------------- 87 // Export format 88 89 // Tags. Must be < 0. 90 const ( 91 // Objects 92 packageTag = -(iota + 1) 93 constTag 94 typeTag 95 varTag 96 funcTag 97 endTag 98 99 // Types 100 namedTag 101 arrayTag 102 sliceTag 103 dddTag 104 structTag 105 pointerTag 106 signatureTag 107 interfaceTag 108 mapTag 109 chanTag 110 111 // Values 112 falseTag 113 trueTag 114 int64Tag 115 floatTag 116 fractionTag // not used by gc 117 complexTag 118 stringTag 119 nilTag 120 unknownTag // not used by gc (only appears in packages with errors) 121 122 // Type aliases 123 aliasTag 124 ) 125 126 // untype returns the "pseudo" untyped type for a Ctype (import/export use only). 127 // (we can't use an pre-initialized array because we must be sure all types are 128 // set up) 129 func untype(ctype Ctype) *types.Type { 130 switch ctype { 131 case CTINT: 132 return types.Idealint 133 case CTRUNE: 134 return types.Idealrune 135 case CTFLT: 136 return types.Idealfloat 137 case CTCPLX: 138 return types.Idealcomplex 139 case CTSTR: 140 return types.Idealstring 141 case CTBOOL: 142 return types.Idealbool 143 case CTNIL: 144 return types.Types[TNIL] 145 } 146 Fatalf("exporter: unknown Ctype") 147 return nil 148 } 149 150 var predecl []*types.Type // initialized lazily 151 152 func predeclared() []*types.Type { 153 if predecl == nil { 154 // initialize lazily to be sure that all 155 // elements have been initialized before 156 predecl = []*types.Type{ 157 // basic types 158 types.Types[TBOOL], 159 types.Types[TINT], 160 types.Types[TINT8], 161 types.Types[TINT16], 162 types.Types[TINT32], 163 types.Types[TINT64], 164 types.Types[TUINT], 165 types.Types[TUINT8], 166 types.Types[TUINT16], 167 types.Types[TUINT32], 168 types.Types[TUINT64], 169 types.Types[TUINTPTR], 170 types.Types[TFLOAT32], 171 types.Types[TFLOAT64], 172 types.Types[TCOMPLEX64], 173 types.Types[TCOMPLEX128], 174 types.Types[TSTRING], 175 176 // basic type aliases 177 types.Bytetype, 178 types.Runetype, 179 180 // error 181 types.Errortype, 182 183 // untyped types 184 untype(CTBOOL), 185 untype(CTINT), 186 untype(CTRUNE), 187 untype(CTFLT), 188 untype(CTCPLX), 189 untype(CTSTR), 190 untype(CTNIL), 191 192 // package unsafe 193 types.Types[TUNSAFEPTR], 194 195 // invalid type (package contains errors) 196 types.Types[Txxx], 197 198 // any type, for builtin export data 199 types.Types[TANY], 200 } 201 } 202 return predecl 203 }