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  }