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  }