github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/gc/export.go (about) 1 // Copyright 2009 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 "github.com/gagliardetto/golang-go/cmd/internal/bio" 10 "github.com/gagliardetto/golang-go/cmd/internal/src" 11 "fmt" 12 ) 13 14 var ( 15 Debug_export int // if set, print debugging information about export data 16 ) 17 18 func exportf(bout *bio.Writer, format string, args ...interface{}) { 19 fmt.Fprintf(bout, format, args...) 20 if Debug_export != 0 { 21 fmt.Printf(format, args...) 22 } 23 } 24 25 var asmlist []*Node 26 27 // exportsym marks n for export (or reexport). 28 func exportsym(n *Node) { 29 if n.Sym.OnExportList() { 30 return 31 } 32 n.Sym.SetOnExportList(true) 33 34 if Debug['E'] != 0 { 35 fmt.Printf("export symbol %v\n", n.Sym) 36 } 37 38 exportlist = append(exportlist, n) 39 } 40 41 func initname(s string) bool { 42 return s == "init" 43 } 44 45 func autoexport(n *Node, ctxt Class) { 46 if n.Sym.Pkg != localpkg { 47 return 48 } 49 if (ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN { 50 return 51 } 52 if n.Type != nil && n.Type.IsKind(TFUNC) && n.IsMethod() { 53 return 54 } 55 56 if types.IsExported(n.Sym.Name) || initname(n.Sym.Name) { 57 exportsym(n) 58 } 59 if asmhdr != "" && !n.Sym.Asm() { 60 n.Sym.SetAsm(true) 61 asmlist = append(asmlist, n) 62 } 63 } 64 65 func dumpexport(bout *bio.Writer) { 66 // The linker also looks for the $$ marker - use char after $$ to distinguish format. 67 exportf(bout, "\n$$B\n") // indicate binary export format 68 off := bout.Offset() 69 iexport(bout.Writer) 70 size := bout.Offset() - off 71 exportf(bout, "\n$$\n") 72 73 if Debug_export != 0 { 74 fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", myimportpath, size) 75 } 76 } 77 78 func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node { 79 n := asNode(s.PkgDef()) 80 if n == nil { 81 // iimport should have created a stub ONONAME 82 // declaration for all imported symbols. The exception 83 // is declarations for Runtimepkg, which are populated 84 // by loadsys instead. 85 if s.Pkg != Runtimepkg { 86 Fatalf("missing ONONAME for %v\n", s) 87 } 88 89 n = dclname(s) 90 s.SetPkgDef(asTypesNode(n)) 91 s.Importdef = ipkg 92 } 93 if n.Op != ONONAME && n.Op != op { 94 redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path)) 95 } 96 return n 97 } 98 99 // pkgtype returns the named type declared by symbol s. 100 // If no such type has been declared yet, a forward declaration is returned. 101 // ipkg is the package being imported 102 func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type { 103 n := importsym(ipkg, s, OTYPE) 104 if n.Op != OTYPE { 105 t := types.New(TFORW) 106 t.Sym = s 107 t.Nod = asTypesNode(n) 108 109 n.Op = OTYPE 110 n.Pos = pos 111 n.Type = t 112 n.SetClass(PEXTERN) 113 } 114 115 t := n.Type 116 if t == nil { 117 Fatalf("importtype %v", s) 118 } 119 return t 120 } 121 122 // importobj declares symbol s as an imported object representable by op. 123 // ipkg is the package being imported 124 func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t *types.Type) *Node { 125 n := importsym(ipkg, s, op) 126 if n.Op != ONONAME { 127 if n.Op == op && (n.Class() != ctxt || !types.Identical(n.Type, t)) { 128 redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path)) 129 } 130 return nil 131 } 132 133 n.Op = op 134 n.Pos = pos 135 n.SetClass(ctxt) 136 if ctxt == PFUNC { 137 n.Sym.SetFunc(true) 138 } 139 n.Type = t 140 return n 141 } 142 143 // importconst declares symbol s as an imported constant with type t and value val. 144 // ipkg is the package being imported 145 func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val Val) { 146 n := importobj(ipkg, pos, s, OLITERAL, PEXTERN, t) 147 if n == nil { // TODO: Check that value matches. 148 return 149 } 150 151 n.SetVal(val) 152 153 if Debug['E'] != 0 { 154 fmt.Printf("import const %v %L = %v\n", s, t, val) 155 } 156 } 157 158 // importfunc declares symbol s as an imported function with type t. 159 // ipkg is the package being imported 160 func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) { 161 n := importobj(ipkg, pos, s, ONAME, PFUNC, t) 162 if n == nil { 163 return 164 } 165 166 n.Func = new(Func) 167 t.SetNname(asTypesNode(n)) 168 169 if Debug['E'] != 0 { 170 fmt.Printf("import func %v%S\n", s, t) 171 } 172 } 173 174 // importvar declares symbol s as an imported variable with type t. 175 // ipkg is the package being imported 176 func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) { 177 n := importobj(ipkg, pos, s, ONAME, PEXTERN, t) 178 if n == nil { 179 return 180 } 181 182 if Debug['E'] != 0 { 183 fmt.Printf("import var %v %L\n", s, t) 184 } 185 } 186 187 // importalias declares symbol s as an imported type alias with type t. 188 // ipkg is the package being imported 189 func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) { 190 n := importobj(ipkg, pos, s, OTYPE, PEXTERN, t) 191 if n == nil { 192 return 193 } 194 195 if Debug['E'] != 0 { 196 fmt.Printf("import type %v = %L\n", s, t) 197 } 198 } 199 200 func dumpasmhdr() { 201 b, err := bio.Create(asmhdr) 202 if err != nil { 203 Fatalf("%v", err) 204 } 205 fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", localpkg.Name) 206 for _, n := range asmlist { 207 if n.Sym.IsBlank() { 208 continue 209 } 210 switch n.Op { 211 case OLITERAL: 212 t := n.Val().Ctype() 213 if t == CTFLT || t == CTCPLX { 214 break 215 } 216 fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym.Name, n.Val()) 217 218 case OTYPE: 219 t := n.Type 220 if !t.IsStruct() || t.StructType().Map != nil || t.IsFuncArgStruct() { 221 break 222 } 223 fmt.Fprintf(b, "#define %s__size %d\n", n.Sym.Name, int(t.Width)) 224 for _, f := range t.Fields().Slice() { 225 if !f.Sym.IsBlank() { 226 fmt.Fprintf(b, "#define %s_%s %d\n", n.Sym.Name, f.Sym.Name, int(f.Offset)) 227 } 228 } 229 } 230 } 231 232 b.Close() 233 }