github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/types/type.go (about)

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