...
Run Format

Source file src/cmd/compile/internal/types/type.go

Documentation: cmd/compile/internal/types

     1  // Copyright 2017 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 types
     6  
     7  import (
     8  	"cmd/internal/obj"
     9  	"cmd/internal/src"
    10  	"fmt"
    11  )
    12  
    13  // Dummy Node so we can refer to *Node without actually
    14  // having a gc.Node. Necessary to break import cycles.
    15  // TODO(gri) try to eliminate soon
    16  type Node struct{ _ int }
    17  
    18  //go:generate stringer -type EType -trimprefix T
    19  
    20  // EType describes a kind of type.
    21  type EType uint8
    22  
    23  const (
    24  	Txxx EType = iota
    25  
    26  	TINT8
    27  	TUINT8
    28  	TINT16
    29  	TUINT16
    30  	TINT32
    31  	TUINT32
    32  	TINT64
    33  	TUINT64
    34  	TINT
    35  	TUINT
    36  	TUINTPTR
    37  
    38  	TCOMPLEX64
    39  	TCOMPLEX128
    40  
    41  	TFLOAT32
    42  	TFLOAT64
    43  
    44  	TBOOL
    45  
    46  	TPTR
    47  	TFUNC
    48  	TSLICE
    49  	TARRAY
    50  	TSTRUCT
    51  	TCHAN
    52  	TMAP
    53  	TINTER
    54  	TFORW
    55  	TANY
    56  	TSTRING
    57  	TUNSAFEPTR
    58  
    59  	// pseudo-types for literals
    60  	TIDEAL
    61  	TNIL
    62  	TBLANK
    63  
    64  	// pseudo-types for frame layout
    65  	TFUNCARGS
    66  	TCHANARGS
    67  
    68  	// pseudo-types for import/export
    69  	TDDDFIELD // wrapper: contained type is a ... field
    70  
    71  	// SSA backend types
    72  	TSSA   // internal types used by SSA backend (flags, memory, etc.)
    73  	TTUPLE // a pair of types, used by SSA backend
    74  
    75  	NTYPE
    76  )
    77  
    78  // ChanDir is whether a channel can send, receive, or both.
    79  type ChanDir uint8
    80  
    81  func (c ChanDir) CanRecv() bool { return c&Crecv != 0 }
    82  func (c ChanDir) CanSend() bool { return c&Csend != 0 }
    83  
    84  const (
    85  	// types of channel
    86  	// must match ../../../../reflect/type.go:/ChanDir
    87  	Crecv ChanDir = 1 << 0
    88  	Csend ChanDir = 1 << 1
    89  	Cboth ChanDir = Crecv | Csend
    90  )
    91  
    92  // Types stores pointers to predeclared named types.
    93  //
    94  // It also stores pointers to several special types:
    95  //   - Types[TANY] is the placeholder "any" type recognized by substArgTypes.
    96  //   - Types[TBLANK] represents the blank variable's type.
    97  //   - Types[TIDEAL] represents untyped numeric constants.
    98  //   - Types[TNIL] represents the predeclared "nil" value's type.
    99  //   - Types[TUNSAFEPTR] is package unsafe's Pointer type.
   100  var Types [NTYPE]*Type
   101  
   102  var (
   103  	// Predeclared alias types. Kept separate for better error messages.
   104  	Bytetype *Type
   105  	Runetype *Type
   106  
   107  	// Predeclared error interface type.
   108  	Errortype *Type
   109  
   110  	// Types to represent untyped string and boolean constants.
   111  	Idealstring *Type
   112  	Idealbool   *Type
   113  
   114  	// Types to represent untyped numeric constants.
   115  	// Note: Currently these are only used within the binary export
   116  	// data format. The rest of the compiler only uses Types[TIDEAL].
   117  	Idealint     = New(TIDEAL)
   118  	Idealrune    = New(TIDEAL)
   119  	Idealfloat   = New(TIDEAL)
   120  	Idealcomplex = New(TIDEAL)
   121  )
   122  
   123  // A Type represents a Go type.
   124  type Type struct {
   125  	// Extra contains extra etype-specific fields.
   126  	// As an optimization, those etype-specific structs which contain exactly
   127  	// one pointer-shaped field are stored as values rather than pointers when possible.
   128  	//
   129  	// TMAP: *Map
   130  	// TFORW: *Forward
   131  	// TFUNC: *Func
   132  	// TSTRUCT: *Struct
   133  	// TINTER: *Interface
   134  	// TDDDFIELD: DDDField
   135  	// TFUNCARGS: FuncArgs
   136  	// TCHANARGS: ChanArgs
   137  	// TCHAN: *Chan
   138  	// TPTR: Ptr
   139  	// TARRAY: *Array
   140  	// TSLICE: Slice
   141  	Extra interface{}
   142  
   143  	// Width is the width of this Type in bytes.
   144  	Width int64 // valid if Align > 0
   145  
   146  	methods    Fields
   147  	allMethods Fields
   148  
   149  	Nod  *Node // canonical OTYPE node
   150  	Orig *Type // original type (type literal or predefined type)
   151  
   152  	// Cache of composite types, with this type being the element type.
   153  	Cache struct {
   154  		ptr   *Type // *T, or nil
   155  		slice *Type // []T, or nil
   156  	}
   157  
   158  	Sym    *Sym  // symbol containing name, for named types
   159  	Vargen int32 // unique name for OTYPE/ONAME
   160  
   161  	Etype EType // kind of type
   162  	Align uint8 // the required alignment of this type, in bytes (0 means Width and Align have not yet been computed)
   163  
   164  	flags bitset8
   165  }
   166  
   167  const (
   168  	typeNotInHeap  = 1 << iota // type cannot be heap allocated
   169  	typeBroke                  // broken type definition
   170  	typeNoalg                  // suppress hash and eq algorithm generation
   171  	typeDeferwidth             // width computation has been deferred and type is on deferredTypeStack
   172  	typeRecur
   173  )
   174  
   175  func (t *Type) NotInHeap() bool  { return t.flags&typeNotInHeap != 0 }
   176  func (t *Type) Broke() bool      { return t.flags&typeBroke != 0 }
   177  func (t *Type) Noalg() bool      { return t.flags&typeNoalg != 0 }
   178  func (t *Type) Deferwidth() bool { return t.flags&typeDeferwidth != 0 }
   179  func (t *Type) Recur() bool      { return t.flags&typeRecur != 0 }
   180  
   181  func (t *Type) SetNotInHeap(b bool)  { t.flags.set(typeNotInHeap, b) }
   182  func (t *Type) SetBroke(b bool)      { t.flags.set(typeBroke, b) }
   183  func (t *Type) SetNoalg(b bool)      { t.flags.set(typeNoalg, b) }
   184  func (t *Type) SetDeferwidth(b bool) { t.flags.set(typeDeferwidth, b) }
   185  func (t *Type) SetRecur(b bool)      { t.flags.set(typeRecur, b) }
   186  
   187  // Pkg returns the package that t appeared in.
   188  //
   189  // Pkg is only defined for function, struct, and interface types
   190  // (i.e., types with named elements). This information isn't used by
   191  // cmd/compile itself, but we need to track it because it's exposed by
   192  // the go/types API.
   193  func (t *Type) Pkg() *Pkg {
   194  	switch t.Etype {
   195  	case TFUNC:
   196  		return t.Extra.(*Func).pkg
   197  	case TSTRUCT:
   198  		return t.Extra.(*Struct).pkg
   199  	case TINTER:
   200  		return t.Extra.(*Interface).pkg
   201  	default:
   202  		Fatalf("Pkg: unexpected kind: %v", t)
   203  		return nil
   204  	}
   205  }
   206  
   207  // SetPkg sets the package that t appeared in.
   208  func (t *Type) SetPkg(pkg *Pkg) {
   209  	switch t.Etype {
   210  	case TFUNC:
   211  		t.Extra.(*Func).pkg = pkg
   212  	case TSTRUCT:
   213  		t.Extra.(*Struct).pkg = pkg
   214  	case TINTER:
   215  		t.Extra.(*Interface).pkg = pkg
   216  	default:
   217  		Fatalf("Pkg: unexpected kind: %v", t)
   218  	}
   219  }
   220  
   221  // Map contains Type fields specific to maps.
   222  type Map struct {
   223  	Key  *Type // Key type
   224  	Elem *Type // Val (elem) type
   225  
   226  	Bucket *Type // internal struct type representing a hash bucket
   227  	Hmap   *Type // internal struct type representing the Hmap (map header object)
   228  	Hiter  *Type // internal struct type representing hash iterator state
   229  }
   230  
   231  // MapType returns t's extra map-specific fields.
   232  func (t *Type) MapType() *Map {
   233  	t.wantEtype(TMAP)
   234  	return t.Extra.(*Map)
   235  }
   236  
   237  // Forward contains Type fields specific to forward types.
   238  type Forward struct {
   239  	Copyto      []*Node  // where to copy the eventual value to
   240  	Embedlineno src.XPos // first use of this type as an embedded type
   241  }
   242  
   243  // ForwardType returns t's extra forward-type-specific fields.
   244  func (t *Type) ForwardType() *Forward {
   245  	t.wantEtype(TFORW)
   246  	return t.Extra.(*Forward)
   247  }
   248  
   249  // Func contains Type fields specific to func types.
   250  type Func struct {
   251  	Receiver *Type // function receiver
   252  	Results  *Type // function results
   253  	Params   *Type // function params
   254  
   255  	Nname *Node
   256  	pkg   *Pkg
   257  
   258  	// Argwid is the total width of the function receiver, params, and results.
   259  	// It gets calculated via a temporary TFUNCARGS type.
   260  	// Note that TFUNC's Width is Widthptr.
   261  	Argwid int64
   262  
   263  	Outnamed bool
   264  }
   265  
   266  // FuncType returns t's extra func-specific fields.
   267  func (t *Type) FuncType() *Func {
   268  	t.wantEtype(TFUNC)
   269  	return t.Extra.(*Func)
   270  }
   271  
   272  // StructType contains Type fields specific to struct types.
   273  type Struct struct {
   274  	fields Fields
   275  	pkg    *Pkg
   276  
   277  	// Maps have three associated internal structs (see struct MapType).
   278  	// Map links such structs back to their map type.
   279  	Map *Type
   280  
   281  	Funarg Funarg // type of function arguments for arg struct
   282  }
   283  
   284  // Fnstruct records the kind of function argument
   285  type Funarg uint8
   286  
   287  const (
   288  	FunargNone    Funarg = iota
   289  	FunargRcvr           // receiver
   290  	FunargParams         // input parameters
   291  	FunargResults        // output results
   292  )
   293  
   294  // StructType returns t's extra struct-specific fields.
   295  func (t *Type) StructType() *Struct {
   296  	t.wantEtype(TSTRUCT)
   297  	return t.Extra.(*Struct)
   298  }
   299  
   300  // Interface contains Type fields specific to interface types.
   301  type Interface struct {
   302  	Fields Fields
   303  	pkg    *Pkg
   304  }
   305  
   306  // Ptr contains Type fields specific to pointer types.
   307  type Ptr struct {
   308  	Elem *Type // element type
   309  }
   310  
   311  // DDDField contains Type fields specific to TDDDFIELD types.
   312  type DDDField struct {
   313  	T *Type // reference to a slice type for ... args
   314  }
   315  
   316  // ChanArgs contains Type fields specific to TCHANARGS types.
   317  type ChanArgs struct {
   318  	T *Type // reference to a chan type whose elements need a width check
   319  }
   320  
   321  // // FuncArgs contains Type fields specific to TFUNCARGS types.
   322  type FuncArgs struct {
   323  	T *Type // reference to a func type whose elements need a width check
   324  }
   325  
   326  // Chan contains Type fields specific to channel types.
   327  type Chan struct {
   328  	Elem *Type   // element type
   329  	Dir  ChanDir // channel direction
   330  }
   331  
   332  // ChanType returns t's extra channel-specific fields.
   333  func (t *Type) ChanType() *Chan {
   334  	t.wantEtype(TCHAN)
   335  	return t.Extra.(*Chan)
   336  }
   337  
   338  type Tuple struct {
   339  	first  *Type
   340  	second *Type
   341  	// Any tuple with a memory type must put that memory type second.
   342  }
   343  
   344  // Array contains Type fields specific to array types.
   345  type Array struct {
   346  	Elem  *Type // element type
   347  	Bound int64 // number of elements; <0 if unknown yet
   348  }
   349  
   350  // Slice contains Type fields specific to slice types.
   351  type Slice struct {
   352  	Elem *Type // element type
   353  }
   354  
   355  // A Field represents a field in a struct or a method in an interface or
   356  // associated with a named type.
   357  type Field struct {
   358  	flags bitset8
   359  
   360  	Embedded uint8 // embedded field
   361  
   362  	Pos  src.XPos
   363  	Sym  *Sym
   364  	Type *Type  // field type
   365  	Note string // literal string annotation
   366  
   367  	// For fields that represent function parameters, Nname points
   368  	// to the associated ONAME Node.
   369  	Nname *Node
   370  
   371  	// Offset in bytes of this field or method within its enclosing struct
   372  	// or interface Type.
   373  	Offset int64
   374  }
   375  
   376  const (
   377  	fieldIsDDD = 1 << iota // field is ... argument
   378  	fieldBroke             // broken field definition
   379  	fieldNointerface
   380  )
   381  
   382  func (f *Field) IsDDD() bool       { return f.flags&fieldIsDDD != 0 }
   383  func (f *Field) Broke() bool       { return f.flags&fieldBroke != 0 }
   384  func (f *Field) Nointerface() bool { return f.flags&fieldNointerface != 0 }
   385  
   386  func (f *Field) SetIsDDD(b bool)       { f.flags.set(fieldIsDDD, b) }
   387  func (f *Field) SetBroke(b bool)       { f.flags.set(fieldBroke, b) }
   388  func (f *Field) SetNointerface(b bool) { f.flags.set(fieldNointerface, b) }
   389  
   390  // End returns the offset of the first byte immediately after this field.
   391  func (f *Field) End() int64 {
   392  	return f.Offset + f.Type.Width
   393  }
   394  
   395  // Fields is a pointer to a slice of *Field.
   396  // This saves space in Types that do not have fields or methods
   397  // compared to a simple slice of *Field.
   398  type Fields struct {
   399  	s *[]*Field
   400  }
   401  
   402  // Len returns the number of entries in f.
   403  func (f *Fields) Len() int {
   404  	if f.s == nil {
   405  		return 0
   406  	}
   407  	return len(*f.s)
   408  }
   409  
   410  // Slice returns the entries in f as a slice.
   411  // Changes to the slice entries will be reflected in f.
   412  func (f *Fields) Slice() []*Field {
   413  	if f.s == nil {
   414  		return nil
   415  	}
   416  	return *f.s
   417  }
   418  
   419  // Index returns the i'th element of Fields.
   420  // It panics if f does not have at least i+1 elements.
   421  func (f *Fields) Index(i int) *Field {
   422  	return (*f.s)[i]
   423  }
   424  
   425  // Set sets f to a slice.
   426  // This takes ownership of the slice.
   427  func (f *Fields) Set(s []*Field) {
   428  	if len(s) == 0 {
   429  		f.s = nil
   430  	} else {
   431  		// Copy s and take address of t rather than s to avoid
   432  		// allocation in the case where len(s) == 0.
   433  		t := s
   434  		f.s = &t
   435  	}
   436  }
   437  
   438  // Append appends entries to f.
   439  func (f *Fields) Append(s ...*Field) {
   440  	if f.s == nil {
   441  		f.s = new([]*Field)
   442  	}
   443  	*f.s = append(*f.s, s...)
   444  }
   445  
   446  // New returns a new Type of the specified kind.
   447  func New(et EType) *Type {
   448  	t := &Type{
   449  		Etype: et,
   450  		Width: BADWIDTH,
   451  	}
   452  	t.Orig = t
   453  	// TODO(josharian): lazily initialize some of these?
   454  	switch t.Etype {
   455  	case TMAP:
   456  		t.Extra = new(Map)
   457  	case TFORW:
   458  		t.Extra = new(Forward)
   459  	case TFUNC:
   460  		t.Extra = new(Func)
   461  	case TSTRUCT:
   462  		t.Extra = new(Struct)
   463  	case TINTER:
   464  		t.Extra = new(Interface)
   465  	case TPTR:
   466  		t.Extra = Ptr{}
   467  	case TCHANARGS:
   468  		t.Extra = ChanArgs{}
   469  	case TFUNCARGS:
   470  		t.Extra = FuncArgs{}
   471  	case TDDDFIELD:
   472  		t.Extra = DDDField{}
   473  	case TCHAN:
   474  		t.Extra = new(Chan)
   475  	case TTUPLE:
   476  		t.Extra = new(Tuple)
   477  	}
   478  	return t
   479  }
   480  
   481  // NewArray returns a new fixed-length array Type.
   482  func NewArray(elem *Type, bound int64) *Type {
   483  	if bound < 0 {
   484  		Fatalf("NewArray: invalid bound %v", bound)
   485  	}
   486  	t := New(TARRAY)
   487  	t.Extra = &Array{Elem: elem, Bound: bound}
   488  	t.SetNotInHeap(elem.NotInHeap())
   489  	return t
   490  }
   491  
   492  // NewSlice returns the slice Type with element type elem.
   493  func NewSlice(elem *Type) *Type {
   494  	if t := elem.Cache.slice; t != nil {
   495  		if t.Elem() != elem {
   496  			Fatalf("elem mismatch")
   497  		}
   498  		return t
   499  	}
   500  
   501  	t := New(TSLICE)
   502  	t.Extra = Slice{Elem: elem}
   503  	elem.Cache.slice = t
   504  	return t
   505  }
   506  
   507  // NewDDDArray returns a new [...]T array Type.
   508  func NewDDDArray(elem *Type) *Type {
   509  	t := New(TARRAY)
   510  	t.Extra = &Array{Elem: elem, Bound: -1}
   511  	t.SetNotInHeap(elem.NotInHeap())
   512  	return t
   513  }
   514  
   515  // NewChan returns a new chan Type with direction dir.
   516  func NewChan(elem *Type, dir ChanDir) *Type {
   517  	t := New(TCHAN)
   518  	ct := t.ChanType()
   519  	ct.Elem = elem
   520  	ct.Dir = dir
   521  	return t
   522  }
   523  
   524  func NewTuple(t1, t2 *Type) *Type {
   525  	t := New(TTUPLE)
   526  	t.Extra.(*Tuple).first = t1
   527  	t.Extra.(*Tuple).second = t2
   528  	return t
   529  }
   530  
   531  func newSSA(name string) *Type {
   532  	t := New(TSSA)
   533  	t.Extra = name
   534  	return t
   535  }
   536  
   537  // NewMap returns a new map Type with key type k and element (aka value) type v.
   538  func NewMap(k, v *Type) *Type {
   539  	t := New(TMAP)
   540  	mt := t.MapType()
   541  	mt.Key = k
   542  	mt.Elem = v
   543  	return t
   544  }
   545  
   546  // NewPtrCacheEnabled controls whether *T Types are cached in T.
   547  // Caching is disabled just before starting the backend.
   548  // This allows the backend to run concurrently.
   549  var NewPtrCacheEnabled = true
   550  
   551  // NewPtr returns the pointer type pointing to t.
   552  func NewPtr(elem *Type) *Type {
   553  	if elem == nil {
   554  		Fatalf("NewPtr: pointer to elem Type is nil")
   555  	}
   556  
   557  	if t := elem.Cache.ptr; t != nil {
   558  		if t.Elem() != elem {
   559  			Fatalf("NewPtr: elem mismatch")
   560  		}
   561  		return t
   562  	}
   563  
   564  	t := New(TPTR)
   565  	t.Extra = Ptr{Elem: elem}
   566  	t.Width = int64(Widthptr)
   567  	t.Align = uint8(Widthptr)
   568  	if NewPtrCacheEnabled {
   569  		elem.Cache.ptr = t
   570  	}
   571  	return t
   572  }
   573  
   574  // NewDDDField returns a new TDDDFIELD type for slice type s.
   575  func NewDDDField(s *Type) *Type {
   576  	t := New(TDDDFIELD)
   577  	t.Extra = DDDField{T: s}
   578  	return t
   579  }
   580  
   581  // NewChanArgs returns a new TCHANARGS type for channel type c.
   582  func NewChanArgs(c *Type) *Type {
   583  	t := New(TCHANARGS)
   584  	t.Extra = ChanArgs{T: c}
   585  	return t
   586  }
   587  
   588  // NewFuncArgs returns a new TFUNCARGS type for func type f.
   589  func NewFuncArgs(f *Type) *Type {
   590  	t := New(TFUNCARGS)
   591  	t.Extra = FuncArgs{T: f}
   592  	return t
   593  }
   594  
   595  func NewField() *Field {
   596  	return &Field{
   597  		Offset: BADWIDTH,
   598  	}
   599  }
   600  
   601  // SubstAny walks t, replacing instances of "any" with successive
   602  // elements removed from types.  It returns the substituted type.
   603  func SubstAny(t *Type, types *[]*Type) *Type {
   604  	if t == nil {
   605  		return nil
   606  	}
   607  
   608  	switch t.Etype {
   609  	default:
   610  		// Leave the type unchanged.
   611  
   612  	case TANY:
   613  		if len(*types) == 0 {
   614  			Fatalf("substArgTypes: not enough argument types")
   615  		}
   616  		t = (*types)[0]
   617  		*types = (*types)[1:]
   618  
   619  	case TPTR:
   620  		elem := SubstAny(t.Elem(), types)
   621  		if elem != t.Elem() {
   622  			t = t.copy()
   623  			t.Extra = Ptr{Elem: elem}
   624  		}
   625  
   626  	case TARRAY:
   627  		elem := SubstAny(t.Elem(), types)
   628  		if elem != t.Elem() {
   629  			t = t.copy()
   630  			t.Extra.(*Array).Elem = elem
   631  		}
   632  
   633  	case TSLICE:
   634  		elem := SubstAny(t.Elem(), types)
   635  		if elem != t.Elem() {
   636  			t = t.copy()
   637  			t.Extra = Slice{Elem: elem}
   638  		}
   639  
   640  	case TCHAN:
   641  		elem := SubstAny(t.Elem(), types)
   642  		if elem != t.Elem() {
   643  			t = t.copy()
   644  			t.Extra.(*Chan).Elem = elem
   645  		}
   646  
   647  	case TMAP:
   648  		key := SubstAny(t.Key(), types)
   649  		elem := SubstAny(t.Elem(), types)
   650  		if key != t.Key() || elem != t.Elem() {
   651  			t = t.copy()
   652  			t.Extra.(*Map).Key = key
   653  			t.Extra.(*Map).Elem = elem
   654  		}
   655  
   656  	case TFUNC:
   657  		recvs := SubstAny(t.Recvs(), types)
   658  		params := SubstAny(t.Params(), types)
   659  		results := SubstAny(t.Results(), types)
   660  		if recvs != t.Recvs() || params != t.Params() || results != t.Results() {
   661  			t = t.copy()
   662  			t.FuncType().Receiver = recvs
   663  			t.FuncType().Results = results
   664  			t.FuncType().Params = params
   665  		}
   666  
   667  	case TSTRUCT:
   668  		// Make a copy of all fields, including ones whose type does not change.
   669  		// This prevents aliasing across functions, which can lead to later
   670  		// fields getting their Offset incorrectly overwritten.
   671  		fields := t.FieldSlice()
   672  		nfs := make([]*Field, len(fields))
   673  		for i, f := range fields {
   674  			nft := SubstAny(f.Type, types)
   675  			nfs[i] = f.Copy()
   676  			nfs[i].Type = nft
   677  		}
   678  		t = t.copy()
   679  		t.SetFields(nfs)
   680  	}
   681  
   682  	return t
   683  }
   684  
   685  // copy returns a shallow copy of the Type.
   686  func (t *Type) copy() *Type {
   687  	if t == nil {
   688  		return nil
   689  	}
   690  	nt := *t
   691  	// copy any *T Extra fields, to avoid aliasing
   692  	switch t.Etype {
   693  	case TMAP:
   694  		x := *t.Extra.(*Map)
   695  		nt.Extra = &x
   696  	case TFORW:
   697  		x := *t.Extra.(*Forward)
   698  		nt.Extra = &x
   699  	case TFUNC:
   700  		x := *t.Extra.(*Func)
   701  		nt.Extra = &x
   702  	case TSTRUCT:
   703  		x := *t.Extra.(*Struct)
   704  		nt.Extra = &x
   705  	case TINTER:
   706  		x := *t.Extra.(*Interface)
   707  		nt.Extra = &x
   708  	case TCHAN:
   709  		x := *t.Extra.(*Chan)
   710  		nt.Extra = &x
   711  	case TARRAY:
   712  		x := *t.Extra.(*Array)
   713  		nt.Extra = &x
   714  	case TTUPLE, TSSA:
   715  		Fatalf("ssa types cannot be copied")
   716  	}
   717  	// TODO(mdempsky): Find out why this is necessary and explain.
   718  	if t.Orig == t {
   719  		nt.Orig = &nt
   720  	}
   721  	return &nt
   722  }
   723  
   724  func (f *Field) Copy() *Field {
   725  	nf := *f
   726  	return &nf
   727  }
   728  
   729  func (t *Type) wantEtype(et EType) {
   730  	if t.Etype != et {
   731  		Fatalf("want %v, but have %v", et, t)
   732  	}
   733  }
   734  
   735  func (t *Type) Recvs() *Type   { return t.FuncType().Receiver }
   736  func (t *Type) Params() *Type  { return t.FuncType().Params }
   737  func (t *Type) Results() *Type { return t.FuncType().Results }
   738  
   739  func (t *Type) NumRecvs() int   { return t.FuncType().Receiver.NumFields() }
   740  func (t *Type) NumParams() int  { return t.FuncType().Params.NumFields() }
   741  func (t *Type) NumResults() int { return t.FuncType().Results.NumFields() }
   742  
   743  // IsVariadic reports whether function type t is variadic.
   744  func (t *Type) IsVariadic() bool {
   745  	n := t.NumParams()
   746  	return n > 0 && t.Params().Field(n-1).IsDDD()
   747  }
   748  
   749  // Recv returns the receiver of function type t, if any.
   750  func (t *Type) Recv() *Field {
   751  	s := t.Recvs()
   752  	if s.NumFields() == 0 {
   753  		return nil
   754  	}
   755  	return s.Field(0)
   756  }
   757  
   758  // RecvsParamsResults stores the accessor functions for a function Type's
   759  // receiver, parameters, and result parameters, in that order.
   760  // It can be used to iterate over all of a function's parameter lists.
   761  var RecvsParamsResults = [3]func(*Type) *Type{
   762  	(*Type).Recvs, (*Type).Params, (*Type).Results,
   763  }
   764  
   765  // RecvsParams is like RecvsParamsResults, but omits result parameters.
   766  var RecvsParams = [2]func(*Type) *Type{
   767  	(*Type).Recvs, (*Type).Params,
   768  }
   769  
   770  // ParamsResults is like RecvsParamsResults, but omits receiver parameters.
   771  var ParamsResults = [2]func(*Type) *Type{
   772  	(*Type).Params, (*Type).Results,
   773  }
   774  
   775  // Key returns the key type of map type t.
   776  func (t *Type) Key() *Type {
   777  	t.wantEtype(TMAP)
   778  	return t.Extra.(*Map).Key
   779  }
   780  
   781  // Elem returns the type of elements of t.
   782  // Usable with pointers, channels, arrays, slices, and maps.
   783  func (t *Type) Elem() *Type {
   784  	switch t.Etype {
   785  	case TPTR:
   786  		return t.Extra.(Ptr).Elem
   787  	case TARRAY:
   788  		return t.Extra.(*Array).Elem
   789  	case TSLICE:
   790  		return t.Extra.(Slice).Elem
   791  	case TCHAN:
   792  		return t.Extra.(*Chan).Elem
   793  	case TMAP:
   794  		return t.Extra.(*Map).Elem
   795  	}
   796  	Fatalf("Type.Elem %s", t.Etype)
   797  	return nil
   798  }
   799  
   800  // DDDField returns the slice ... type for TDDDFIELD type t.
   801  func (t *Type) DDDField() *Type {
   802  	t.wantEtype(TDDDFIELD)
   803  	return t.Extra.(DDDField).T
   804  }
   805  
   806  // ChanArgs returns the channel type for TCHANARGS type t.
   807  func (t *Type) ChanArgs() *Type {
   808  	t.wantEtype(TCHANARGS)
   809  	return t.Extra.(ChanArgs).T
   810  }
   811  
   812  // FuncArgs returns the func type for TFUNCARGS type t.
   813  func (t *Type) FuncArgs() *Type {
   814  	t.wantEtype(TFUNCARGS)
   815  	return t.Extra.(FuncArgs).T
   816  }
   817  
   818  // Nname returns the associated function's nname.
   819  func (t *Type) Nname() *Node {
   820  	switch t.Etype {
   821  	case TFUNC:
   822  		return t.Extra.(*Func).Nname
   823  	}
   824  	Fatalf("Type.Nname %v %v", t.Etype, t)
   825  	return nil
   826  }
   827  
   828  // Nname sets the associated function's nname.
   829  func (t *Type) SetNname(n *Node) {
   830  	switch t.Etype {
   831  	case TFUNC:
   832  		t.Extra.(*Func).Nname = n
   833  	default:
   834  		Fatalf("Type.SetNname %v %v", t.Etype, t)
   835  	}
   836  }
   837  
   838  // IsFuncArgStruct reports whether t is a struct representing function parameters.
   839  func (t *Type) IsFuncArgStruct() bool {
   840  	return t.Etype == TSTRUCT && t.Extra.(*Struct).Funarg != FunargNone
   841  }
   842  
   843  func (t *Type) Methods() *Fields {
   844  	// TODO(mdempsky): Validate t?
   845  	return &t.methods
   846  }
   847  
   848  func (t *Type) AllMethods() *Fields {
   849  	// TODO(mdempsky): Validate t?
   850  	return &t.allMethods
   851  }
   852  
   853  func (t *Type) Fields() *Fields {
   854  	switch t.Etype {
   855  	case TSTRUCT:
   856  		return &t.Extra.(*Struct).fields
   857  	case TINTER:
   858  		Dowidth(t)
   859  		return &t.Extra.(*Interface).Fields
   860  	}
   861  	Fatalf("Fields: type %v does not have fields", t)
   862  	return nil
   863  }
   864  
   865  // Field returns the i'th field/method of struct/interface type t.
   866  func (t *Type) Field(i int) *Field {
   867  	return t.Fields().Slice()[i]
   868  }
   869  
   870  // FieldSlice returns a slice of containing all fields/methods of
   871  // struct/interface type t.
   872  func (t *Type) FieldSlice() []*Field {
   873  	return t.Fields().Slice()
   874  }
   875  
   876  // SetFields sets struct/interface type t's fields/methods to fields.
   877  func (t *Type) SetFields(fields []*Field) {
   878  	// If we've calculated the width of t before,
   879  	// then some other type such as a function signature
   880  	// might now have the wrong type.
   881  	// Rather than try to track and invalidate those,
   882  	// enforce that SetFields cannot be called once
   883  	// t's width has been calculated.
   884  	if t.WidthCalculated() {
   885  		Fatalf("SetFields of %v: width previously calculated", t)
   886  	}
   887  	t.wantEtype(TSTRUCT)
   888  	for _, f := range fields {
   889  		// If type T contains a field F with a go:notinheap
   890  		// type, then T must also be go:notinheap. Otherwise,
   891  		// you could heap allocate T and then get a pointer F,
   892  		// which would be a heap pointer to a go:notinheap
   893  		// type.
   894  		if f.Type != nil && f.Type.NotInHeap() {
   895  			t.SetNotInHeap(true)
   896  			break
   897  		}
   898  	}
   899  	t.Fields().Set(fields)
   900  }
   901  
   902  func (t *Type) SetInterface(methods []*Field) {
   903  	t.wantEtype(TINTER)
   904  	t.Methods().Set(methods)
   905  }
   906  
   907  func (t *Type) IsDDDArray() bool {
   908  	if t.Etype != TARRAY {
   909  		return false
   910  	}
   911  	return t.Extra.(*Array).Bound < 0
   912  }
   913  
   914  func (t *Type) WidthCalculated() bool {
   915  	return t.Align > 0
   916  }
   917  
   918  // ArgWidth returns the total aligned argument size for a function.
   919  // It includes the receiver, parameters, and results.
   920  func (t *Type) ArgWidth() int64 {
   921  	t.wantEtype(TFUNC)
   922  	return t.Extra.(*Func).Argwid
   923  }
   924  
   925  func (t *Type) Size() int64 {
   926  	if t.Etype == TSSA {
   927  		if t == TypeInt128 {
   928  			return 16
   929  		}
   930  		return 0
   931  	}
   932  	Dowidth(t)
   933  	return t.Width
   934  }
   935  
   936  func (t *Type) Alignment() int64 {
   937  	Dowidth(t)
   938  	return int64(t.Align)
   939  }
   940  
   941  func (t *Type) SimpleString() string {
   942  	return t.Etype.String()
   943  }
   944  
   945  // Cmp is a comparison between values a and b.
   946  // -1 if a < b
   947  //  0 if a == b
   948  //  1 if a > b
   949  type Cmp int8
   950  
   951  const (
   952  	CMPlt = Cmp(-1)
   953  	CMPeq = Cmp(0)
   954  	CMPgt = Cmp(1)
   955  )
   956  
   957  // Compare compares types for purposes of the SSA back
   958  // end, returning a Cmp (one of CMPlt, CMPeq, CMPgt).
   959  // The answers are correct for an optimizer
   960  // or code generator, but not necessarily typechecking.
   961  // The order chosen is arbitrary, only consistency and division
   962  // into equivalence classes (Types that compare CMPeq) matters.
   963  func (t *Type) Compare(x *Type) Cmp {
   964  	if x == t {
   965  		return CMPeq
   966  	}
   967  	return t.cmp(x)
   968  }
   969  
   970  func cmpForNe(x bool) Cmp {
   971  	if x {
   972  		return CMPlt
   973  	}
   974  	return CMPgt
   975  }
   976  
   977  func (r *Sym) cmpsym(s *Sym) Cmp {
   978  	if r == s {
   979  		return CMPeq
   980  	}
   981  	if r == nil {
   982  		return CMPlt
   983  	}
   984  	if s == nil {
   985  		return CMPgt
   986  	}
   987  	// Fast sort, not pretty sort
   988  	if len(r.Name) != len(s.Name) {
   989  		return cmpForNe(len(r.Name) < len(s.Name))
   990  	}
   991  	if r.Pkg != s.Pkg {
   992  		if len(r.Pkg.Prefix) != len(s.Pkg.Prefix) {
   993  			return cmpForNe(len(r.Pkg.Prefix) < len(s.Pkg.Prefix))
   994  		}
   995  		if r.Pkg.Prefix != s.Pkg.Prefix {
   996  			return cmpForNe(r.Pkg.Prefix < s.Pkg.Prefix)
   997  		}
   998  	}
   999  	if r.Name != s.Name {
  1000  		return cmpForNe(r.Name < s.Name)
  1001  	}
  1002  	return CMPeq
  1003  }
  1004  
  1005  // cmp compares two *Types t and x, returning CMPlt,
  1006  // CMPeq, CMPgt as t<x, t==x, t>x, for an arbitrary
  1007  // and optimizer-centric notion of comparison.
  1008  // TODO(josharian): make this safe for recursive interface types
  1009  // and use in signatlist sorting. See issue 19869.
  1010  func (t *Type) cmp(x *Type) Cmp {
  1011  	// This follows the structure of eqtype in subr.go
  1012  	// with two exceptions.
  1013  	// 1. Symbols are compared more carefully because a <,=,> result is desired.
  1014  	// 2. Maps are treated specially to avoid endless recursion -- maps
  1015  	//    contain an internal data type not expressible in Go source code.
  1016  	if t == x {
  1017  		return CMPeq
  1018  	}
  1019  	if t == nil {
  1020  		return CMPlt
  1021  	}
  1022  	if x == nil {
  1023  		return CMPgt
  1024  	}
  1025  
  1026  	if t.Etype != x.Etype {
  1027  		return cmpForNe(t.Etype < x.Etype)
  1028  	}
  1029  
  1030  	if t.Sym != nil || x.Sym != nil {
  1031  		// Special case: we keep byte and uint8 separate
  1032  		// for error messages. Treat them as equal.
  1033  		switch t.Etype {
  1034  		case TUINT8:
  1035  			if (t == Types[TUINT8] || t == Bytetype) && (x == Types[TUINT8] || x == Bytetype) {
  1036  				return CMPeq
  1037  			}
  1038  
  1039  		case TINT32:
  1040  			if (t == Types[Runetype.Etype] || t == Runetype) && (x == Types[Runetype.Etype] || x == Runetype) {
  1041  				return CMPeq
  1042  			}
  1043  		}
  1044  	}
  1045  
  1046  	if c := t.Sym.cmpsym(x.Sym); c != CMPeq {
  1047  		return c
  1048  	}
  1049  
  1050  	if x.Sym != nil {
  1051  		// Syms non-nil, if vargens match then equal.
  1052  		if t.Vargen != x.Vargen {
  1053  			return cmpForNe(t.Vargen < x.Vargen)
  1054  		}
  1055  		return CMPeq
  1056  	}
  1057  	// both syms nil, look at structure below.
  1058  
  1059  	switch t.Etype {
  1060  	case TBOOL, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TUNSAFEPTR, TUINTPTR,
  1061  		TINT8, TINT16, TINT32, TINT64, TINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINT:
  1062  		return CMPeq
  1063  
  1064  	case TSSA:
  1065  		tname := t.Extra.(string)
  1066  		xname := t.Extra.(string)
  1067  		// desire fast sorting, not pretty sorting.
  1068  		if len(tname) == len(xname) {
  1069  			if tname == xname {
  1070  				return CMPeq
  1071  			}
  1072  			if tname < xname {
  1073  				return CMPlt
  1074  			}
  1075  			return CMPgt
  1076  		}
  1077  		if len(tname) > len(xname) {
  1078  			return CMPgt
  1079  		}
  1080  		return CMPlt
  1081  
  1082  	case TTUPLE:
  1083  		xtup := x.Extra.(*Tuple)
  1084  		ttup := t.Extra.(*Tuple)
  1085  		if c := ttup.first.Compare(xtup.first); c != CMPeq {
  1086  			return c
  1087  		}
  1088  		return ttup.second.Compare(xtup.second)
  1089  
  1090  	case TMAP:
  1091  		if c := t.Key().cmp(x.Key()); c != CMPeq {
  1092  			return c
  1093  		}
  1094  		return t.Elem().cmp(x.Elem())
  1095  
  1096  	case TPTR, TSLICE:
  1097  		// No special cases for these, they are handled
  1098  		// by the general code after the switch.
  1099  
  1100  	case TSTRUCT:
  1101  		if t.StructType().Map == nil {
  1102  			if x.StructType().Map != nil {
  1103  				return CMPlt // nil < non-nil
  1104  			}
  1105  			// to the fallthrough
  1106  		} else if x.StructType().Map == nil {
  1107  			return CMPgt // nil > non-nil
  1108  		} else if t.StructType().Map.MapType().Bucket == t {
  1109  			// Both have non-nil Map
  1110  			// Special case for Maps which include a recursive type where the recursion is not broken with a named type
  1111  			if x.StructType().Map.MapType().Bucket != x {
  1112  				return CMPlt // bucket maps are least
  1113  			}
  1114  			return t.StructType().Map.cmp(x.StructType().Map)
  1115  		} else if x.StructType().Map.MapType().Bucket == x {
  1116  			return CMPgt // bucket maps are least
  1117  		} // If t != t.Map.Bucket, fall through to general case
  1118  
  1119  		tfs := t.FieldSlice()
  1120  		xfs := x.FieldSlice()
  1121  		for i := 0; i < len(tfs) && i < len(xfs); i++ {
  1122  			t1, x1 := tfs[i], xfs[i]
  1123  			if t1.Embedded != x1.Embedded {
  1124  				return cmpForNe(t1.Embedded < x1.Embedded)
  1125  			}
  1126  			if t1.Note != x1.Note {
  1127  				return cmpForNe(t1.Note < x1.Note)
  1128  			}
  1129  			if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
  1130  				return c
  1131  			}
  1132  			if c := t1.Type.cmp(x1.Type); c != CMPeq {
  1133  				return c
  1134  			}
  1135  		}
  1136  		if len(tfs) != len(xfs) {
  1137  			return cmpForNe(len(tfs) < len(xfs))
  1138  		}
  1139  		return CMPeq
  1140  
  1141  	case TINTER:
  1142  		tfs := t.FieldSlice()
  1143  		xfs := x.FieldSlice()
  1144  		for i := 0; i < len(tfs) && i < len(xfs); i++ {
  1145  			t1, x1 := tfs[i], xfs[i]
  1146  			if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
  1147  				return c
  1148  			}
  1149  			if c := t1.Type.cmp(x1.Type); c != CMPeq {
  1150  				return c
  1151  			}
  1152  		}
  1153  		if len(tfs) != len(xfs) {
  1154  			return cmpForNe(len(tfs) < len(xfs))
  1155  		}
  1156  		return CMPeq
  1157  
  1158  	case TFUNC:
  1159  		for _, f := range RecvsParamsResults {
  1160  			// Loop over fields in structs, ignoring argument names.
  1161  			tfs := f(t).FieldSlice()
  1162  			xfs := f(x).FieldSlice()
  1163  			for i := 0; i < len(tfs) && i < len(xfs); i++ {
  1164  				ta := tfs[i]
  1165  				tb := xfs[i]
  1166  				if ta.IsDDD() != tb.IsDDD() {
  1167  					return cmpForNe(!ta.IsDDD())
  1168  				}
  1169  				if c := ta.Type.cmp(tb.Type); c != CMPeq {
  1170  					return c
  1171  				}
  1172  			}
  1173  			if len(tfs) != len(xfs) {
  1174  				return cmpForNe(len(tfs) < len(xfs))
  1175  			}
  1176  		}
  1177  		return CMPeq
  1178  
  1179  	case TARRAY:
  1180  		if t.NumElem() != x.NumElem() {
  1181  			return cmpForNe(t.NumElem() < x.NumElem())
  1182  		}
  1183  
  1184  	case TCHAN:
  1185  		if t.ChanDir() != x.ChanDir() {
  1186  			return cmpForNe(t.ChanDir() < x.ChanDir())
  1187  		}
  1188  
  1189  	default:
  1190  		e := fmt.Sprintf("Do not know how to compare %v with %v", t, x)
  1191  		panic(e)
  1192  	}
  1193  
  1194  	// Common element type comparison for TARRAY, TCHAN, TPTR, and TSLICE.
  1195  	return t.Elem().cmp(x.Elem())
  1196  }
  1197  
  1198  // IsKind reports whether t is a Type of the specified kind.
  1199  func (t *Type) IsKind(et EType) bool {
  1200  	return t != nil && t.Etype == et
  1201  }
  1202  
  1203  func (t *Type) IsBoolean() bool {
  1204  	return t.Etype == TBOOL
  1205  }
  1206  
  1207  var unsignedEType = [...]EType{
  1208  	TINT8:    TUINT8,
  1209  	TUINT8:   TUINT8,
  1210  	TINT16:   TUINT16,
  1211  	TUINT16:  TUINT16,
  1212  	TINT32:   TUINT32,
  1213  	TUINT32:  TUINT32,
  1214  	TINT64:   TUINT64,
  1215  	TUINT64:  TUINT64,
  1216  	TINT:     TUINT,
  1217  	TUINT:    TUINT,
  1218  	TUINTPTR: TUINTPTR,
  1219  }
  1220  
  1221  // ToUnsigned returns the unsigned equivalent of integer type t.
  1222  func (t *Type) ToUnsigned() *Type {
  1223  	if !t.IsInteger() {
  1224  		Fatalf("unsignedType(%v)", t)
  1225  	}
  1226  	return Types[unsignedEType[t.Etype]]
  1227  }
  1228  
  1229  func (t *Type) IsInteger() bool {
  1230  	switch t.Etype {
  1231  	case TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64, TUINT64, TINT, TUINT, TUINTPTR:
  1232  		return true
  1233  	}
  1234  	return false
  1235  }
  1236  
  1237  func (t *Type) IsSigned() bool {
  1238  	switch t.Etype {
  1239  	case TINT8, TINT16, TINT32, TINT64, TINT:
  1240  		return true
  1241  	}
  1242  	return false
  1243  }
  1244  
  1245  func (t *Type) IsFloat() bool {
  1246  	return t.Etype == TFLOAT32 || t.Etype == TFLOAT64
  1247  }
  1248  
  1249  func (t *Type) IsComplex() bool {
  1250  	return t.Etype == TCOMPLEX64 || t.Etype == TCOMPLEX128
  1251  }
  1252  
  1253  // IsPtr reports whether t is a regular Go pointer type.
  1254  // This does not include unsafe.Pointer.
  1255  func (t *Type) IsPtr() bool {
  1256  	return t.Etype == TPTR
  1257  }
  1258  
  1259  // IsPtrElem reports whether t is the element of a pointer (to t).
  1260  func (t *Type) IsPtrElem() bool {
  1261  	return t.Cache.ptr != nil
  1262  }
  1263  
  1264  // IsUnsafePtr reports whether t is an unsafe pointer.
  1265  func (t *Type) IsUnsafePtr() bool {
  1266  	return t.Etype == TUNSAFEPTR
  1267  }
  1268  
  1269  // IsPtrShaped reports whether t is represented by a single machine pointer.
  1270  // In addition to regular Go pointer types, this includes map, channel, and
  1271  // function types and unsafe.Pointer. It does not include array or struct types
  1272  // that consist of a single pointer shaped type.
  1273  // TODO(mdempsky): Should it? See golang.org/issue/15028.
  1274  func (t *Type) IsPtrShaped() bool {
  1275  	return t.Etype == TPTR || t.Etype == TUNSAFEPTR ||
  1276  		t.Etype == TMAP || t.Etype == TCHAN || t.Etype == TFUNC
  1277  }
  1278  
  1279  func (t *Type) IsString() bool {
  1280  	return t.Etype == TSTRING
  1281  }
  1282  
  1283  func (t *Type) IsMap() bool {
  1284  	return t.Etype == TMAP
  1285  }
  1286  
  1287  func (t *Type) IsChan() bool {
  1288  	return t.Etype == TCHAN
  1289  }
  1290  
  1291  func (t *Type) IsSlice() bool {
  1292  	return t.Etype == TSLICE
  1293  }
  1294  
  1295  func (t *Type) IsArray() bool {
  1296  	return t.Etype == TARRAY
  1297  }
  1298  
  1299  func (t *Type) IsStruct() bool {
  1300  	return t.Etype == TSTRUCT
  1301  }
  1302  
  1303  func (t *Type) IsInterface() bool {
  1304  	return t.Etype == TINTER
  1305  }
  1306  
  1307  // IsEmptyInterface reports whether t is an empty interface type.
  1308  func (t *Type) IsEmptyInterface() bool {
  1309  	return t.IsInterface() && t.NumFields() == 0
  1310  }
  1311  
  1312  func (t *Type) PtrTo() *Type {
  1313  	return NewPtr(t)
  1314  }
  1315  
  1316  func (t *Type) NumFields() int {
  1317  	return t.Fields().Len()
  1318  }
  1319  func (t *Type) FieldType(i int) *Type {
  1320  	if t.Etype == TTUPLE {
  1321  		switch i {
  1322  		case 0:
  1323  			return t.Extra.(*Tuple).first
  1324  		case 1:
  1325  			return t.Extra.(*Tuple).second
  1326  		default:
  1327  			panic("bad tuple index")
  1328  		}
  1329  	}
  1330  	return t.Field(i).Type
  1331  }
  1332  func (t *Type) FieldOff(i int) int64 {
  1333  	return t.Field(i).Offset
  1334  }
  1335  func (t *Type) FieldName(i int) string {
  1336  	return t.Field(i).Sym.Name
  1337  }
  1338  
  1339  func (t *Type) NumElem() int64 {
  1340  	t.wantEtype(TARRAY)
  1341  	at := t.Extra.(*Array)
  1342  	if at.Bound < 0 {
  1343  		Fatalf("NumElem array %v does not have bound yet", t)
  1344  	}
  1345  	return at.Bound
  1346  }
  1347  
  1348  // SetNumElem sets the number of elements in an array type.
  1349  // The only allowed use is on array types created with NewDDDArray.
  1350  // For other uses, create a new array with NewArray instead.
  1351  func (t *Type) SetNumElem(n int64) {
  1352  	t.wantEtype(TARRAY)
  1353  	at := t.Extra.(*Array)
  1354  	if at.Bound >= 0 {
  1355  		Fatalf("SetNumElem array %v already has bound %d", t, at.Bound)
  1356  	}
  1357  	at.Bound = n
  1358  }
  1359  
  1360  type componentsIncludeBlankFields bool
  1361  
  1362  const (
  1363  	IgnoreBlankFields componentsIncludeBlankFields = false
  1364  	CountBlankFields  componentsIncludeBlankFields = true
  1365  )
  1366  
  1367  // NumComponents returns the number of primitive elements that compose t.
  1368  // Struct and array types are flattened for the purpose of counting.
  1369  // All other types (including string, slice, and interface types) count as one element.
  1370  // If countBlank is IgnoreBlankFields, then blank struct fields
  1371  // (and their comprised elements) are excluded from the count.
  1372  // struct { x, y [3]int } has six components; [10]struct{ x, y string } has twenty.
  1373  func (t *Type) NumComponents(countBlank componentsIncludeBlankFields) int64 {
  1374  	switch t.Etype {
  1375  	case TSTRUCT:
  1376  		if t.IsFuncArgStruct() {
  1377  			Fatalf("NumComponents func arg struct")
  1378  		}
  1379  		var n int64
  1380  		for _, f := range t.FieldSlice() {
  1381  			if countBlank == IgnoreBlankFields && f.Sym.IsBlank() {
  1382  				continue
  1383  			}
  1384  			n += f.Type.NumComponents(countBlank)
  1385  		}
  1386  		return n
  1387  	case TARRAY:
  1388  		return t.NumElem() * t.Elem().NumComponents(countBlank)
  1389  	}
  1390  	return 1
  1391  }
  1392  
  1393  // ChanDir returns the direction of a channel type t.
  1394  // The direction will be one of Crecv, Csend, or Cboth.
  1395  func (t *Type) ChanDir() ChanDir {
  1396  	t.wantEtype(TCHAN)
  1397  	return t.Extra.(*Chan).Dir
  1398  }
  1399  
  1400  func (t *Type) IsMemory() bool {
  1401  	return t == TypeMem || t.Etype == TTUPLE && t.Extra.(*Tuple).second == TypeMem
  1402  }
  1403  func (t *Type) IsFlags() bool { return t == TypeFlags }
  1404  func (t *Type) IsVoid() bool  { return t == TypeVoid }
  1405  func (t *Type) IsTuple() bool { return t.Etype == TTUPLE }
  1406  
  1407  // IsUntyped reports whether t is an untyped type.
  1408  func (t *Type) IsUntyped() bool {
  1409  	if t == nil {
  1410  		return false
  1411  	}
  1412  	if t == Idealstring || t == Idealbool {
  1413  		return true
  1414  	}
  1415  	switch t.Etype {
  1416  	case TNIL, TIDEAL:
  1417  		return true
  1418  	}
  1419  	return false
  1420  }
  1421  
  1422  // TODO(austin): We probably only need HasHeapPointer. See
  1423  // golang.org/cl/73412 for discussion.
  1424  
  1425  func Haspointers(t *Type) bool {
  1426  	return Haspointers1(t, false)
  1427  }
  1428  
  1429  func Haspointers1(t *Type, ignoreNotInHeap bool) bool {
  1430  	switch t.Etype {
  1431  	case TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64,
  1432  		TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL, TSSA:
  1433  		return false
  1434  
  1435  	case TARRAY:
  1436  		if t.NumElem() == 0 { // empty array has no pointers
  1437  			return false
  1438  		}
  1439  		return Haspointers1(t.Elem(), ignoreNotInHeap)
  1440  
  1441  	case TSTRUCT:
  1442  		for _, t1 := range t.Fields().Slice() {
  1443  			if Haspointers1(t1.Type, ignoreNotInHeap) {
  1444  				return true
  1445  			}
  1446  		}
  1447  		return false
  1448  
  1449  	case TPTR, TSLICE:
  1450  		return !(ignoreNotInHeap && t.Elem().NotInHeap())
  1451  
  1452  	case TTUPLE:
  1453  		ttup := t.Extra.(*Tuple)
  1454  		return Haspointers1(ttup.first, ignoreNotInHeap) || Haspointers1(ttup.second, ignoreNotInHeap)
  1455  	}
  1456  
  1457  	return true
  1458  }
  1459  
  1460  // HasHeapPointer reports whether t contains a heap pointer.
  1461  // This is used for write barrier insertion, so it ignores
  1462  // pointers to go:notinheap types.
  1463  func (t *Type) HasHeapPointer() bool {
  1464  	return Haspointers1(t, true)
  1465  }
  1466  
  1467  func (t *Type) Symbol() *obj.LSym {
  1468  	return TypeLinkSym(t)
  1469  }
  1470  
  1471  // Tie returns 'T' if t is a concrete type,
  1472  // 'I' if t is an interface type, and 'E' if t is an empty interface type.
  1473  // It is used to build calls to the conv* and assert* runtime routines.
  1474  func (t *Type) Tie() byte {
  1475  	if t.IsEmptyInterface() {
  1476  		return 'E'
  1477  	}
  1478  	if t.IsInterface() {
  1479  		return 'I'
  1480  	}
  1481  	return 'T'
  1482  }
  1483  
  1484  var recvType *Type
  1485  
  1486  // FakeRecvType returns the singleton type used for interface method receivers.
  1487  func FakeRecvType() *Type {
  1488  	if recvType == nil {
  1489  		recvType = NewPtr(New(TSTRUCT))
  1490  	}
  1491  	return recvType
  1492  }
  1493  
  1494  var (
  1495  	// TSSA types. Haspointers assumes these are pointer-free.
  1496  	TypeInvalid = newSSA("invalid")
  1497  	TypeMem     = newSSA("mem")
  1498  	TypeFlags   = newSSA("flags")
  1499  	TypeVoid    = newSSA("void")
  1500  	TypeInt128  = newSSA("int128")
  1501  )
  1502  

View as plain text