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  // IsMethod reports whether f represents a method rather than a struct field.
   396  func (f *Field) IsMethod() bool {
   397  	return f.Type.Etype == TFUNC && f.Type.Recv() != nil
   398  }
   399  
   400  // Fields is a pointer to a slice of *Field.
   401  // This saves space in Types that do not have fields or methods
   402  // compared to a simple slice of *Field.
   403  type Fields struct {
   404  	s *[]*Field
   405  }
   406  
   407  // Len returns the number of entries in f.
   408  func (f *Fields) Len() int {
   409  	if f.s == nil {
   410  		return 0
   411  	}
   412  	return len(*f.s)
   413  }
   414  
   415  // Slice returns the entries in f as a slice.
   416  // Changes to the slice entries will be reflected in f.
   417  func (f *Fields) Slice() []*Field {
   418  	if f.s == nil {
   419  		return nil
   420  	}
   421  	return *f.s
   422  }
   423  
   424  // Index returns the i'th element of Fields.
   425  // It panics if f does not have at least i+1 elements.
   426  func (f *Fields) Index(i int) *Field {
   427  	return (*f.s)[i]
   428  }
   429  
   430  // Set sets f to a slice.
   431  // This takes ownership of the slice.
   432  func (f *Fields) Set(s []*Field) {
   433  	if len(s) == 0 {
   434  		f.s = nil
   435  	} else {
   436  		// Copy s and take address of t rather than s to avoid
   437  		// allocation in the case where len(s) == 0.
   438  		t := s
   439  		f.s = &t
   440  	}
   441  }
   442  
   443  // Append appends entries to f.
   444  func (f *Fields) Append(s ...*Field) {
   445  	if f.s == nil {
   446  		f.s = new([]*Field)
   447  	}
   448  	*f.s = append(*f.s, s...)
   449  }
   450  
   451  // New returns a new Type of the specified kind.
   452  func New(et EType) *Type {
   453  	t := &Type{
   454  		Etype: et,
   455  		Width: BADWIDTH,
   456  	}
   457  	t.Orig = t
   458  	// TODO(josharian): lazily initialize some of these?
   459  	switch t.Etype {
   460  	case TMAP:
   461  		t.Extra = new(Map)
   462  	case TFORW:
   463  		t.Extra = new(Forward)
   464  	case TFUNC:
   465  		t.Extra = new(Func)
   466  	case TSTRUCT:
   467  		t.Extra = new(Struct)
   468  	case TINTER:
   469  		t.Extra = new(Interface)
   470  	case TPTR:
   471  		t.Extra = Ptr{}
   472  	case TCHANARGS:
   473  		t.Extra = ChanArgs{}
   474  	case TFUNCARGS:
   475  		t.Extra = FuncArgs{}
   476  	case TDDDFIELD:
   477  		t.Extra = DDDField{}
   478  	case TCHAN:
   479  		t.Extra = new(Chan)
   480  	case TTUPLE:
   481  		t.Extra = new(Tuple)
   482  	}
   483  	return t
   484  }
   485  
   486  // NewArray returns a new fixed-length array Type.
   487  func NewArray(elem *Type, bound int64) *Type {
   488  	if bound < 0 {
   489  		Fatalf("NewArray: invalid bound %v", bound)
   490  	}
   491  	t := New(TARRAY)
   492  	t.Extra = &Array{Elem: elem, Bound: bound}
   493  	t.SetNotInHeap(elem.NotInHeap())
   494  	return t
   495  }
   496  
   497  // NewSlice returns the slice Type with element type elem.
   498  func NewSlice(elem *Type) *Type {
   499  	if t := elem.Cache.slice; t != nil {
   500  		if t.Elem() != elem {
   501  			Fatalf("elem mismatch")
   502  		}
   503  		return t
   504  	}
   505  
   506  	t := New(TSLICE)
   507  	t.Extra = Slice{Elem: elem}
   508  	elem.Cache.slice = t
   509  	return t
   510  }
   511  
   512  // NewDDDArray returns a new [...]T array Type.
   513  func NewDDDArray(elem *Type) *Type {
   514  	t := New(TARRAY)
   515  	t.Extra = &Array{Elem: elem, Bound: -1}
   516  	t.SetNotInHeap(elem.NotInHeap())
   517  	return t
   518  }
   519  
   520  // NewChan returns a new chan Type with direction dir.
   521  func NewChan(elem *Type, dir ChanDir) *Type {
   522  	t := New(TCHAN)
   523  	ct := t.ChanType()
   524  	ct.Elem = elem
   525  	ct.Dir = dir
   526  	return t
   527  }
   528  
   529  func NewTuple(t1, t2 *Type) *Type {
   530  	t := New(TTUPLE)
   531  	t.Extra.(*Tuple).first = t1
   532  	t.Extra.(*Tuple).second = t2
   533  	return t
   534  }
   535  
   536  func newSSA(name string) *Type {
   537  	t := New(TSSA)
   538  	t.Extra = name
   539  	return t
   540  }
   541  
   542  // NewMap returns a new map Type with key type k and element (aka value) type v.
   543  func NewMap(k, v *Type) *Type {
   544  	t := New(TMAP)
   545  	mt := t.MapType()
   546  	mt.Key = k
   547  	mt.Elem = v
   548  	return t
   549  }
   550  
   551  // NewPtrCacheEnabled controls whether *T Types are cached in T.
   552  // Caching is disabled just before starting the backend.
   553  // This allows the backend to run concurrently.
   554  var NewPtrCacheEnabled = true
   555  
   556  // NewPtr returns the pointer type pointing to t.
   557  func NewPtr(elem *Type) *Type {
   558  	if elem == nil {
   559  		Fatalf("NewPtr: pointer to elem Type is nil")
   560  	}
   561  
   562  	if t := elem.Cache.ptr; t != nil {
   563  		if t.Elem() != elem {
   564  			Fatalf("NewPtr: elem mismatch")
   565  		}
   566  		return t
   567  	}
   568  
   569  	t := New(TPTR)
   570  	t.Extra = Ptr{Elem: elem}
   571  	t.Width = int64(Widthptr)
   572  	t.Align = uint8(Widthptr)
   573  	if NewPtrCacheEnabled {
   574  		elem.Cache.ptr = t
   575  	}
   576  	return t
   577  }
   578  
   579  // NewDDDField returns a new TDDDFIELD type for slice type s.
   580  func NewDDDField(s *Type) *Type {
   581  	t := New(TDDDFIELD)
   582  	t.Extra = DDDField{T: s}
   583  	return t
   584  }
   585  
   586  // NewChanArgs returns a new TCHANARGS type for channel type c.
   587  func NewChanArgs(c *Type) *Type {
   588  	t := New(TCHANARGS)
   589  	t.Extra = ChanArgs{T: c}
   590  	return t
   591  }
   592  
   593  // NewFuncArgs returns a new TFUNCARGS type for func type f.
   594  func NewFuncArgs(f *Type) *Type {
   595  	t := New(TFUNCARGS)
   596  	t.Extra = FuncArgs{T: f}
   597  	return t
   598  }
   599  
   600  func NewField() *Field {
   601  	return &Field{
   602  		Offset: BADWIDTH,
   603  	}
   604  }
   605  
   606  // SubstAny walks t, replacing instances of "any" with successive
   607  // elements removed from types.  It returns the substituted type.
   608  func SubstAny(t *Type, types *[]*Type) *Type {
   609  	if t == nil {
   610  		return nil
   611  	}
   612  
   613  	switch t.Etype {
   614  	default:
   615  		// Leave the type unchanged.
   616  
   617  	case TANY:
   618  		if len(*types) == 0 {
   619  			Fatalf("substArgTypes: not enough argument types")
   620  		}
   621  		t = (*types)[0]
   622  		*types = (*types)[1:]
   623  
   624  	case TPTR:
   625  		elem := SubstAny(t.Elem(), types)
   626  		if elem != t.Elem() {
   627  			t = t.copy()
   628  			t.Extra = Ptr{Elem: elem}
   629  		}
   630  
   631  	case TARRAY:
   632  		elem := SubstAny(t.Elem(), types)
   633  		if elem != t.Elem() {
   634  			t = t.copy()
   635  			t.Extra.(*Array).Elem = elem
   636  		}
   637  
   638  	case TSLICE:
   639  		elem := SubstAny(t.Elem(), types)
   640  		if elem != t.Elem() {
   641  			t = t.copy()
   642  			t.Extra = Slice{Elem: elem}
   643  		}
   644  
   645  	case TCHAN:
   646  		elem := SubstAny(t.Elem(), types)
   647  		if elem != t.Elem() {
   648  			t = t.copy()
   649  			t.Extra.(*Chan).Elem = elem
   650  		}
   651  
   652  	case TMAP:
   653  		key := SubstAny(t.Key(), types)
   654  		elem := SubstAny(t.Elem(), types)
   655  		if key != t.Key() || elem != t.Elem() {
   656  			t = t.copy()
   657  			t.Extra.(*Map).Key = key
   658  			t.Extra.(*Map).Elem = elem
   659  		}
   660  
   661  	case TFUNC:
   662  		recvs := SubstAny(t.Recvs(), types)
   663  		params := SubstAny(t.Params(), types)
   664  		results := SubstAny(t.Results(), types)
   665  		if recvs != t.Recvs() || params != t.Params() || results != t.Results() {
   666  			t = t.copy()
   667  			t.FuncType().Receiver = recvs
   668  			t.FuncType().Results = results
   669  			t.FuncType().Params = params
   670  		}
   671  
   672  	case TSTRUCT:
   673  		// Make a copy of all fields, including ones whose type does not change.
   674  		// This prevents aliasing across functions, which can lead to later
   675  		// fields getting their Offset incorrectly overwritten.
   676  		fields := t.FieldSlice()
   677  		nfs := make([]*Field, len(fields))
   678  		for i, f := range fields {
   679  			nft := SubstAny(f.Type, types)
   680  			nfs[i] = f.Copy()
   681  			nfs[i].Type = nft
   682  		}
   683  		t = t.copy()
   684  		t.SetFields(nfs)
   685  	}
   686  
   687  	return t
   688  }
   689  
   690  // copy returns a shallow copy of the Type.
   691  func (t *Type) copy() *Type {
   692  	if t == nil {
   693  		return nil
   694  	}
   695  	nt := *t
   696  	// copy any *T Extra fields, to avoid aliasing
   697  	switch t.Etype {
   698  	case TMAP:
   699  		x := *t.Extra.(*Map)
   700  		nt.Extra = &x
   701  	case TFORW:
   702  		x := *t.Extra.(*Forward)
   703  		nt.Extra = &x
   704  	case TFUNC:
   705  		x := *t.Extra.(*Func)
   706  		nt.Extra = &x
   707  	case TSTRUCT:
   708  		x := *t.Extra.(*Struct)
   709  		nt.Extra = &x
   710  	case TINTER:
   711  		x := *t.Extra.(*Interface)
   712  		nt.Extra = &x
   713  	case TCHAN:
   714  		x := *t.Extra.(*Chan)
   715  		nt.Extra = &x
   716  	case TARRAY:
   717  		x := *t.Extra.(*Array)
   718  		nt.Extra = &x
   719  	case TTUPLE, TSSA:
   720  		Fatalf("ssa types cannot be copied")
   721  	}
   722  	// TODO(mdempsky): Find out why this is necessary and explain.
   723  	if t.Orig == t {
   724  		nt.Orig = &nt
   725  	}
   726  	return &nt
   727  }
   728  
   729  func (f *Field) Copy() *Field {
   730  	nf := *f
   731  	return &nf
   732  }
   733  
   734  func (t *Type) wantEtype(et EType) {
   735  	if t.Etype != et {
   736  		Fatalf("want %v, but have %v", et, t)
   737  	}
   738  }
   739  
   740  func (t *Type) Recvs() *Type   { return t.FuncType().Receiver }
   741  func (t *Type) Params() *Type  { return t.FuncType().Params }
   742  func (t *Type) Results() *Type { return t.FuncType().Results }
   743  
   744  func (t *Type) NumRecvs() int   { return t.FuncType().Receiver.NumFields() }
   745  func (t *Type) NumParams() int  { return t.FuncType().Params.NumFields() }
   746  func (t *Type) NumResults() int { return t.FuncType().Results.NumFields() }
   747  
   748  // IsVariadic reports whether function type t is variadic.
   749  func (t *Type) IsVariadic() bool {
   750  	n := t.NumParams()
   751  	return n > 0 && t.Params().Field(n-1).IsDDD()
   752  }
   753  
   754  // Recv returns the receiver of function type t, if any.
   755  func (t *Type) Recv() *Field {
   756  	s := t.Recvs()
   757  	if s.NumFields() == 0 {
   758  		return nil
   759  	}
   760  	return s.Field(0)
   761  }
   762  
   763  // RecvsParamsResults stores the accessor functions for a function Type's
   764  // receiver, parameters, and result parameters, in that order.
   765  // It can be used to iterate over all of a function's parameter lists.
   766  var RecvsParamsResults = [3]func(*Type) *Type{
   767  	(*Type).Recvs, (*Type).Params, (*Type).Results,
   768  }
   769  
   770  // RecvsParams is like RecvsParamsResults, but omits result parameters.
   771  var RecvsParams = [2]func(*Type) *Type{
   772  	(*Type).Recvs, (*Type).Params,
   773  }
   774  
   775  // ParamsResults is like RecvsParamsResults, but omits receiver parameters.
   776  var ParamsResults = [2]func(*Type) *Type{
   777  	(*Type).Params, (*Type).Results,
   778  }
   779  
   780  // Key returns the key type of map type t.
   781  func (t *Type) Key() *Type {
   782  	t.wantEtype(TMAP)
   783  	return t.Extra.(*Map).Key
   784  }
   785  
   786  // Elem returns the type of elements of t.
   787  // Usable with pointers, channels, arrays, slices, and maps.
   788  func (t *Type) Elem() *Type {
   789  	switch t.Etype {
   790  	case TPTR:
   791  		return t.Extra.(Ptr).Elem
   792  	case TARRAY:
   793  		return t.Extra.(*Array).Elem
   794  	case TSLICE:
   795  		return t.Extra.(Slice).Elem
   796  	case TCHAN:
   797  		return t.Extra.(*Chan).Elem
   798  	case TMAP:
   799  		return t.Extra.(*Map).Elem
   800  	}
   801  	Fatalf("Type.Elem %s", t.Etype)
   802  	return nil
   803  }
   804  
   805  // DDDField returns the slice ... type for TDDDFIELD type t.
   806  func (t *Type) DDDField() *Type {
   807  	t.wantEtype(TDDDFIELD)
   808  	return t.Extra.(DDDField).T
   809  }
   810  
   811  // ChanArgs returns the channel type for TCHANARGS type t.
   812  func (t *Type) ChanArgs() *Type {
   813  	t.wantEtype(TCHANARGS)
   814  	return t.Extra.(ChanArgs).T
   815  }
   816  
   817  // FuncArgs returns the func type for TFUNCARGS type t.
   818  func (t *Type) FuncArgs() *Type {
   819  	t.wantEtype(TFUNCARGS)
   820  	return t.Extra.(FuncArgs).T
   821  }
   822  
   823  // Nname returns the associated function's nname.
   824  func (t *Type) Nname() *Node {
   825  	switch t.Etype {
   826  	case TFUNC:
   827  		return t.Extra.(*Func).Nname
   828  	}
   829  	Fatalf("Type.Nname %v %v", t.Etype, t)
   830  	return nil
   831  }
   832  
   833  // Nname sets the associated function's nname.
   834  func (t *Type) SetNname(n *Node) {
   835  	switch t.Etype {
   836  	case TFUNC:
   837  		t.Extra.(*Func).Nname = n
   838  	default:
   839  		Fatalf("Type.SetNname %v %v", t.Etype, t)
   840  	}
   841  }
   842  
   843  // IsFuncArgStruct reports whether t is a struct representing function parameters.
   844  func (t *Type) IsFuncArgStruct() bool {
   845  	return t.Etype == TSTRUCT && t.Extra.(*Struct).Funarg != FunargNone
   846  }
   847  
   848  func (t *Type) Methods() *Fields {
   849  	// TODO(mdempsky): Validate t?
   850  	return &t.methods
   851  }
   852  
   853  func (t *Type) AllMethods() *Fields {
   854  	// TODO(mdempsky): Validate t?
   855  	return &t.allMethods
   856  }
   857  
   858  func (t *Type) Fields() *Fields {
   859  	switch t.Etype {
   860  	case TSTRUCT:
   861  		return &t.Extra.(*Struct).fields
   862  	case TINTER:
   863  		Dowidth(t)
   864  		return &t.Extra.(*Interface).Fields
   865  	}
   866  	Fatalf("Fields: type %v does not have fields", t)
   867  	return nil
   868  }
   869  
   870  // Field returns the i'th field/method of struct/interface type t.
   871  func (t *Type) Field(i int) *Field {
   872  	return t.Fields().Slice()[i]
   873  }
   874  
   875  // FieldSlice returns a slice of containing all fields/methods of
   876  // struct/interface type t.
   877  func (t *Type) FieldSlice() []*Field {
   878  	return t.Fields().Slice()
   879  }
   880  
   881  // SetFields sets struct/interface type t's fields/methods to fields.
   882  func (t *Type) SetFields(fields []*Field) {
   883  	// If we've calculated the width of t before,
   884  	// then some other type such as a function signature
   885  	// might now have the wrong type.
   886  	// Rather than try to track and invalidate those,
   887  	// enforce that SetFields cannot be called once
   888  	// t's width has been calculated.
   889  	if t.WidthCalculated() {
   890  		Fatalf("SetFields of %v: width previously calculated", t)
   891  	}
   892  	t.wantEtype(TSTRUCT)
   893  	for _, f := range fields {
   894  		// If type T contains a field F with a go:notinheap
   895  		// type, then T must also be go:notinheap. Otherwise,
   896  		// you could heap allocate T and then get a pointer F,
   897  		// which would be a heap pointer to a go:notinheap
   898  		// type.
   899  		if f.Type != nil && f.Type.NotInHeap() {
   900  			t.SetNotInHeap(true)
   901  			break
   902  		}
   903  	}
   904  	t.Fields().Set(fields)
   905  }
   906  
   907  func (t *Type) SetInterface(methods []*Field) {
   908  	t.wantEtype(TINTER)
   909  	t.Methods().Set(methods)
   910  }
   911  
   912  func (t *Type) IsDDDArray() bool {
   913  	if t.Etype != TARRAY {
   914  		return false
   915  	}
   916  	return t.Extra.(*Array).Bound < 0
   917  }
   918  
   919  func (t *Type) WidthCalculated() bool {
   920  	return t.Align > 0
   921  }
   922  
   923  // ArgWidth returns the total aligned argument size for a function.
   924  // It includes the receiver, parameters, and results.
   925  func (t *Type) ArgWidth() int64 {
   926  	t.wantEtype(TFUNC)
   927  	return t.Extra.(*Func).Argwid
   928  }
   929  
   930  func (t *Type) Size() int64 {
   931  	if t.Etype == TSSA {
   932  		if t == TypeInt128 {
   933  			return 16
   934  		}
   935  		return 0
   936  	}
   937  	Dowidth(t)
   938  	return t.Width
   939  }
   940  
   941  func (t *Type) Alignment() int64 {
   942  	Dowidth(t)
   943  	return int64(t.Align)
   944  }
   945  
   946  func (t *Type) SimpleString() string {
   947  	return t.Etype.String()
   948  }
   949  
   950  // Cmp is a comparison between values a and b.
   951  // -1 if a < b
   952  //  0 if a == b
   953  //  1 if a > b
   954  type Cmp int8
   955  
   956  const (
   957  	CMPlt = Cmp(-1)
   958  	CMPeq = Cmp(0)
   959  	CMPgt = Cmp(1)
   960  )
   961  
   962  // Compare compares types for purposes of the SSA back
   963  // end, returning a Cmp (one of CMPlt, CMPeq, CMPgt).
   964  // The answers are correct for an optimizer
   965  // or code generator, but not necessarily typechecking.
   966  // The order chosen is arbitrary, only consistency and division
   967  // into equivalence classes (Types that compare CMPeq) matters.
   968  func (t *Type) Compare(x *Type) Cmp {
   969  	if x == t {
   970  		return CMPeq
   971  	}
   972  	return t.cmp(x)
   973  }
   974  
   975  func cmpForNe(x bool) Cmp {
   976  	if x {
   977  		return CMPlt
   978  	}
   979  	return CMPgt
   980  }
   981  
   982  func (r *Sym) cmpsym(s *Sym) Cmp {
   983  	if r == s {
   984  		return CMPeq
   985  	}
   986  	if r == nil {
   987  		return CMPlt
   988  	}
   989  	if s == nil {
   990  		return CMPgt
   991  	}
   992  	// Fast sort, not pretty sort
   993  	if len(r.Name) != len(s.Name) {
   994  		return cmpForNe(len(r.Name) < len(s.Name))
   995  	}
   996  	if r.Pkg != s.Pkg {
   997  		if len(r.Pkg.Prefix) != len(s.Pkg.Prefix) {
   998  			return cmpForNe(len(r.Pkg.Prefix) < len(s.Pkg.Prefix))
   999  		}
  1000  		if r.Pkg.Prefix != s.Pkg.Prefix {
  1001  			return cmpForNe(r.Pkg.Prefix < s.Pkg.Prefix)
  1002  		}
  1003  	}
  1004  	if r.Name != s.Name {
  1005  		return cmpForNe(r.Name < s.Name)
  1006  	}
  1007  	return CMPeq
  1008  }
  1009  
  1010  // cmp compares two *Types t and x, returning CMPlt,
  1011  // CMPeq, CMPgt as t<x, t==x, t>x, for an arbitrary
  1012  // and optimizer-centric notion of comparison.
  1013  // TODO(josharian): make this safe for recursive interface types
  1014  // and use in signatlist sorting. See issue 19869.
  1015  func (t *Type) cmp(x *Type) Cmp {
  1016  	// This follows the structure of eqtype in subr.go
  1017  	// with two exceptions.
  1018  	// 1. Symbols are compared more carefully because a <,=,> result is desired.
  1019  	// 2. Maps are treated specially to avoid endless recursion -- maps
  1020  	//    contain an internal data type not expressible in Go source code.
  1021  	if t == x {
  1022  		return CMPeq
  1023  	}
  1024  	if t == nil {
  1025  		return CMPlt
  1026  	}
  1027  	if x == nil {
  1028  		return CMPgt
  1029  	}
  1030  
  1031  	if t.Etype != x.Etype {
  1032  		return cmpForNe(t.Etype < x.Etype)
  1033  	}
  1034  
  1035  	if t.Sym != nil || x.Sym != nil {
  1036  		// Special case: we keep byte and uint8 separate
  1037  		// for error messages. Treat them as equal.
  1038  		switch t.Etype {
  1039  		case TUINT8:
  1040  			if (t == Types[TUINT8] || t == Bytetype) && (x == Types[TUINT8] || x == Bytetype) {
  1041  				return CMPeq
  1042  			}
  1043  
  1044  		case TINT32:
  1045  			if (t == Types[Runetype.Etype] || t == Runetype) && (x == Types[Runetype.Etype] || x == Runetype) {
  1046  				return CMPeq
  1047  			}
  1048  		}
  1049  	}
  1050  
  1051  	if c := t.Sym.cmpsym(x.Sym); c != CMPeq {
  1052  		return c
  1053  	}
  1054  
  1055  	if x.Sym != nil {
  1056  		// Syms non-nil, if vargens match then equal.
  1057  		if t.Vargen != x.Vargen {
  1058  			return cmpForNe(t.Vargen < x.Vargen)
  1059  		}
  1060  		return CMPeq
  1061  	}
  1062  	// both syms nil, look at structure below.
  1063  
  1064  	switch t.Etype {
  1065  	case TBOOL, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TUNSAFEPTR, TUINTPTR,
  1066  		TINT8, TINT16, TINT32, TINT64, TINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINT:
  1067  		return CMPeq
  1068  
  1069  	case TSSA:
  1070  		tname := t.Extra.(string)
  1071  		xname := t.Extra.(string)
  1072  		// desire fast sorting, not pretty sorting.
  1073  		if len(tname) == len(xname) {
  1074  			if tname == xname {
  1075  				return CMPeq
  1076  			}
  1077  			if tname < xname {
  1078  				return CMPlt
  1079  			}
  1080  			return CMPgt
  1081  		}
  1082  		if len(tname) > len(xname) {
  1083  			return CMPgt
  1084  		}
  1085  		return CMPlt
  1086  
  1087  	case TTUPLE:
  1088  		xtup := x.Extra.(*Tuple)
  1089  		ttup := t.Extra.(*Tuple)
  1090  		if c := ttup.first.Compare(xtup.first); c != CMPeq {
  1091  			return c
  1092  		}
  1093  		return ttup.second.Compare(xtup.second)
  1094  
  1095  	case TMAP:
  1096  		if c := t.Key().cmp(x.Key()); c != CMPeq {
  1097  			return c
  1098  		}
  1099  		return t.Elem().cmp(x.Elem())
  1100  
  1101  	case TPTR, TSLICE:
  1102  		// No special cases for these, they are handled
  1103  		// by the general code after the switch.
  1104  
  1105  	case TSTRUCT:
  1106  		if t.StructType().Map == nil {
  1107  			if x.StructType().Map != nil {
  1108  				return CMPlt // nil < non-nil
  1109  			}
  1110  			// to the fallthrough
  1111  		} else if x.StructType().Map == nil {
  1112  			return CMPgt // nil > non-nil
  1113  		} else if t.StructType().Map.MapType().Bucket == t {
  1114  			// Both have non-nil Map
  1115  			// Special case for Maps which include a recursive type where the recursion is not broken with a named type
  1116  			if x.StructType().Map.MapType().Bucket != x {
  1117  				return CMPlt // bucket maps are least
  1118  			}
  1119  			return t.StructType().Map.cmp(x.StructType().Map)
  1120  		} else if x.StructType().Map.MapType().Bucket == x {
  1121  			return CMPgt // bucket maps are least
  1122  		} // If t != t.Map.Bucket, fall through to general case
  1123  
  1124  		tfs := t.FieldSlice()
  1125  		xfs := x.FieldSlice()
  1126  		for i := 0; i < len(tfs) && i < len(xfs); i++ {
  1127  			t1, x1 := tfs[i], xfs[i]
  1128  			if t1.Embedded != x1.Embedded {
  1129  				return cmpForNe(t1.Embedded < x1.Embedded)
  1130  			}
  1131  			if t1.Note != x1.Note {
  1132  				return cmpForNe(t1.Note < x1.Note)
  1133  			}
  1134  			if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
  1135  				return c
  1136  			}
  1137  			if c := t1.Type.cmp(x1.Type); c != CMPeq {
  1138  				return c
  1139  			}
  1140  		}
  1141  		if len(tfs) != len(xfs) {
  1142  			return cmpForNe(len(tfs) < len(xfs))
  1143  		}
  1144  		return CMPeq
  1145  
  1146  	case TINTER:
  1147  		tfs := t.FieldSlice()
  1148  		xfs := x.FieldSlice()
  1149  		for i := 0; i < len(tfs) && i < len(xfs); i++ {
  1150  			t1, x1 := tfs[i], xfs[i]
  1151  			if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
  1152  				return c
  1153  			}
  1154  			if c := t1.Type.cmp(x1.Type); c != CMPeq {
  1155  				return c
  1156  			}
  1157  		}
  1158  		if len(tfs) != len(xfs) {
  1159  			return cmpForNe(len(tfs) < len(xfs))
  1160  		}
  1161  		return CMPeq
  1162  
  1163  	case TFUNC:
  1164  		for _, f := range RecvsParamsResults {
  1165  			// Loop over fields in structs, ignoring argument names.
  1166  			tfs := f(t).FieldSlice()
  1167  			xfs := f(x).FieldSlice()
  1168  			for i := 0; i < len(tfs) && i < len(xfs); i++ {
  1169  				ta := tfs[i]
  1170  				tb := xfs[i]
  1171  				if ta.IsDDD() != tb.IsDDD() {
  1172  					return cmpForNe(!ta.IsDDD())
  1173  				}
  1174  				if c := ta.Type.cmp(tb.Type); c != CMPeq {
  1175  					return c
  1176  				}
  1177  			}
  1178  			if len(tfs) != len(xfs) {
  1179  				return cmpForNe(len(tfs) < len(xfs))
  1180  			}
  1181  		}
  1182  		return CMPeq
  1183  
  1184  	case TARRAY:
  1185  		if t.NumElem() != x.NumElem() {
  1186  			return cmpForNe(t.NumElem() < x.NumElem())
  1187  		}
  1188  
  1189  	case TCHAN:
  1190  		if t.ChanDir() != x.ChanDir() {
  1191  			return cmpForNe(t.ChanDir() < x.ChanDir())
  1192  		}
  1193  
  1194  	default:
  1195  		e := fmt.Sprintf("Do not know how to compare %v with %v", t, x)
  1196  		panic(e)
  1197  	}
  1198  
  1199  	// Common element type comparison for TARRAY, TCHAN, TPTR, and TSLICE.
  1200  	return t.Elem().cmp(x.Elem())
  1201  }
  1202  
  1203  // IsKind reports whether t is a Type of the specified kind.
  1204  func (t *Type) IsKind(et EType) bool {
  1205  	return t != nil && t.Etype == et
  1206  }
  1207  
  1208  func (t *Type) IsBoolean() bool {
  1209  	return t.Etype == TBOOL
  1210  }
  1211  
  1212  var unsignedEType = [...]EType{
  1213  	TINT8:    TUINT8,
  1214  	TUINT8:   TUINT8,
  1215  	TINT16:   TUINT16,
  1216  	TUINT16:  TUINT16,
  1217  	TINT32:   TUINT32,
  1218  	TUINT32:  TUINT32,
  1219  	TINT64:   TUINT64,
  1220  	TUINT64:  TUINT64,
  1221  	TINT:     TUINT,
  1222  	TUINT:    TUINT,
  1223  	TUINTPTR: TUINTPTR,
  1224  }
  1225  
  1226  // ToUnsigned returns the unsigned equivalent of integer type t.
  1227  func (t *Type) ToUnsigned() *Type {
  1228  	if !t.IsInteger() {
  1229  		Fatalf("unsignedType(%v)", t)
  1230  	}
  1231  	return Types[unsignedEType[t.Etype]]
  1232  }
  1233  
  1234  func (t *Type) IsInteger() bool {
  1235  	switch t.Etype {
  1236  	case TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64, TUINT64, TINT, TUINT, TUINTPTR:
  1237  		return true
  1238  	}
  1239  	return false
  1240  }
  1241  
  1242  func (t *Type) IsSigned() bool {
  1243  	switch t.Etype {
  1244  	case TINT8, TINT16, TINT32, TINT64, TINT:
  1245  		return true
  1246  	}
  1247  	return false
  1248  }
  1249  
  1250  func (t *Type) IsFloat() bool {
  1251  	return t.Etype == TFLOAT32 || t.Etype == TFLOAT64
  1252  }
  1253  
  1254  func (t *Type) IsComplex() bool {
  1255  	return t.Etype == TCOMPLEX64 || t.Etype == TCOMPLEX128
  1256  }
  1257  
  1258  // IsPtr reports whether t is a regular Go pointer type.
  1259  // This does not include unsafe.Pointer.
  1260  func (t *Type) IsPtr() bool {
  1261  	return t.Etype == TPTR
  1262  }
  1263  
  1264  // IsPtrElem reports whether t is the element of a pointer (to t).
  1265  func (t *Type) IsPtrElem() bool {
  1266  	return t.Cache.ptr != nil
  1267  }
  1268  
  1269  // IsUnsafePtr reports whether t is an unsafe pointer.
  1270  func (t *Type) IsUnsafePtr() bool {
  1271  	return t.Etype == TUNSAFEPTR
  1272  }
  1273  
  1274  // IsPtrShaped reports whether t is represented by a single machine pointer.
  1275  // In addition to regular Go pointer types, this includes map, channel, and
  1276  // function types and unsafe.Pointer. It does not include array or struct types
  1277  // that consist of a single pointer shaped type.
  1278  // TODO(mdempsky): Should it? See golang.org/issue/15028.
  1279  func (t *Type) IsPtrShaped() bool {
  1280  	return t.Etype == TPTR || t.Etype == TUNSAFEPTR ||
  1281  		t.Etype == TMAP || t.Etype == TCHAN || t.Etype == TFUNC
  1282  }
  1283  
  1284  func (t *Type) IsString() bool {
  1285  	return t.Etype == TSTRING
  1286  }
  1287  
  1288  func (t *Type) IsMap() bool {
  1289  	return t.Etype == TMAP
  1290  }
  1291  
  1292  func (t *Type) IsChan() bool {
  1293  	return t.Etype == TCHAN
  1294  }
  1295  
  1296  func (t *Type) IsSlice() bool {
  1297  	return t.Etype == TSLICE
  1298  }
  1299  
  1300  func (t *Type) IsArray() bool {
  1301  	return t.Etype == TARRAY
  1302  }
  1303  
  1304  func (t *Type) IsStruct() bool {
  1305  	return t.Etype == TSTRUCT
  1306  }
  1307  
  1308  func (t *Type) IsInterface() bool {
  1309  	return t.Etype == TINTER
  1310  }
  1311  
  1312  // IsEmptyInterface reports whether t is an empty interface type.
  1313  func (t *Type) IsEmptyInterface() bool {
  1314  	return t.IsInterface() && t.NumFields() == 0
  1315  }
  1316  
  1317  func (t *Type) PtrTo() *Type {
  1318  	return NewPtr(t)
  1319  }
  1320  
  1321  func (t *Type) NumFields() int {
  1322  	return t.Fields().Len()
  1323  }
  1324  func (t *Type) FieldType(i int) *Type {
  1325  	if t.Etype == TTUPLE {
  1326  		switch i {
  1327  		case 0:
  1328  			return t.Extra.(*Tuple).first
  1329  		case 1:
  1330  			return t.Extra.(*Tuple).second
  1331  		default:
  1332  			panic("bad tuple index")
  1333  		}
  1334  	}
  1335  	return t.Field(i).Type
  1336  }
  1337  func (t *Type) FieldOff(i int) int64 {
  1338  	return t.Field(i).Offset
  1339  }
  1340  func (t *Type) FieldName(i int) string {
  1341  	return t.Field(i).Sym.Name
  1342  }
  1343  
  1344  func (t *Type) NumElem() int64 {
  1345  	t.wantEtype(TARRAY)
  1346  	at := t.Extra.(*Array)
  1347  	if at.Bound < 0 {
  1348  		Fatalf("NumElem array %v does not have bound yet", t)
  1349  	}
  1350  	return at.Bound
  1351  }
  1352  
  1353  // SetNumElem sets the number of elements in an array type.
  1354  // The only allowed use is on array types created with NewDDDArray.
  1355  // For other uses, create a new array with NewArray instead.
  1356  func (t *Type) SetNumElem(n int64) {
  1357  	t.wantEtype(TARRAY)
  1358  	at := t.Extra.(*Array)
  1359  	if at.Bound >= 0 {
  1360  		Fatalf("SetNumElem array %v already has bound %d", t, at.Bound)
  1361  	}
  1362  	at.Bound = n
  1363  }
  1364  
  1365  type componentsIncludeBlankFields bool
  1366  
  1367  const (
  1368  	IgnoreBlankFields componentsIncludeBlankFields = false
  1369  	CountBlankFields  componentsIncludeBlankFields = true
  1370  )
  1371  
  1372  // NumComponents returns the number of primitive elements that compose t.
  1373  // Struct and array types are flattened for the purpose of counting.
  1374  // All other types (including string, slice, and interface types) count as one element.
  1375  // If countBlank is IgnoreBlankFields, then blank struct fields
  1376  // (and their comprised elements) are excluded from the count.
  1377  // struct { x, y [3]int } has six components; [10]struct{ x, y string } has twenty.
  1378  func (t *Type) NumComponents(countBlank componentsIncludeBlankFields) int64 {
  1379  	switch t.Etype {
  1380  	case TSTRUCT:
  1381  		if t.IsFuncArgStruct() {
  1382  			Fatalf("NumComponents func arg struct")
  1383  		}
  1384  		var n int64
  1385  		for _, f := range t.FieldSlice() {
  1386  			if countBlank == IgnoreBlankFields && f.Sym.IsBlank() {
  1387  				continue
  1388  			}
  1389  			n += f.Type.NumComponents(countBlank)
  1390  		}
  1391  		return n
  1392  	case TARRAY:
  1393  		return t.NumElem() * t.Elem().NumComponents(countBlank)
  1394  	}
  1395  	return 1
  1396  }
  1397  
  1398  // SoleComponent returns the only primitive component in t,
  1399  // if there is exactly one. Otherwise, it returns nil.
  1400  // Components are counted as in NumComponents, including blank fields.
  1401  func (t *Type) SoleComponent() *Type {
  1402  	switch t.Etype {
  1403  	case TSTRUCT:
  1404  		if t.IsFuncArgStruct() {
  1405  			Fatalf("SoleComponent func arg struct")
  1406  		}
  1407  		if t.NumFields() != 1 {
  1408  			return nil
  1409  		}
  1410  		return t.Field(0).Type.SoleComponent()
  1411  	case TARRAY:
  1412  		if t.NumElem() != 1 {
  1413  			return nil
  1414  		}
  1415  		return t.Elem().SoleComponent()
  1416  	}
  1417  	return t
  1418  }
  1419  
  1420  // ChanDir returns the direction of a channel type t.
  1421  // The direction will be one of Crecv, Csend, or Cboth.
  1422  func (t *Type) ChanDir() ChanDir {
  1423  	t.wantEtype(TCHAN)
  1424  	return t.Extra.(*Chan).Dir
  1425  }
  1426  
  1427  func (t *Type) IsMemory() bool {
  1428  	return t == TypeMem || t.Etype == TTUPLE && t.Extra.(*Tuple).second == TypeMem
  1429  }
  1430  func (t *Type) IsFlags() bool { return t == TypeFlags }
  1431  func (t *Type) IsVoid() bool  { return t == TypeVoid }
  1432  func (t *Type) IsTuple() bool { return t.Etype == TTUPLE }
  1433  
  1434  // IsUntyped reports whether t is an untyped type.
  1435  func (t *Type) IsUntyped() bool {
  1436  	if t == nil {
  1437  		return false
  1438  	}
  1439  	if t == Idealstring || t == Idealbool {
  1440  		return true
  1441  	}
  1442  	switch t.Etype {
  1443  	case TNIL, TIDEAL:
  1444  		return true
  1445  	}
  1446  	return false
  1447  }
  1448  
  1449  // TODO(austin): We probably only need HasHeapPointer. See
  1450  // golang.org/cl/73412 for discussion.
  1451  
  1452  func Haspointers(t *Type) bool {
  1453  	return Haspointers1(t, false)
  1454  }
  1455  
  1456  func Haspointers1(t *Type, ignoreNotInHeap bool) bool {
  1457  	switch t.Etype {
  1458  	case TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64,
  1459  		TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL, TSSA:
  1460  		return false
  1461  
  1462  	case TARRAY:
  1463  		if t.NumElem() == 0 { // empty array has no pointers
  1464  			return false
  1465  		}
  1466  		return Haspointers1(t.Elem(), ignoreNotInHeap)
  1467  
  1468  	case TSTRUCT:
  1469  		for _, t1 := range t.Fields().Slice() {
  1470  			if Haspointers1(t1.Type, ignoreNotInHeap) {
  1471  				return true
  1472  			}
  1473  		}
  1474  		return false
  1475  
  1476  	case TPTR, TSLICE:
  1477  		return !(ignoreNotInHeap && t.Elem().NotInHeap())
  1478  
  1479  	case TTUPLE:
  1480  		ttup := t.Extra.(*Tuple)
  1481  		return Haspointers1(ttup.first, ignoreNotInHeap) || Haspointers1(ttup.second, ignoreNotInHeap)
  1482  	}
  1483  
  1484  	return true
  1485  }
  1486  
  1487  // HasHeapPointer reports whether t contains a heap pointer.
  1488  // This is used for write barrier insertion, so it ignores
  1489  // pointers to go:notinheap types.
  1490  func (t *Type) HasHeapPointer() bool {
  1491  	return Haspointers1(t, true)
  1492  }
  1493  
  1494  func (t *Type) Symbol() *obj.LSym {
  1495  	return TypeLinkSym(t)
  1496  }
  1497  
  1498  // Tie returns 'T' if t is a concrete type,
  1499  // 'I' if t is an interface type, and 'E' if t is an empty interface type.
  1500  // It is used to build calls to the conv* and assert* runtime routines.
  1501  func (t *Type) Tie() byte {
  1502  	if t.IsEmptyInterface() {
  1503  		return 'E'
  1504  	}
  1505  	if t.IsInterface() {
  1506  		return 'I'
  1507  	}
  1508  	return 'T'
  1509  }
  1510  
  1511  var recvType *Type
  1512  
  1513  // FakeRecvType returns the singleton type used for interface method receivers.
  1514  func FakeRecvType() *Type {
  1515  	if recvType == nil {
  1516  		recvType = NewPtr(New(TSTRUCT))
  1517  	}
  1518  	return recvType
  1519  }
  1520  
  1521  var (
  1522  	// TSSA types. Haspointers assumes these are pointer-free.
  1523  	TypeInvalid = newSSA("invalid")
  1524  	TypeMem     = newSSA("mem")
  1525  	TypeFlags   = newSSA("flags")
  1526  	TypeVoid    = newSSA("void")
  1527  	TypeInt128  = newSSA("int128")
  1528  )
  1529  

View as plain text