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  }