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

View as plain text