github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/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  	"cmd/internal/obj"
     9  	"cmd/internal/src"
    10  	"fmt"
    11  )
    12  
    13  // Dummy Node so we can refer to *Node without actually
    14  // having a gc.Node. Necessary to break import cycles.
    15  // TODO(gri) try to eliminate soon
    16  type Node struct{ _ int }
    17  
    18  //go:generate stringer -type EType -trimprefix T
    19  
    20  // EType describes a kind of type.
    21  type EType uint8
    22  
    23  const (
    24  	Txxx EType = iota
    25  
    26  	TINT8
    27  	TUINT8
    28  	TINT16
    29  	TUINT16
    30  	TINT32
    31  	TUINT32
    32  	TINT64
    33  	TUINT64
    34  	TINT
    35  	TUINT
    36  	TUINTPTR
    37  
    38  	TCOMPLEX64
    39  	TCOMPLEX128
    40  
    41  	TFLOAT32
    42  	TFLOAT64
    43  
    44  	TBOOL
    45  
    46  	TPTR32
    47  	TPTR64
    48  
    49  	TFUNC
    50  	TSLICE
    51  	TARRAY
    52  	TSTRUCT
    53  	TCHAN
    54  	TMAP
    55  	TINTER
    56  	TFORW
    57  	TANY
    58  	TSTRING
    59  	TUNSAFEPTR
    60  
    61  	// pseudo-types for literals
    62  	TIDEAL
    63  	TNIL
    64  	TBLANK
    65  
    66  	// pseudo-types for frame layout
    67  	TFUNCARGS
    68  	TCHANARGS
    69  
    70  	// pseudo-types for import/export
    71  	TDDDFIELD // wrapper: contained type is a ... field
    72  
    73  	// SSA backend types
    74  	TSSA   // internal types used by SSA backend (flags, memory, etc.)
    75  	TTUPLE // a pair of types, used by SSA backend
    76  
    77  	NTYPE
    78  )
    79  
    80  // ChanDir is whether a channel can send, receive, or both.
    81  type ChanDir uint8
    82  
    83  func (c ChanDir) CanRecv() bool { return c&Crecv != 0 }
    84  func (c ChanDir) CanSend() bool { return c&Csend != 0 }
    85  
    86  const (
    87  	// types of channel
    88  	// must match ../../../../reflect/type.go:/ChanDir
    89  	Crecv ChanDir = 1 << 0
    90  	Csend ChanDir = 1 << 1
    91  	Cboth ChanDir = Crecv | Csend
    92  )
    93  
    94  // Types stores pointers to predeclared named types.
    95  //
    96  // It also stores pointers to several special types:
    97  //   - Types[TANY] is the placeholder "any" type recognized by substArgTypes.
    98  //   - Types[TBLANK] represents the blank variable's type.
    99  //   - Types[TIDEAL] represents untyped numeric constants.
   100  //   - Types[TNIL] represents the predeclared "nil" value's type.
   101  //   - Types[TUNSAFEPTR] is package unsafe's Pointer type.
   102  var Types [NTYPE]*Type
   103  
   104  var (
   105  	// Predeclared alias types. Kept separate for better error messages.
   106  	Bytetype *Type
   107  	Runetype *Type
   108  
   109  	// Predeclared error interface type.
   110  	Errortype *Type
   111  
   112  	// Types to represent untyped string and boolean constants.
   113  	Idealstring *Type
   114  	Idealbool   *Type
   115  
   116  	// Types to represent untyped numeric constants.
   117  	// Note: Currently these are only used within the binary export
   118  	// data format. The rest of the compiler only uses Types[TIDEAL].
   119  	Idealint     = New(TIDEAL)
   120  	Idealrune    = New(TIDEAL)
   121  	Idealfloat   = New(TIDEAL)
   122  	Idealcomplex = New(TIDEAL)
   123  )
   124  
   125  // A Type represents a Go type.
   126  type Type struct {
   127  	// Extra contains extra etype-specific fields.
   128  	// As an optimization, those etype-specific structs which contain exactly
   129  	// one pointer-shaped field are stored as values rather than pointers when possible.
   130  	//
   131  	// TMAP: *Map
   132  	// TFORW: *Forward
   133  	// TFUNC: *Func
   134  	// TSTRUCT: *Struct
   135  	// TINTER: *Inter
   136  	// TDDDFIELD: DDDField
   137  	// TFUNCARGS: FuncArgs
   138  	// TCHANARGS: ChanArgs
   139  	// TCHAN: *Chan
   140  	// TPTR32, TPTR64: Ptr
   141  	// TARRAY: *Array
   142  	// TSLICE: Slice
   143  	Extra interface{}
   144  
   145  	// Width is the width of this Type in bytes.
   146  	Width int64
   147  
   148  	methods    Fields
   149  	allMethods Fields
   150  
   151  	Nod  *Node // canonical OTYPE node
   152  	Orig *Type // original type (type literal or predefined type)
   153  
   154  	SliceOf *Type
   155  	PtrBase *Type
   156  
   157  	Sym    *Sym  // symbol containing name, for named types
   158  	Vargen int32 // unique name for OTYPE/ONAME
   159  
   160  	Etype EType // kind of type
   161  	Align uint8 // the required alignment of this type, in bytes
   162  
   163  	flags bitset8
   164  }
   165  
   166  const (
   167  	typeNotInHeap = 1 << iota // type cannot be heap allocated
   168  	typeBroke                 // broken type definition
   169  	typeNoalg                 // suppress hash and eq algorithm generation
   170  	typeDeferwidth
   171  	typeRecur
   172  )
   173  
   174  func (t *Type) NotInHeap() bool  { return t.flags&typeNotInHeap != 0 }
   175  func (t *Type) Broke() bool      { return t.flags&typeBroke != 0 }
   176  func (t *Type) Noalg() bool      { return t.flags&typeNoalg != 0 }
   177  func (t *Type) Deferwidth() bool { return t.flags&typeDeferwidth != 0 }
   178  func (t *Type) Recur() bool      { return t.flags&typeRecur != 0 }
   179  
   180  func (t *Type) SetNotInHeap(b bool)  { t.flags.set(typeNotInHeap, b) }
   181  func (t *Type) SetBroke(b bool)      { t.flags.set(typeBroke, b) }
   182  func (t *Type) SetNoalg(b bool)      { t.flags.set(typeNoalg, b) }
   183  func (t *Type) SetDeferwidth(b bool) { t.flags.set(typeDeferwidth, b) }
   184  func (t *Type) SetRecur(b bool)      { t.flags.set(typeRecur, b) }
   185  
   186  // Map contains Type fields specific to maps.
   187  type Map struct {
   188  	Key *Type // Key type
   189  	Val *Type // Val (elem) type
   190  
   191  	Bucket *Type // internal struct type representing a hash bucket
   192  	Hmap   *Type // internal struct type representing the Hmap (map header object)
   193  	Hiter  *Type // internal struct type representing hash iterator state
   194  }
   195  
   196  // MapType returns t's extra map-specific fields.
   197  func (t *Type) MapType() *Map {
   198  	t.wantEtype(TMAP)
   199  	return t.Extra.(*Map)
   200  }
   201  
   202  // Forward contains Type fields specific to forward types.
   203  type Forward struct {
   204  	Copyto      []*Node  // where to copy the eventual value to
   205  	Embedlineno src.XPos // first use of this type as an embedded type
   206  }
   207  
   208  // ForwardType returns t's extra forward-type-specific fields.
   209  func (t *Type) ForwardType() *Forward {
   210  	t.wantEtype(TFORW)
   211  	return t.Extra.(*Forward)
   212  }
   213  
   214  // Func contains Type fields specific to func types.
   215  type Func struct {
   216  	Receiver *Type // function receiver
   217  	Results  *Type // function results
   218  	Params   *Type // function params
   219  
   220  	Nname *Node
   221  
   222  	// Argwid is the total width of the function receiver, params, and results.
   223  	// It gets calculated via a temporary TFUNCARGS type.
   224  	// Note that TFUNC's Width is Widthptr.
   225  	Argwid int64
   226  
   227  	Outnamed bool
   228  }
   229  
   230  // FuncType returns t's extra func-specific fields.
   231  func (t *Type) FuncType() *Func {
   232  	t.wantEtype(TFUNC)
   233  	return t.Extra.(*Func)
   234  }
   235  
   236  // StructType contains Type fields specific to struct types.
   237  type Struct struct {
   238  	fields Fields
   239  
   240  	// Maps have three associated internal structs (see struct MapType).
   241  	// Map links such structs back to their map type.
   242  	Map *Type
   243  
   244  	Funarg Funarg // type of function arguments for arg struct
   245  }
   246  
   247  // Fnstruct records the kind of function argument
   248  type Funarg uint8
   249  
   250  const (
   251  	FunargNone    Funarg = iota
   252  	FunargRcvr           // receiver
   253  	FunargParams         // input parameters
   254  	FunargResults        // output results
   255  )
   256  
   257  // StructType returns t's extra struct-specific fields.
   258  func (t *Type) StructType() *Struct {
   259  	t.wantEtype(TSTRUCT)
   260  	return t.Extra.(*Struct)
   261  }
   262  
   263  // Interface contains Type fields specific to interface types.
   264  type Interface struct {
   265  	Fields Fields
   266  }
   267  
   268  // Ptr contains Type fields specific to pointer types.
   269  type Ptr struct {
   270  	Elem *Type // element type
   271  }
   272  
   273  // DDDField contains Type fields specific to TDDDFIELD types.
   274  type DDDField struct {
   275  	T *Type // reference to a slice type for ... args
   276  }
   277  
   278  // ChanArgs contains Type fields specific to TCHANARGS types.
   279  type ChanArgs struct {
   280  	T *Type // reference to a chan type whose elements need a width check
   281  }
   282  
   283  // // FuncArgs contains Type fields specific to TFUNCARGS types.
   284  type FuncArgs struct {
   285  	T *Type // reference to a func type whose elements need a width check
   286  }
   287  
   288  // Chan contains Type fields specific to channel types.
   289  type Chan struct {
   290  	Elem *Type   // element type
   291  	Dir  ChanDir // channel direction
   292  }
   293  
   294  // ChanType returns t's extra channel-specific fields.
   295  func (t *Type) ChanType() *Chan {
   296  	t.wantEtype(TCHAN)
   297  	return t.Extra.(*Chan)
   298  }
   299  
   300  type Tuple struct {
   301  	first  *Type
   302  	second *Type
   303  	// Any tuple with a memory type must put that memory type second.
   304  }
   305  
   306  // Array contains Type fields specific to array types.
   307  type Array struct {
   308  	Elem  *Type // element type
   309  	Bound int64 // number of elements; <0 if unknown yet
   310  }
   311  
   312  // Slice contains Type fields specific to slice types.
   313  type Slice struct {
   314  	Elem *Type // element type
   315  }
   316  
   317  // A Field represents a field in a struct or a method in an interface or
   318  // associated with a named type.
   319  type Field struct {
   320  	flags bitset8
   321  
   322  	Embedded uint8 // embedded field
   323  	Funarg   Funarg
   324  
   325  	Sym   *Sym
   326  	Nname *Node
   327  
   328  	Type *Type // field type
   329  
   330  	// Offset in bytes of this field or method within its enclosing struct
   331  	// or interface Type.
   332  	Offset int64
   333  
   334  	Note string // literal string annotation
   335  }
   336  
   337  const (
   338  	fieldIsddd = 1 << iota // field is ... argument
   339  	fieldBroke             // broken field definition
   340  	fieldNointerface
   341  )
   342  
   343  func (f *Field) Isddd() bool       { return f.flags&fieldIsddd != 0 }
   344  func (f *Field) Broke() bool       { return f.flags&fieldBroke != 0 }
   345  func (f *Field) Nointerface() bool { return f.flags&fieldNointerface != 0 }
   346  
   347  func (f *Field) SetIsddd(b bool)       { f.flags.set(fieldIsddd, b) }
   348  func (f *Field) SetBroke(b bool)       { f.flags.set(fieldBroke, b) }
   349  func (f *Field) SetNointerface(b bool) { f.flags.set(fieldNointerface, b) }
   350  
   351  // End returns the offset of the first byte immediately after this field.
   352  func (f *Field) End() int64 {
   353  	return f.Offset + f.Type.Width
   354  }
   355  
   356  // Fields is a pointer to a slice of *Field.
   357  // This saves space in Types that do not have fields or methods
   358  // compared to a simple slice of *Field.
   359  type Fields struct {
   360  	s *[]*Field
   361  }
   362  
   363  // Len returns the number of entries in f.
   364  func (f *Fields) Len() int {
   365  	if f.s == nil {
   366  		return 0
   367  	}
   368  	return len(*f.s)
   369  }
   370  
   371  // Slice returns the entries in f as a slice.
   372  // Changes to the slice entries will be reflected in f.
   373  func (f *Fields) Slice() []*Field {
   374  	if f.s == nil {
   375  		return nil
   376  	}
   377  	return *f.s
   378  }
   379  
   380  // Index returns the i'th element of Fields.
   381  // It panics if f does not have at least i+1 elements.
   382  func (f *Fields) Index(i int) *Field {
   383  	return (*f.s)[i]
   384  }
   385  
   386  // Set sets f to a slice.
   387  // This takes ownership of the slice.
   388  func (f *Fields) Set(s []*Field) {
   389  	if len(s) == 0 {
   390  		f.s = nil
   391  	} else {
   392  		// Copy s and take address of t rather than s to avoid
   393  		// allocation in the case where len(s) == 0.
   394  		t := s
   395  		f.s = &t
   396  	}
   397  }
   398  
   399  // Append appends entries to f.
   400  func (f *Fields) Append(s ...*Field) {
   401  	if f.s == nil {
   402  		f.s = new([]*Field)
   403  	}
   404  	*f.s = append(*f.s, s...)
   405  }
   406  
   407  // New returns a new Type of the specified kind.
   408  func New(et EType) *Type {
   409  	t := &Type{
   410  		Etype: et,
   411  		Width: BADWIDTH,
   412  	}
   413  	t.Orig = t
   414  	// TODO(josharian): lazily initialize some of these?
   415  	switch t.Etype {
   416  	case TMAP:
   417  		t.Extra = new(Map)
   418  	case TFORW:
   419  		t.Extra = new(Forward)
   420  	case TFUNC:
   421  		t.Extra = new(Func)
   422  	case TSTRUCT:
   423  		t.Extra = new(Struct)
   424  	case TINTER:
   425  		t.Extra = new(Interface)
   426  	case TPTR32, TPTR64:
   427  		t.Extra = Ptr{}
   428  	case TCHANARGS:
   429  		t.Extra = ChanArgs{}
   430  	case TFUNCARGS:
   431  		t.Extra = FuncArgs{}
   432  	case TDDDFIELD:
   433  		t.Extra = DDDField{}
   434  	case TCHAN:
   435  		t.Extra = new(Chan)
   436  	case TTUPLE:
   437  		t.Extra = new(Tuple)
   438  	}
   439  	return t
   440  }
   441  
   442  // NewArray returns a new fixed-length array Type.
   443  func NewArray(elem *Type, bound int64) *Type {
   444  	if bound < 0 {
   445  		Fatalf("NewArray: invalid bound %v", bound)
   446  	}
   447  	t := New(TARRAY)
   448  	t.Extra = &Array{Elem: elem, Bound: bound}
   449  	t.SetNotInHeap(elem.NotInHeap())
   450  	return t
   451  }
   452  
   453  // NewSlice returns the slice Type with element type elem.
   454  func NewSlice(elem *Type) *Type {
   455  	if t := elem.SliceOf; t != nil {
   456  		if t.Elem() != elem {
   457  			Fatalf("elem mismatch")
   458  		}
   459  		return t
   460  	}
   461  
   462  	t := New(TSLICE)
   463  	t.Extra = Slice{Elem: elem}
   464  	elem.SliceOf = t
   465  	return t
   466  }
   467  
   468  // NewDDDArray returns a new [...]T array Type.
   469  func NewDDDArray(elem *Type) *Type {
   470  	t := New(TARRAY)
   471  	t.Extra = &Array{Elem: elem, Bound: -1}
   472  	t.SetNotInHeap(elem.NotInHeap())
   473  	return t
   474  }
   475  
   476  // NewChan returns a new chan Type with direction dir.
   477  func NewChan(elem *Type, dir ChanDir) *Type {
   478  	t := New(TCHAN)
   479  	ct := t.ChanType()
   480  	ct.Elem = elem
   481  	ct.Dir = dir
   482  	return t
   483  }
   484  
   485  func NewTuple(t1, t2 *Type) *Type {
   486  	t := New(TTUPLE)
   487  	t.Extra.(*Tuple).first = t1
   488  	t.Extra.(*Tuple).second = t2
   489  	return t
   490  }
   491  
   492  func newSSA(name string) *Type {
   493  	t := New(TSSA)
   494  	t.Extra = name
   495  	return t
   496  }
   497  
   498  // NewMap returns a new map Type with key type k and element (aka value) type v.
   499  func NewMap(k, v *Type) *Type {
   500  	t := New(TMAP)
   501  	mt := t.MapType()
   502  	mt.Key = k
   503  	mt.Val = v
   504  	return t
   505  }
   506  
   507  // NewPtrCacheEnabled controls whether *T Types are cached in T.
   508  // Caching is disabled just before starting the backend.
   509  // This allows the backend to run concurrently.
   510  var NewPtrCacheEnabled = true
   511  
   512  // NewPtr returns the pointer type pointing to t.
   513  func NewPtr(elem *Type) *Type {
   514  	if elem == nil {
   515  		Fatalf("NewPtr: pointer to elem Type is nil")
   516  	}
   517  
   518  	if t := elem.PtrBase; t != nil {
   519  		if t.Elem() != elem {
   520  			Fatalf("NewPtr: elem mismatch")
   521  		}
   522  		return t
   523  	}
   524  
   525  	if Tptr == 0 {
   526  		Fatalf("NewPtr: Tptr not initialized")
   527  	}
   528  
   529  	t := New(Tptr)
   530  	t.Extra = Ptr{Elem: elem}
   531  	t.Width = int64(Widthptr)
   532  	t.Align = uint8(Widthptr)
   533  	if NewPtrCacheEnabled {
   534  		elem.PtrBase = t
   535  	}
   536  	return t
   537  }
   538  
   539  // NewDDDField returns a new TDDDFIELD type for slice type s.
   540  func NewDDDField(s *Type) *Type {
   541  	t := New(TDDDFIELD)
   542  	t.Extra = DDDField{T: s}
   543  	return t
   544  }
   545  
   546  // NewChanArgs returns a new TCHANARGS type for channel type c.
   547  func NewChanArgs(c *Type) *Type {
   548  	t := New(TCHANARGS)
   549  	t.Extra = ChanArgs{T: c}
   550  	return t
   551  }
   552  
   553  // NewFuncArgs returns a new TFUNCARGS type for func type f.
   554  func NewFuncArgs(f *Type) *Type {
   555  	t := New(TFUNCARGS)
   556  	t.Extra = FuncArgs{T: f}
   557  	return t
   558  }
   559  
   560  func NewField() *Field {
   561  	return &Field{
   562  		Offset: BADWIDTH,
   563  	}
   564  }
   565  
   566  // SubstAny walks t, replacing instances of "any" with successive
   567  // elements removed from types.  It returns the substituted type.
   568  func SubstAny(t *Type, types *[]*Type) *Type {
   569  	if t == nil {
   570  		return nil
   571  	}
   572  
   573  	switch t.Etype {
   574  	default:
   575  		// Leave the type unchanged.
   576  
   577  	case TANY:
   578  		if len(*types) == 0 {
   579  			Fatalf("substArgTypes: not enough argument types")
   580  		}
   581  		t = (*types)[0]
   582  		*types = (*types)[1:]
   583  
   584  	case TPTR32, TPTR64:
   585  		elem := SubstAny(t.Elem(), types)
   586  		if elem != t.Elem() {
   587  			t = t.copy()
   588  			t.Extra = Ptr{Elem: elem}
   589  		}
   590  
   591  	case TARRAY:
   592  		elem := SubstAny(t.Elem(), types)
   593  		if elem != t.Elem() {
   594  			t = t.copy()
   595  			t.Extra.(*Array).Elem = elem
   596  		}
   597  
   598  	case TSLICE:
   599  		elem := SubstAny(t.Elem(), types)
   600  		if elem != t.Elem() {
   601  			t = t.copy()
   602  			t.Extra = Slice{Elem: elem}
   603  		}
   604  
   605  	case TCHAN:
   606  		elem := SubstAny(t.Elem(), types)
   607  		if elem != t.Elem() {
   608  			t = t.copy()
   609  			t.Extra.(*Chan).Elem = elem
   610  		}
   611  
   612  	case TMAP:
   613  		key := SubstAny(t.Key(), types)
   614  		val := SubstAny(t.Val(), types)
   615  		if key != t.Key() || val != t.Val() {
   616  			t = t.copy()
   617  			t.Extra.(*Map).Key = key
   618  			t.Extra.(*Map).Val = val
   619  		}
   620  
   621  	case TFUNC:
   622  		recvs := SubstAny(t.Recvs(), types)
   623  		params := SubstAny(t.Params(), types)
   624  		results := SubstAny(t.Results(), types)
   625  		if recvs != t.Recvs() || params != t.Params() || results != t.Results() {
   626  			t = t.copy()
   627  			t.FuncType().Receiver = recvs
   628  			t.FuncType().Results = results
   629  			t.FuncType().Params = params
   630  		}
   631  
   632  	case TSTRUCT:
   633  		fields := t.FieldSlice()
   634  		var nfs []*Field
   635  		for i, f := range fields {
   636  			nft := SubstAny(f.Type, types)
   637  			if nft == f.Type {
   638  				continue
   639  			}
   640  			if nfs == nil {
   641  				nfs = append([]*Field(nil), fields...)
   642  			}
   643  			nfs[i] = f.Copy()
   644  			nfs[i].Type = nft
   645  		}
   646  		if nfs != nil {
   647  			t = t.copy()
   648  			t.SetFields(nfs)
   649  		}
   650  	}
   651  
   652  	return t
   653  }
   654  
   655  // copy returns a shallow copy of the Type.
   656  func (t *Type) copy() *Type {
   657  	if t == nil {
   658  		return nil
   659  	}
   660  	nt := *t
   661  	// copy any *T Extra fields, to avoid aliasing
   662  	switch t.Etype {
   663  	case TMAP:
   664  		x := *t.Extra.(*Map)
   665  		nt.Extra = &x
   666  	case TFORW:
   667  		x := *t.Extra.(*Forward)
   668  		nt.Extra = &x
   669  	case TFUNC:
   670  		x := *t.Extra.(*Func)
   671  		nt.Extra = &x
   672  	case TSTRUCT:
   673  		x := *t.Extra.(*Struct)
   674  		nt.Extra = &x
   675  	case TINTER:
   676  		x := *t.Extra.(*Interface)
   677  		nt.Extra = &x
   678  	case TCHAN:
   679  		x := *t.Extra.(*Chan)
   680  		nt.Extra = &x
   681  	case TARRAY:
   682  		x := *t.Extra.(*Array)
   683  		nt.Extra = &x
   684  	case TTUPLE, TSSA:
   685  		Fatalf("ssa types cannot be copied")
   686  	}
   687  	// TODO(mdempsky): Find out why this is necessary and explain.
   688  	if t.Orig == t {
   689  		nt.Orig = &nt
   690  	}
   691  	return &nt
   692  }
   693  
   694  func (f *Field) Copy() *Field {
   695  	nf := *f
   696  	return &nf
   697  }
   698  
   699  func (t *Type) wantEtype(et EType) {
   700  	if t.Etype != et {
   701  		Fatalf("want %v, but have %v", et, t)
   702  	}
   703  }
   704  
   705  func (t *Type) Recvs() *Type   { return t.FuncType().Receiver }
   706  func (t *Type) Params() *Type  { return t.FuncType().Params }
   707  func (t *Type) Results() *Type { return t.FuncType().Results }
   708  
   709  func (t *Type) NumRecvs() int   { return t.FuncType().Receiver.NumFields() }
   710  func (t *Type) NumParams() int  { return t.FuncType().Params.NumFields() }
   711  func (t *Type) NumResults() int { return t.FuncType().Results.NumFields() }
   712  
   713  // Recv returns the receiver of function type t, if any.
   714  func (t *Type) Recv() *Field {
   715  	s := t.Recvs()
   716  	if s.NumFields() == 0 {
   717  		return nil
   718  	}
   719  	return s.Field(0)
   720  }
   721  
   722  // RecvsParamsResults stores the accessor functions for a function Type's
   723  // receiver, parameters, and result parameters, in that order.
   724  // It can be used to iterate over all of a function's parameter lists.
   725  var RecvsParamsResults = [3]func(*Type) *Type{
   726  	(*Type).Recvs, (*Type).Params, (*Type).Results,
   727  }
   728  
   729  // ParamsResults is like RecvsParamsResults, but omits receiver parameters.
   730  var ParamsResults = [2]func(*Type) *Type{
   731  	(*Type).Params, (*Type).Results,
   732  }
   733  
   734  // Key returns the key type of map type t.
   735  func (t *Type) Key() *Type {
   736  	t.wantEtype(TMAP)
   737  	return t.Extra.(*Map).Key
   738  }
   739  
   740  // Val returns the value type of map type t.
   741  func (t *Type) Val() *Type {
   742  	t.wantEtype(TMAP)
   743  	return t.Extra.(*Map).Val
   744  }
   745  
   746  // Elem returns the type of elements of t.
   747  // Usable with pointers, channels, arrays, and slices.
   748  func (t *Type) Elem() *Type {
   749  	switch t.Etype {
   750  	case TPTR32, TPTR64:
   751  		return t.Extra.(Ptr).Elem
   752  	case TARRAY:
   753  		return t.Extra.(*Array).Elem
   754  	case TSLICE:
   755  		return t.Extra.(Slice).Elem
   756  	case TCHAN:
   757  		return t.Extra.(*Chan).Elem
   758  	}
   759  	Fatalf("Type.Elem %s", t.Etype)
   760  	return nil
   761  }
   762  
   763  // DDDField returns the slice ... type for TDDDFIELD type t.
   764  func (t *Type) DDDField() *Type {
   765  	t.wantEtype(TDDDFIELD)
   766  	return t.Extra.(DDDField).T
   767  }
   768  
   769  // ChanArgs returns the channel type for TCHANARGS type t.
   770  func (t *Type) ChanArgs() *Type {
   771  	t.wantEtype(TCHANARGS)
   772  	return t.Extra.(ChanArgs).T
   773  }
   774  
   775  // FuncArgs returns the channel type for TFUNCARGS type t.
   776  func (t *Type) FuncArgs() *Type {
   777  	t.wantEtype(TFUNCARGS)
   778  	return t.Extra.(FuncArgs).T
   779  }
   780  
   781  // Nname returns the associated function's nname.
   782  func (t *Type) Nname() *Node {
   783  	switch t.Etype {
   784  	case TFUNC:
   785  		return t.Extra.(*Func).Nname
   786  	}
   787  	Fatalf("Type.Nname %v %v", t.Etype, t)
   788  	return nil
   789  }
   790  
   791  // Nname sets the associated function's nname.
   792  func (t *Type) SetNname(n *Node) {
   793  	switch t.Etype {
   794  	case TFUNC:
   795  		t.Extra.(*Func).Nname = n
   796  	default:
   797  		Fatalf("Type.SetNname %v %v", t.Etype, t)
   798  	}
   799  }
   800  
   801  // IsFuncArgStruct reports whether t is a struct representing function parameters.
   802  func (t *Type) IsFuncArgStruct() bool {
   803  	return t.Etype == TSTRUCT && t.Extra.(*Struct).Funarg != FunargNone
   804  }
   805  
   806  func (t *Type) Methods() *Fields {
   807  	// TODO(mdempsky): Validate t?
   808  	return &t.methods
   809  }
   810  
   811  func (t *Type) AllMethods() *Fields {
   812  	// TODO(mdempsky): Validate t?
   813  	return &t.allMethods
   814  }
   815  
   816  func (t *Type) Fields() *Fields {
   817  	switch t.Etype {
   818  	case TSTRUCT:
   819  		return &t.Extra.(*Struct).fields
   820  	case TINTER:
   821  		Dowidth(t)
   822  		return &t.Extra.(*Interface).Fields
   823  	}
   824  	Fatalf("Fields: type %v does not have fields", t)
   825  	return nil
   826  }
   827  
   828  // Field returns the i'th field/method of struct/interface type t.
   829  func (t *Type) Field(i int) *Field {
   830  	return t.Fields().Slice()[i]
   831  }
   832  
   833  // FieldSlice returns a slice of containing all fields/methods of
   834  // struct/interface type t.
   835  func (t *Type) FieldSlice() []*Field {
   836  	return t.Fields().Slice()
   837  }
   838  
   839  // SetFields sets struct/interface type t's fields/methods to fields.
   840  func (t *Type) SetFields(fields []*Field) {
   841  	// If we've calculated the width of t before,
   842  	// then some other type such as a function signature
   843  	// might now have the wrong type.
   844  	// Rather than try to track and invalidate those,
   845  	// enforce that SetFields cannot be called once
   846  	// t's width has been calculated.
   847  	if t.WidthCalculated() {
   848  		Fatalf("SetFields of %v: width previously calculated", t)
   849  	}
   850  	t.wantEtype(TSTRUCT)
   851  	for _, f := range fields {
   852  		// If type T contains a field F with a go:notinheap
   853  		// type, then T must also be go:notinheap. Otherwise,
   854  		// you could heap allocate T and then get a pointer F,
   855  		// which would be a heap pointer to a go:notinheap
   856  		// type.
   857  		if f.Type != nil && f.Type.NotInHeap() {
   858  			t.SetNotInHeap(true)
   859  			break
   860  		}
   861  	}
   862  	t.Fields().Set(fields)
   863  }
   864  
   865  func (t *Type) SetInterface(methods []*Field) {
   866  	t.wantEtype(TINTER)
   867  	t.Methods().Set(methods)
   868  }
   869  
   870  func (t *Type) IsDDDArray() bool {
   871  	if t.Etype != TARRAY {
   872  		return false
   873  	}
   874  	return t.Extra.(*Array).Bound < 0
   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 eqtype in subr.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.Val().cmp(x.Val())
  1058  
  1059  	case TPTR32, TPTR64, 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, TPTR32, TPTR64, 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 == TPTR32 || t.Etype == TPTR64
  1220  }
  1221  
  1222  // IsUnsafePtr reports whether t is an unsafe pointer.
  1223  func (t *Type) IsUnsafePtr() bool {
  1224  	return t.Etype == TUNSAFEPTR
  1225  }
  1226  
  1227  // IsPtrShaped reports whether t is represented by a single machine pointer.
  1228  // In addition to regular Go pointer types, this includes map, channel, and
  1229  // function types and unsafe.Pointer. It does not include array or struct types
  1230  // that consist of a single pointer shaped type.
  1231  // TODO(mdempsky): Should it? See golang.org/issue/15028.
  1232  func (t *Type) IsPtrShaped() bool {
  1233  	return t.Etype == TPTR32 || t.Etype == TPTR64 || t.Etype == TUNSAFEPTR ||
  1234  		t.Etype == TMAP || t.Etype == TCHAN || t.Etype == TFUNC
  1235  }
  1236  
  1237  func (t *Type) IsString() bool {
  1238  	return t.Etype == TSTRING
  1239  }
  1240  
  1241  func (t *Type) IsMap() bool {
  1242  	return t.Etype == TMAP
  1243  }
  1244  
  1245  func (t *Type) IsChan() bool {
  1246  	return t.Etype == TCHAN
  1247  }
  1248  
  1249  func (t *Type) IsSlice() bool {
  1250  	return t.Etype == TSLICE
  1251  }
  1252  
  1253  func (t *Type) IsArray() bool {
  1254  	return t.Etype == TARRAY
  1255  }
  1256  
  1257  func (t *Type) IsStruct() bool {
  1258  	return t.Etype == TSTRUCT
  1259  }
  1260  
  1261  func (t *Type) IsInterface() bool {
  1262  	return t.Etype == TINTER
  1263  }
  1264  
  1265  // IsEmptyInterface reports whether t is an empty interface type.
  1266  func (t *Type) IsEmptyInterface() bool {
  1267  	return t.IsInterface() && t.NumFields() == 0
  1268  }
  1269  
  1270  func (t *Type) ElemType() *Type {
  1271  	// TODO(josharian): If Type ever moves to a shared
  1272  	// internal package, remove this silly wrapper.
  1273  	return t.Elem()
  1274  }
  1275  func (t *Type) PtrTo() *Type {
  1276  	return NewPtr(t)
  1277  }
  1278  
  1279  func (t *Type) NumFields() int {
  1280  	return t.Fields().Len()
  1281  }
  1282  func (t *Type) FieldType(i int) *Type {
  1283  	if t.Etype == TTUPLE {
  1284  		switch i {
  1285  		case 0:
  1286  			return t.Extra.(*Tuple).first
  1287  		case 1:
  1288  			return t.Extra.(*Tuple).second
  1289  		default:
  1290  			panic("bad tuple index")
  1291  		}
  1292  	}
  1293  	return t.Field(i).Type
  1294  }
  1295  func (t *Type) FieldOff(i int) int64 {
  1296  	return t.Field(i).Offset
  1297  }
  1298  func (t *Type) FieldName(i int) string {
  1299  	return t.Field(i).Sym.Name
  1300  }
  1301  
  1302  func (t *Type) NumElem() int64 {
  1303  	t.wantEtype(TARRAY)
  1304  	at := t.Extra.(*Array)
  1305  	if at.Bound < 0 {
  1306  		Fatalf("NumElem array %v does not have bound yet", t)
  1307  	}
  1308  	return at.Bound
  1309  }
  1310  
  1311  // SetNumElem sets the number of elements in an array type.
  1312  // The only allowed use is on array types created with NewDDDArray.
  1313  // For other uses, create a new array with NewArray instead.
  1314  func (t *Type) SetNumElem(n int64) {
  1315  	t.wantEtype(TARRAY)
  1316  	at := t.Extra.(*Array)
  1317  	if at.Bound >= 0 {
  1318  		Fatalf("SetNumElem array %v already has bound %d", t, at.Bound)
  1319  	}
  1320  	at.Bound = n
  1321  }
  1322  
  1323  func (t *Type) NumComponents() int64 {
  1324  	switch t.Etype {
  1325  	case TSTRUCT:
  1326  		if t.IsFuncArgStruct() {
  1327  			Fatalf("NumComponents func arg struct")
  1328  		}
  1329  		var n int64
  1330  		for _, f := range t.FieldSlice() {
  1331  			n += f.Type.NumComponents()
  1332  		}
  1333  		return n
  1334  	case TARRAY:
  1335  		return t.NumElem() * t.Elem().NumComponents()
  1336  	}
  1337  	return 1
  1338  }
  1339  
  1340  // ChanDir returns the direction of a channel type t.
  1341  // The direction will be one of Crecv, Csend, or Cboth.
  1342  func (t *Type) ChanDir() ChanDir {
  1343  	t.wantEtype(TCHAN)
  1344  	return t.Extra.(*Chan).Dir
  1345  }
  1346  
  1347  func (t *Type) IsMemory() bool {
  1348  	return t == TypeMem || t.Etype == TTUPLE && t.Extra.(*Tuple).second == TypeMem
  1349  }
  1350  func (t *Type) IsFlags() bool { return t == TypeFlags }
  1351  func (t *Type) IsVoid() bool  { return t == TypeVoid }
  1352  func (t *Type) IsTuple() bool { return t.Etype == TTUPLE }
  1353  
  1354  // IsUntyped reports whether t is an untyped type.
  1355  func (t *Type) IsUntyped() bool {
  1356  	if t == nil {
  1357  		return false
  1358  	}
  1359  	if t == Idealstring || t == Idealbool {
  1360  		return true
  1361  	}
  1362  	switch t.Etype {
  1363  	case TNIL, TIDEAL:
  1364  		return true
  1365  	}
  1366  	return false
  1367  }
  1368  
  1369  // TODO(austin): We probably only need HasHeapPointer. See
  1370  // golang.org/cl/73412 for discussion.
  1371  
  1372  func Haspointers(t *Type) bool {
  1373  	return Haspointers1(t, false)
  1374  }
  1375  
  1376  func Haspointers1(t *Type, ignoreNotInHeap bool) bool {
  1377  	switch t.Etype {
  1378  	case TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64,
  1379  		TUINT64, TUINTPTR, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TBOOL:
  1380  		return false
  1381  
  1382  	case TARRAY:
  1383  		if t.NumElem() == 0 { // empty array has no pointers
  1384  			return false
  1385  		}
  1386  		return Haspointers1(t.Elem(), ignoreNotInHeap)
  1387  
  1388  	case TSTRUCT:
  1389  		for _, t1 := range t.Fields().Slice() {
  1390  			if Haspointers1(t1.Type, ignoreNotInHeap) {
  1391  				return true
  1392  			}
  1393  		}
  1394  		return false
  1395  
  1396  	case TPTR32, TPTR64, TSLICE:
  1397  		return !(ignoreNotInHeap && t.Elem().NotInHeap())
  1398  	}
  1399  
  1400  	return true
  1401  }
  1402  
  1403  // HasHeapPointer returns whether t contains a heap pointer.
  1404  // This is used for write barrier insertion, so it ignores
  1405  // pointers to go:notinheap types.
  1406  func (t *Type) HasHeapPointer() bool {
  1407  	return Haspointers1(t, true)
  1408  }
  1409  
  1410  func (t *Type) Symbol() *obj.LSym {
  1411  	return TypeLinkSym(t)
  1412  }
  1413  
  1414  // Tie returns 'T' if t is a concrete type,
  1415  // 'I' if t is an interface type, and 'E' if t is an empty interface type.
  1416  // It is used to build calls to the conv* and assert* runtime routines.
  1417  func (t *Type) Tie() byte {
  1418  	if t.IsEmptyInterface() {
  1419  		return 'E'
  1420  	}
  1421  	if t.IsInterface() {
  1422  		return 'I'
  1423  	}
  1424  	return 'T'
  1425  }
  1426  
  1427  var recvType *Type
  1428  
  1429  // FakeRecvType returns the singleton type used for interface method receivers.
  1430  func FakeRecvType() *Type {
  1431  	if recvType == nil {
  1432  		recvType = NewPtr(New(TSTRUCT))
  1433  	}
  1434  	return recvType
  1435  }
  1436  
  1437  var (
  1438  	TypeInvalid = newSSA("invalid")
  1439  	TypeMem     = newSSA("mem")
  1440  	TypeFlags   = newSSA("flags")
  1441  	TypeVoid    = newSSA("void")
  1442  	TypeInt128  = newSSA("int128")
  1443  )