github.com/euank/go@v0.0.0-20160829210321-495514729181/src/cmd/compile/internal/gc/type.go (about)

     1  // Copyright 2015 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  // This file provides methods that let us export a Type as an ../ssa:Type.
     6  // We don't export this package's Type directly because it would lead
     7  // to an import cycle with this package and ../ssa.
     8  // TODO: move Type to its own package, then we don't need to dance around import cycles.
     9  
    10  package gc
    11  
    12  import (
    13  	"cmd/compile/internal/ssa"
    14  	"fmt"
    15  )
    16  
    17  // EType describes a kind of type.
    18  type EType uint8
    19  
    20  const (
    21  	Txxx = iota
    22  
    23  	TINT8
    24  	TUINT8
    25  	TINT16
    26  	TUINT16
    27  	TINT32
    28  	TUINT32
    29  	TINT64
    30  	TUINT64
    31  	TINT
    32  	TUINT
    33  	TUINTPTR
    34  
    35  	TCOMPLEX64
    36  	TCOMPLEX128
    37  
    38  	TFLOAT32
    39  	TFLOAT64
    40  
    41  	TBOOL
    42  
    43  	TPTR32
    44  	TPTR64
    45  
    46  	TFUNC
    47  	TSLICE
    48  	TARRAY
    49  	TSTRUCT
    50  	TCHAN
    51  	TMAP
    52  	TINTER
    53  	TFORW
    54  	TANY
    55  	TSTRING
    56  	TUNSAFEPTR
    57  
    58  	// pseudo-types for literals
    59  	TIDEAL
    60  	TNIL
    61  	TBLANK
    62  
    63  	// pseudo-types for frame layout
    64  	TFUNCARGS
    65  	TCHANARGS
    66  	TINTERMETH
    67  
    68  	// pseudo-types for import/export
    69  	TDDDFIELD // wrapper: contained type is a ... field
    70  
    71  	NTYPE
    72  )
    73  
    74  // ChanDir is whether a channel can send, receive, or both.
    75  type ChanDir uint8
    76  
    77  func (c ChanDir) CanRecv() bool { return c&Crecv != 0 }
    78  func (c ChanDir) CanSend() bool { return c&Csend != 0 }
    79  
    80  const (
    81  	// types of channel
    82  	// must match ../../../../reflect/type.go:/ChanDir
    83  	Crecv ChanDir = 1 << 0
    84  	Csend ChanDir = 1 << 1
    85  	Cboth ChanDir = Crecv | Csend
    86  )
    87  
    88  // Types stores pointers to predeclared named types.
    89  //
    90  // It also stores pointers to several special types:
    91  //   - Types[TANY] is the placeholder "any" type recognized by substArgTypes.
    92  //   - Types[TBLANK] represents the blank variable's type.
    93  //   - Types[TIDEAL] represents untyped numeric constants.
    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  	// Note: Currently these are only used within the binary export
   112  	// data format. The rest of the compiler only uses Types[TIDEAL].
   113  	idealint     = typ(TIDEAL)
   114  	idealrune    = typ(TIDEAL)
   115  	idealfloat   = typ(TIDEAL)
   116  	idealcomplex = typ(TIDEAL)
   117  )
   118  
   119  // A Type represents a Go type.
   120  type Type struct {
   121  	// Extra contains extra etype-specific fields.
   122  	// As an optimization, those etype-specific structs which contain exactly
   123  	// one pointer-shaped field are stored as values rather than pointers when possible.
   124  	//
   125  	// TMAP: *MapType
   126  	// TFORW: *ForwardType
   127  	// TFUNC: *FuncType
   128  	// TINTERMETHOD: InterMethType
   129  	// TSTRUCT: *StructType
   130  	// TINTER: *InterType
   131  	// TDDDFIELD: DDDFieldType
   132  	// TFUNCARGS: FuncArgsType
   133  	// TCHANARGS: ChanArgsType
   134  	// TCHAN: *ChanType
   135  	// TPTR32, TPTR64: PtrType
   136  	// TARRAY: *ArrayType
   137  	// TSLICE: SliceType
   138  	Extra interface{}
   139  
   140  	// Width is the width of this Type in bytes.
   141  	Width int64
   142  
   143  	methods    Fields
   144  	allMethods Fields
   145  
   146  	Nod  *Node // canonical OTYPE node
   147  	Orig *Type // original type (type literal or predefined type)
   148  
   149  	Sym    *Sym  // symbol containing name, for named types
   150  	Vargen int32 // unique name for OTYPE/ONAME
   151  	Lineno int32 // line at which this type was declared, implicitly or explicitly
   152  
   153  	Etype      EType // kind of type
   154  	Noalg      bool  // suppress hash and eq algorithm generation
   155  	Trecur     uint8 // to detect loops
   156  	Printed    bool  // prevent duplicate export printing
   157  	Local      bool  // created in this file
   158  	Deferwidth bool
   159  	Broke      bool  // broken type definition.
   160  	Align      uint8 // the required alignment of this type, in bytes
   161  }
   162  
   163  // MapType contains Type fields specific to maps.
   164  type MapType struct {
   165  	Key *Type // Key type
   166  	Val *Type // Val (elem) type
   167  
   168  	Bucket *Type // internal struct type representing a hash bucket
   169  	Hmap   *Type // internal struct type representing the Hmap (map header object)
   170  	Hiter  *Type // internal struct type representing hash iterator state
   171  }
   172  
   173  // MapType returns t's extra map-specific fields.
   174  func (t *Type) MapType() *MapType {
   175  	t.wantEtype(TMAP)
   176  	return t.Extra.(*MapType)
   177  }
   178  
   179  // ForwardType contains Type fields specific to forward types.
   180  type ForwardType struct {
   181  	Copyto      []*Node // where to copy the eventual value to
   182  	Embedlineno int32   // first use of this type as an embedded type
   183  }
   184  
   185  // ForwardType returns t's extra forward-type-specific fields.
   186  func (t *Type) ForwardType() *ForwardType {
   187  	t.wantEtype(TFORW)
   188  	return t.Extra.(*ForwardType)
   189  }
   190  
   191  // FuncType contains Type fields specific to func types.
   192  type FuncType struct {
   193  	Receiver *Type // function receiver
   194  	Results  *Type // function results
   195  	Params   *Type // function params
   196  
   197  	Nname *Node
   198  
   199  	// Argwid is the total width of the function receiver, params, and results.
   200  	// It gets calculated via a temporary TFUNCARGS type.
   201  	// Note that TFUNC's Width is Widthptr.
   202  	Argwid int64
   203  
   204  	Outnamed bool
   205  }
   206  
   207  // FuncType returns t's extra func-specific fields.
   208  func (t *Type) FuncType() *FuncType {
   209  	t.wantEtype(TFUNC)
   210  	return t.Extra.(*FuncType)
   211  }
   212  
   213  // InterMethType contains Type fields specific to interface method psuedo-types.
   214  type InterMethType struct {
   215  	Nname *Node
   216  }
   217  
   218  // StructType contains Type fields specific to struct types.
   219  type StructType struct {
   220  	fields Fields
   221  
   222  	// Maps have three associated internal structs (see struct MapType).
   223  	// Map links such structs back to their map type.
   224  	Map *Type
   225  
   226  	Funarg      Funarg // type of function arguments for arg struct
   227  	Haspointers uint8  // 0 unknown, 1 no, 2 yes
   228  }
   229  
   230  // Fnstruct records the kind of function argument
   231  type Funarg uint8
   232  
   233  const (
   234  	FunargNone    Funarg = iota
   235  	FunargRcvr           // receiver
   236  	FunargParams         // input parameters
   237  	FunargResults        // output results
   238  )
   239  
   240  // StructType returns t's extra struct-specific fields.
   241  func (t *Type) StructType() *StructType {
   242  	t.wantEtype(TSTRUCT)
   243  	return t.Extra.(*StructType)
   244  }
   245  
   246  // InterType contains Type fields specific to interface types.
   247  type InterType struct {
   248  	fields Fields
   249  }
   250  
   251  // PtrType contains Type fields specific to pointer types.
   252  type PtrType struct {
   253  	Elem *Type // element type
   254  }
   255  
   256  // DDDFieldType contains Type fields specific to TDDDFIELD types.
   257  type DDDFieldType struct {
   258  	T *Type // reference to a slice type for ... args
   259  }
   260  
   261  // ChanArgsType contains Type fields specific to TCHANARGS types.
   262  type ChanArgsType struct {
   263  	T *Type // reference to a chan type whose elements need a width check
   264  }
   265  
   266  // // FuncArgsType contains Type fields specific to TFUNCARGS types.
   267  type FuncArgsType struct {
   268  	T *Type // reference to a func type whose elements need a width check
   269  }
   270  
   271  // ChanType contains Type fields specific to channel types.
   272  type ChanType struct {
   273  	Elem *Type   // element type
   274  	Dir  ChanDir // channel direction
   275  }
   276  
   277  // ChanType returns t's extra channel-specific fields.
   278  func (t *Type) ChanType() *ChanType {
   279  	t.wantEtype(TCHAN)
   280  	return t.Extra.(*ChanType)
   281  }
   282  
   283  // ArrayType contains Type fields specific to array types.
   284  type ArrayType struct {
   285  	Elem        *Type // element type
   286  	Bound       int64 // number of elements; <0 if unknown yet
   287  	Haspointers uint8 // 0 unknown, 1 no, 2 yes
   288  }
   289  
   290  // SliceType contains Type fields specific to slice types.
   291  type SliceType struct {
   292  	Elem *Type // element type
   293  }
   294  
   295  // A Field represents a field in a struct or a method in an interface or
   296  // associated with a named type.
   297  type Field struct {
   298  	Nointerface bool
   299  	Embedded    uint8 // embedded field
   300  	Funarg      Funarg
   301  	Broke       bool // broken field definition
   302  	Isddd       bool // field is ... argument
   303  
   304  	Sym   *Sym
   305  	Nname *Node
   306  
   307  	Type *Type // field type
   308  
   309  	// Offset in bytes of this field or method within its enclosing struct
   310  	// or interface Type.
   311  	Offset int64
   312  
   313  	Note string // literal string annotation
   314  }
   315  
   316  // End returns the offset of the first byte immediately after this field.
   317  func (f *Field) End() int64 {
   318  	return f.Offset + f.Type.Width
   319  }
   320  
   321  // Fields is a pointer to a slice of *Field.
   322  // This saves space in Types that do not have fields or methods
   323  // compared to a simple slice of *Field.
   324  type Fields struct {
   325  	s *[]*Field
   326  }
   327  
   328  // Len returns the number of entries in f.
   329  func (f *Fields) Len() int {
   330  	if f.s == nil {
   331  		return 0
   332  	}
   333  	return len(*f.s)
   334  }
   335  
   336  // Slice returns the entries in f as a slice.
   337  // Changes to the slice entries will be reflected in f.
   338  func (f *Fields) Slice() []*Field {
   339  	if f.s == nil {
   340  		return nil
   341  	}
   342  	return *f.s
   343  }
   344  
   345  // Index returns the i'th element of Fields.
   346  // It panics if f does not have at least i+1 elements.
   347  func (f *Fields) Index(i int) *Field {
   348  	return (*f.s)[i]
   349  }
   350  
   351  // Set sets f to a slice.
   352  // This takes ownership of the slice.
   353  func (f *Fields) Set(s []*Field) {
   354  	if len(s) == 0 {
   355  		f.s = nil
   356  	} else {
   357  		// Copy s and take address of t rather than s to avoid
   358  		// allocation in the case where len(s) == 0.
   359  		t := s
   360  		f.s = &t
   361  	}
   362  }
   363  
   364  // Append appends entries to f.
   365  func (f *Fields) Append(s ...*Field) {
   366  	if f.s == nil {
   367  		f.s = new([]*Field)
   368  	}
   369  	*f.s = append(*f.s, s...)
   370  }
   371  
   372  // typ returns a new Type of the specified kind.
   373  func typ(et EType) *Type {
   374  	t := &Type{
   375  		Etype:  et,
   376  		Width:  BADWIDTH,
   377  		Lineno: lineno,
   378  	}
   379  	t.Orig = t
   380  	// TODO(josharian): lazily initialize some of these?
   381  	switch t.Etype {
   382  	case TMAP:
   383  		t.Extra = new(MapType)
   384  	case TFORW:
   385  		t.Extra = new(ForwardType)
   386  	case TFUNC:
   387  		t.Extra = new(FuncType)
   388  	case TINTERMETH:
   389  		t.Extra = InterMethType{}
   390  	case TSTRUCT:
   391  		t.Extra = new(StructType)
   392  	case TINTER:
   393  		t.Extra = new(InterType)
   394  	case TPTR32, TPTR64:
   395  		t.Extra = PtrType{}
   396  	case TCHANARGS:
   397  		t.Extra = ChanArgsType{}
   398  	case TFUNCARGS:
   399  		t.Extra = FuncArgsType{}
   400  	case TDDDFIELD:
   401  		t.Extra = DDDFieldType{}
   402  	case TCHAN:
   403  		t.Extra = new(ChanType)
   404  	}
   405  	return t
   406  }
   407  
   408  // typArray returns a new fixed-length array Type.
   409  func typArray(elem *Type, bound int64) *Type {
   410  	if bound < 0 {
   411  		Fatalf("typArray: invalid bound %v", bound)
   412  	}
   413  	t := typ(TARRAY)
   414  	t.Extra = &ArrayType{Elem: elem, Bound: bound}
   415  	return t
   416  }
   417  
   418  // typSlice returns a new slice Type.
   419  func typSlice(elem *Type) *Type {
   420  	t := typ(TSLICE)
   421  	t.Extra = SliceType{Elem: elem}
   422  	return t
   423  }
   424  
   425  // typDDDArray returns a new [...]T array Type.
   426  func typDDDArray(elem *Type) *Type {
   427  	t := typ(TARRAY)
   428  	t.Extra = &ArrayType{Elem: elem, Bound: -1}
   429  	return t
   430  }
   431  
   432  // typChan returns a new chan Type with direction dir.
   433  func typChan(elem *Type, dir ChanDir) *Type {
   434  	t := typ(TCHAN)
   435  	ct := t.ChanType()
   436  	ct.Elem = elem
   437  	ct.Dir = dir
   438  	return t
   439  }
   440  
   441  // typMap returns a new map Type with key type k and element (aka value) type v.
   442  func typMap(k, v *Type) *Type {
   443  	t := typ(TMAP)
   444  	mt := t.MapType()
   445  	mt.Key = k
   446  	mt.Val = v
   447  	return t
   448  }
   449  
   450  // typPtr returns a new pointer type pointing to t.
   451  func typPtr(elem *Type) *Type {
   452  	t := typ(Tptr)
   453  	t.Extra = PtrType{Elem: elem}
   454  	t.Width = int64(Widthptr)
   455  	t.Align = uint8(Widthptr)
   456  	return t
   457  }
   458  
   459  // typDDDField returns a new TDDDFIELD type for slice type s.
   460  func typDDDField(s *Type) *Type {
   461  	t := typ(TDDDFIELD)
   462  	t.Extra = DDDFieldType{T: s}
   463  	return t
   464  }
   465  
   466  // typChanArgs returns a new TCHANARGS type for channel type c.
   467  func typChanArgs(c *Type) *Type {
   468  	t := typ(TCHANARGS)
   469  	t.Extra = ChanArgsType{T: c}
   470  	return t
   471  }
   472  
   473  // typFuncArgs returns a new TFUNCARGS type for func type f.
   474  func typFuncArgs(f *Type) *Type {
   475  	t := typ(TFUNCARGS)
   476  	t.Extra = FuncArgsType{T: f}
   477  	return t
   478  }
   479  
   480  func newField() *Field {
   481  	return &Field{
   482  		Offset: BADWIDTH,
   483  	}
   484  }
   485  
   486  // substArgTypes substitutes the given list of types for
   487  // successive occurrences of the "any" placeholder in the
   488  // type syntax expression n.Type.
   489  // The result of substArgTypes MUST be assigned back to old, e.g.
   490  // 	n.Left = substArgTypes(n.Left, t1, t2)
   491  func substArgTypes(old *Node, types ...*Type) *Node {
   492  	n := *old // make shallow copy
   493  
   494  	for _, t := range types {
   495  		dowidth(t)
   496  	}
   497  	n.Type = substAny(n.Type, &types)
   498  	if len(types) > 0 {
   499  		Fatalf("substArgTypes: too many argument types")
   500  	}
   501  	return &n
   502  }
   503  
   504  // substAny walks t, replacing instances of "any" with successive
   505  // elements removed from types.  It returns the substituted type.
   506  func substAny(t *Type, types *[]*Type) *Type {
   507  	if t == nil {
   508  		return nil
   509  	}
   510  
   511  	switch t.Etype {
   512  	default:
   513  		// Leave the type unchanged.
   514  
   515  	case TANY:
   516  		if len(*types) == 0 {
   517  			Fatalf("substArgTypes: not enough argument types")
   518  		}
   519  		t = (*types)[0]
   520  		*types = (*types)[1:]
   521  
   522  	case TPTR32, TPTR64:
   523  		elem := substAny(t.Elem(), types)
   524  		if elem != t.Elem() {
   525  			t = t.Copy()
   526  			t.Extra = PtrType{Elem: elem}
   527  		}
   528  
   529  	case TARRAY:
   530  		elem := substAny(t.Elem(), types)
   531  		if elem != t.Elem() {
   532  			t = t.Copy()
   533  			t.Extra.(*ArrayType).Elem = elem
   534  		}
   535  
   536  	case TSLICE:
   537  		elem := substAny(t.Elem(), types)
   538  		if elem != t.Elem() {
   539  			t = t.Copy()
   540  			t.Extra = SliceType{Elem: elem}
   541  		}
   542  
   543  	case TCHAN:
   544  		elem := substAny(t.Elem(), types)
   545  		if elem != t.Elem() {
   546  			t = t.Copy()
   547  			t.Extra.(*ChanType).Elem = elem
   548  		}
   549  
   550  	case TMAP:
   551  		key := substAny(t.Key(), types)
   552  		val := substAny(t.Val(), types)
   553  		if key != t.Key() || val != t.Val() {
   554  			t = t.Copy()
   555  			t.Extra.(*MapType).Key = key
   556  			t.Extra.(*MapType).Val = val
   557  		}
   558  
   559  	case TFUNC:
   560  		recvs := substAny(t.Recvs(), types)
   561  		params := substAny(t.Params(), types)
   562  		results := substAny(t.Results(), types)
   563  		if recvs != t.Recvs() || params != t.Params() || results != t.Results() {
   564  			// Note that this code has to be aware of the
   565  			// representation underlying Recvs/Results/Params.
   566  			if recvs == t.Recvs() {
   567  				recvs = recvs.Copy()
   568  			}
   569  			if results == t.Results() {
   570  				results = results.Copy()
   571  			}
   572  			t = t.Copy()
   573  			*t.RecvsP() = recvs
   574  			*t.ResultsP() = results
   575  			*t.ParamsP() = params
   576  		}
   577  
   578  	case TSTRUCT:
   579  		fields := t.FieldSlice()
   580  		var nfs []*Field
   581  		for i, f := range fields {
   582  			nft := substAny(f.Type, types)
   583  			if nft == f.Type {
   584  				continue
   585  			}
   586  			if nfs == nil {
   587  				nfs = append([]*Field(nil), fields...)
   588  			}
   589  			nfs[i] = f.Copy()
   590  			nfs[i].Type = nft
   591  		}
   592  		if nfs != nil {
   593  			t = t.Copy()
   594  			t.SetFields(nfs)
   595  		}
   596  	}
   597  
   598  	return t
   599  }
   600  
   601  // Copy returns a shallow copy of the Type.
   602  func (t *Type) Copy() *Type {
   603  	if t == nil {
   604  		return nil
   605  	}
   606  	nt := *t
   607  	// copy any *T Extra fields, to avoid aliasing
   608  	switch t.Etype {
   609  	case TMAP:
   610  		x := *t.Extra.(*MapType)
   611  		nt.Extra = &x
   612  	case TFORW:
   613  		x := *t.Extra.(*ForwardType)
   614  		nt.Extra = &x
   615  	case TFUNC:
   616  		x := *t.Extra.(*FuncType)
   617  		nt.Extra = &x
   618  	case TSTRUCT:
   619  		x := *t.Extra.(*StructType)
   620  		nt.Extra = &x
   621  	case TINTER:
   622  		x := *t.Extra.(*InterType)
   623  		nt.Extra = &x
   624  	case TCHAN:
   625  		x := *t.Extra.(*ChanType)
   626  		nt.Extra = &x
   627  	case TARRAY:
   628  		x := *t.Extra.(*ArrayType)
   629  		nt.Extra = &x
   630  	}
   631  	// TODO(mdempsky): Find out why this is necessary and explain.
   632  	if t.Orig == t {
   633  		nt.Orig = &nt
   634  	}
   635  	return &nt
   636  }
   637  
   638  func (f *Field) Copy() *Field {
   639  	nf := *f
   640  	return &nf
   641  }
   642  
   643  // Iter provides an abstraction for iterating across struct fields and
   644  // interface methods.
   645  type Iter struct {
   646  	s []*Field
   647  }
   648  
   649  // IterFields returns the first field or method in struct or interface type t
   650  // and an Iter value to continue iterating across the rest.
   651  func IterFields(t *Type) (*Field, Iter) {
   652  	return t.Fields().Iter()
   653  }
   654  
   655  // Iter returns the first field in fs and an Iter value to continue iterating
   656  // across its successor fields.
   657  // Deprecated: New code should use Slice instead.
   658  func (fs *Fields) Iter() (*Field, Iter) {
   659  	i := Iter{s: fs.Slice()}
   660  	f := i.Next()
   661  	return f, i
   662  }
   663  
   664  // Next returns the next field or method, if any.
   665  func (i *Iter) Next() *Field {
   666  	if len(i.s) == 0 {
   667  		return nil
   668  	}
   669  	f := i.s[0]
   670  	i.s = i.s[1:]
   671  	return f
   672  }
   673  
   674  func (t *Type) wantEtype(et EType) {
   675  	if t.Etype != et {
   676  		Fatalf("want %v, but have %v", et, t)
   677  	}
   678  }
   679  
   680  func (t *Type) RecvsP() **Type {
   681  	t.wantEtype(TFUNC)
   682  	return &t.Extra.(*FuncType).Receiver
   683  }
   684  
   685  func (t *Type) ParamsP() **Type {
   686  	t.wantEtype(TFUNC)
   687  	return &t.Extra.(*FuncType).Params
   688  }
   689  
   690  func (t *Type) ResultsP() **Type {
   691  	t.wantEtype(TFUNC)
   692  	return &t.Extra.(*FuncType).Results
   693  }
   694  
   695  func (t *Type) Recvs() *Type   { return *t.RecvsP() }
   696  func (t *Type) Params() *Type  { return *t.ParamsP() }
   697  func (t *Type) Results() *Type { return *t.ResultsP() }
   698  
   699  // Recv returns the receiver of function type t, if any.
   700  func (t *Type) Recv() *Field {
   701  	s := t.Recvs()
   702  	if s.NumFields() == 0 {
   703  		return nil
   704  	}
   705  	return s.Field(0)
   706  }
   707  
   708  // recvsParamsResults stores the accessor functions for a function Type's
   709  // receiver, parameters, and result parameters, in that order.
   710  // It can be used to iterate over all of a function's parameter lists.
   711  var recvsParamsResults = [3]func(*Type) *Type{
   712  	(*Type).Recvs, (*Type).Params, (*Type).Results,
   713  }
   714  
   715  // paramsResults is like recvsParamsResults, but omits receiver parameters.
   716  var paramsResults = [2]func(*Type) *Type{
   717  	(*Type).Params, (*Type).Results,
   718  }
   719  
   720  // Key returns the key type of map type t.
   721  func (t *Type) Key() *Type {
   722  	t.wantEtype(TMAP)
   723  	return t.Extra.(*MapType).Key
   724  }
   725  
   726  // Val returns the value type of map type t.
   727  func (t *Type) Val() *Type {
   728  	t.wantEtype(TMAP)
   729  	return t.Extra.(*MapType).Val
   730  }
   731  
   732  // Elem returns the type of elements of t.
   733  // Usable with pointers, channels, arrays, and slices.
   734  func (t *Type) Elem() *Type {
   735  	switch t.Etype {
   736  	case TPTR32, TPTR64:
   737  		return t.Extra.(PtrType).Elem
   738  	case TARRAY:
   739  		return t.Extra.(*ArrayType).Elem
   740  	case TSLICE:
   741  		return t.Extra.(SliceType).Elem
   742  	case TCHAN:
   743  		return t.Extra.(*ChanType).Elem
   744  	}
   745  	Fatalf("Type.Elem %s", t.Etype)
   746  	return nil
   747  }
   748  
   749  // DDDField returns the slice ... type for TDDDFIELD type t.
   750  func (t *Type) DDDField() *Type {
   751  	t.wantEtype(TDDDFIELD)
   752  	return t.Extra.(DDDFieldType).T
   753  }
   754  
   755  // ChanArgs returns the channel type for TCHANARGS type t.
   756  func (t *Type) ChanArgs() *Type {
   757  	t.wantEtype(TCHANARGS)
   758  	return t.Extra.(ChanArgsType).T
   759  }
   760  
   761  // FuncArgs returns the channel type for TFUNCARGS type t.
   762  func (t *Type) FuncArgs() *Type {
   763  	t.wantEtype(TFUNCARGS)
   764  	return t.Extra.(FuncArgsType).T
   765  }
   766  
   767  // Nname returns the associated function's nname.
   768  func (t *Type) Nname() *Node {
   769  	switch t.Etype {
   770  	case TFUNC:
   771  		return t.Extra.(*FuncType).Nname
   772  	case TINTERMETH:
   773  		return t.Extra.(InterMethType).Nname
   774  	}
   775  	Fatalf("Type.Nname %v %v", t.Etype, t)
   776  	return nil
   777  }
   778  
   779  // Nname sets the associated function's nname.
   780  func (t *Type) SetNname(n *Node) {
   781  	switch t.Etype {
   782  	case TFUNC:
   783  		t.Extra.(*FuncType).Nname = n
   784  	case TINTERMETH:
   785  		t.Extra = InterMethType{Nname: n}
   786  	default:
   787  		Fatalf("Type.SetNname %v %v", t.Etype, t)
   788  	}
   789  }
   790  
   791  // IsFuncArgStruct reports whether t is a struct representing function parameters.
   792  func (t *Type) IsFuncArgStruct() bool {
   793  	return t.Etype == TSTRUCT && t.Extra.(*StructType).Funarg != FunargNone
   794  }
   795  
   796  func (t *Type) Methods() *Fields {
   797  	// TODO(mdempsky): Validate t?
   798  	return &t.methods
   799  }
   800  
   801  func (t *Type) AllMethods() *Fields {
   802  	// TODO(mdempsky): Validate t?
   803  	return &t.allMethods
   804  }
   805  
   806  func (t *Type) Fields() *Fields {
   807  	switch t.Etype {
   808  	case TSTRUCT:
   809  		return &t.Extra.(*StructType).fields
   810  	case TINTER:
   811  		return &t.Extra.(*InterType).fields
   812  	}
   813  	Fatalf("Fields: type %v does not have fields", t)
   814  	return nil
   815  }
   816  
   817  // Field returns the i'th field/method of struct/interface type t.
   818  func (t *Type) Field(i int) *Field {
   819  	return t.Fields().Slice()[i]
   820  }
   821  
   822  // FieldSlice returns a slice of containing all fields/methods of
   823  // struct/interface type t.
   824  func (t *Type) FieldSlice() []*Field {
   825  	return t.Fields().Slice()
   826  }
   827  
   828  // SetFields sets struct/interface type t's fields/methods to fields.
   829  func (t *Type) SetFields(fields []*Field) {
   830  	t.Fields().Set(fields)
   831  }
   832  
   833  func (t *Type) isDDDArray() bool {
   834  	if t.Etype != TARRAY {
   835  		return false
   836  	}
   837  	return t.Extra.(*ArrayType).Bound < 0
   838  }
   839  
   840  // ArgWidth returns the total aligned argument size for a function.
   841  // It includes the receiver, parameters, and results.
   842  func (t *Type) ArgWidth() int64 {
   843  	t.wantEtype(TFUNC)
   844  	return t.Extra.(*FuncType).Argwid
   845  }
   846  
   847  func (t *Type) Size() int64 {
   848  	dowidth(t)
   849  	return t.Width
   850  }
   851  
   852  func (t *Type) Alignment() int64 {
   853  	dowidth(t)
   854  	return int64(t.Align)
   855  }
   856  
   857  func (t *Type) SimpleString() string {
   858  	return t.Etype.String()
   859  }
   860  
   861  // Compare compares types for purposes of the SSA back
   862  // end, returning an ssa.Cmp (one of CMPlt, CMPeq, CMPgt).
   863  // The answers are correct for an optimizer
   864  // or code generator, but not necessarily typechecking.
   865  // The order chosen is arbitrary, only consistency and division
   866  // into equivalence classes (Types that compare CMPeq) matters.
   867  func (t *Type) Compare(u ssa.Type) ssa.Cmp {
   868  	x, ok := u.(*Type)
   869  	// ssa.CompilerType is smaller than gc.Type
   870  	// bare pointer equality is easy.
   871  	if !ok {
   872  		return ssa.CMPgt
   873  	}
   874  	if x == t {
   875  		return ssa.CMPeq
   876  	}
   877  	return t.cmp(x)
   878  }
   879  
   880  func cmpForNe(x bool) ssa.Cmp {
   881  	if x {
   882  		return ssa.CMPlt
   883  	}
   884  	return ssa.CMPgt
   885  }
   886  
   887  func (r *Sym) cmpsym(s *Sym) ssa.Cmp {
   888  	if r == s {
   889  		return ssa.CMPeq
   890  	}
   891  	if r == nil {
   892  		return ssa.CMPlt
   893  	}
   894  	if s == nil {
   895  		return ssa.CMPgt
   896  	}
   897  	// Fast sort, not pretty sort
   898  	if len(r.Name) != len(s.Name) {
   899  		return cmpForNe(len(r.Name) < len(s.Name))
   900  	}
   901  	if r.Pkg != s.Pkg {
   902  		if len(r.Pkg.Prefix) != len(s.Pkg.Prefix) {
   903  			return cmpForNe(len(r.Pkg.Prefix) < len(s.Pkg.Prefix))
   904  		}
   905  		if r.Pkg.Prefix != s.Pkg.Prefix {
   906  			return cmpForNe(r.Pkg.Prefix < s.Pkg.Prefix)
   907  		}
   908  	}
   909  	if r.Name != s.Name {
   910  		return cmpForNe(r.Name < s.Name)
   911  	}
   912  	return ssa.CMPeq
   913  }
   914  
   915  // cmp compares two *Types t and x, returning ssa.CMPlt,
   916  // ssa.CMPeq, ssa.CMPgt as t<x, t==x, t>x, for an arbitrary
   917  // and optimizer-centric notion of comparison.
   918  func (t *Type) cmp(x *Type) ssa.Cmp {
   919  	// This follows the structure of Eqtype in subr.go
   920  	// with two exceptions.
   921  	// 1. Symbols are compared more carefully because a <,=,> result is desired.
   922  	// 2. Maps are treated specially to avoid endless recursion -- maps
   923  	//    contain an internal data type not expressible in Go source code.
   924  	if t == x {
   925  		return ssa.CMPeq
   926  	}
   927  	if t == nil {
   928  		return ssa.CMPlt
   929  	}
   930  	if x == nil {
   931  		return ssa.CMPgt
   932  	}
   933  
   934  	if t.Etype != x.Etype {
   935  		return cmpForNe(t.Etype < x.Etype)
   936  	}
   937  
   938  	if t.Sym != nil || x.Sym != nil {
   939  		// Special case: we keep byte and uint8 separate
   940  		// for error messages. Treat them as equal.
   941  		switch t.Etype {
   942  		case TUINT8:
   943  			if (t == Types[TUINT8] || t == bytetype) && (x == Types[TUINT8] || x == bytetype) {
   944  				return ssa.CMPeq
   945  			}
   946  
   947  		case TINT32:
   948  			if (t == Types[runetype.Etype] || t == runetype) && (x == Types[runetype.Etype] || x == runetype) {
   949  				return ssa.CMPeq
   950  			}
   951  		}
   952  	}
   953  
   954  	if c := t.Sym.cmpsym(x.Sym); c != ssa.CMPeq {
   955  		return c
   956  	}
   957  
   958  	if x.Sym != nil {
   959  		// Syms non-nil, if vargens match then equal.
   960  		if t.Vargen != x.Vargen {
   961  			return cmpForNe(t.Vargen < x.Vargen)
   962  		}
   963  		return ssa.CMPeq
   964  	}
   965  	// both syms nil, look at structure below.
   966  
   967  	switch t.Etype {
   968  	case TBOOL, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TUNSAFEPTR, TUINTPTR,
   969  		TINT8, TINT16, TINT32, TINT64, TINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINT:
   970  		return ssa.CMPeq
   971  	}
   972  
   973  	switch t.Etype {
   974  	case TMAP:
   975  		if c := t.Key().cmp(x.Key()); c != ssa.CMPeq {
   976  			return c
   977  		}
   978  		return t.Val().cmp(x.Val())
   979  
   980  	case TPTR32, TPTR64, TSLICE:
   981  		// No special cases for these, they are handled
   982  		// by the general code after the switch.
   983  
   984  	case TSTRUCT:
   985  		if t.StructType().Map == nil {
   986  			if x.StructType().Map != nil {
   987  				return ssa.CMPlt // nil < non-nil
   988  			}
   989  			// to the fallthrough
   990  		} else if x.StructType().Map == nil {
   991  			return ssa.CMPgt // nil > non-nil
   992  		} else if t.StructType().Map.MapType().Bucket == t {
   993  			// Both have non-nil Map
   994  			// Special case for Maps which include a recursive type where the recursion is not broken with a named type
   995  			if x.StructType().Map.MapType().Bucket != x {
   996  				return ssa.CMPlt // bucket maps are least
   997  			}
   998  			return t.StructType().Map.cmp(x.StructType().Map)
   999  		} else if x.StructType().Map.MapType().Bucket == x {
  1000  			return ssa.CMPgt // bucket maps are least
  1001  		} // If t != t.Map.Bucket, fall through to general case
  1002  
  1003  		fallthrough
  1004  	case TINTER:
  1005  		t1, ti := IterFields(t)
  1006  		x1, xi := IterFields(x)
  1007  		for ; t1 != nil && x1 != nil; t1, x1 = ti.Next(), xi.Next() {
  1008  			if t1.Embedded != x1.Embedded {
  1009  				return cmpForNe(t1.Embedded < x1.Embedded)
  1010  			}
  1011  			if t1.Note != x1.Note {
  1012  				return cmpForNe(t1.Note < x1.Note)
  1013  			}
  1014  			if c := t1.Sym.cmpsym(x1.Sym); c != ssa.CMPeq {
  1015  				return c
  1016  			}
  1017  			if c := t1.Type.cmp(x1.Type); c != ssa.CMPeq {
  1018  				return c
  1019  			}
  1020  		}
  1021  		if t1 != x1 {
  1022  			return cmpForNe(t1 == nil)
  1023  		}
  1024  		return ssa.CMPeq
  1025  
  1026  	case TFUNC:
  1027  		for _, f := range recvsParamsResults {
  1028  			// Loop over fields in structs, ignoring argument names.
  1029  			ta, ia := IterFields(f(t))
  1030  			tb, ib := IterFields(f(x))
  1031  			for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() {
  1032  				if ta.Isddd != tb.Isddd {
  1033  					return cmpForNe(!ta.Isddd)
  1034  				}
  1035  				if c := ta.Type.cmp(tb.Type); c != ssa.CMPeq {
  1036  					return c
  1037  				}
  1038  			}
  1039  			if ta != tb {
  1040  				return cmpForNe(ta == nil)
  1041  			}
  1042  		}
  1043  		return ssa.CMPeq
  1044  
  1045  	case TARRAY:
  1046  		if t.NumElem() != x.NumElem() {
  1047  			return cmpForNe(t.NumElem() < x.NumElem())
  1048  		}
  1049  
  1050  	case TCHAN:
  1051  		if t.ChanDir() != x.ChanDir() {
  1052  			return cmpForNe(t.ChanDir() < x.ChanDir())
  1053  		}
  1054  
  1055  	default:
  1056  		e := fmt.Sprintf("Do not know how to compare %s with %s", t, x)
  1057  		panic(e)
  1058  	}
  1059  
  1060  	// Common element type comparison for TARRAY, TCHAN, TPTR32, TPTR64, and TSLICE.
  1061  	return t.Elem().cmp(x.Elem())
  1062  }
  1063  
  1064  // IsKind reports whether t is a Type of the specified kind.
  1065  func (t *Type) IsKind(et EType) bool {
  1066  	return t != nil && t.Etype == et
  1067  }
  1068  
  1069  func (t *Type) IsBoolean() bool {
  1070  	return t.Etype == TBOOL
  1071  }
  1072  
  1073  var unsignedEType = [...]EType{
  1074  	TINT8:    TUINT8,
  1075  	TUINT8:   TUINT8,
  1076  	TINT16:   TUINT16,
  1077  	TUINT16:  TUINT16,
  1078  	TINT32:   TUINT32,
  1079  	TUINT32:  TUINT32,
  1080  	TINT64:   TUINT64,
  1081  	TUINT64:  TUINT64,
  1082  	TINT:     TUINT,
  1083  	TUINT:    TUINT,
  1084  	TUINTPTR: TUINTPTR,
  1085  }
  1086  
  1087  // toUnsigned returns the unsigned equivalent of integer type t.
  1088  func (t *Type) toUnsigned() *Type {
  1089  	if !t.IsInteger() {
  1090  		Fatalf("unsignedType(%v)", t)
  1091  	}
  1092  	return Types[unsignedEType[t.Etype]]
  1093  }
  1094  
  1095  func (t *Type) IsInteger() bool {
  1096  	switch t.Etype {
  1097  	case TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64, TUINT64, TINT, TUINT, TUINTPTR:
  1098  		return true
  1099  	}
  1100  	return false
  1101  }
  1102  
  1103  func (t *Type) IsSigned() bool {
  1104  	switch t.Etype {
  1105  	case TINT8, TINT16, TINT32, TINT64, TINT:
  1106  		return true
  1107  	}
  1108  	return false
  1109  }
  1110  
  1111  func (t *Type) IsFloat() bool {
  1112  	return t.Etype == TFLOAT32 || t.Etype == TFLOAT64
  1113  }
  1114  
  1115  func (t *Type) IsComplex() bool {
  1116  	return t.Etype == TCOMPLEX64 || t.Etype == TCOMPLEX128
  1117  }
  1118  
  1119  // IsPtr reports whether t is a regular Go pointer type.
  1120  // This does not include unsafe.Pointer.
  1121  func (t *Type) IsPtr() bool {
  1122  	return t.Etype == TPTR32 || t.Etype == TPTR64
  1123  }
  1124  
  1125  // IsUnsafePtr reports whether t is an unsafe pointer.
  1126  func (t *Type) IsUnsafePtr() bool {
  1127  	return t.Etype == TUNSAFEPTR
  1128  }
  1129  
  1130  // IsPtrShaped reports whether t is represented by a single machine pointer.
  1131  // In addition to regular Go pointer types, this includes map, channel, and
  1132  // function types and unsafe.Pointer. It does not include array or struct types
  1133  // that consist of a single pointer shaped type.
  1134  // TODO(mdempsky): Should it? See golang.org/issue/15028.
  1135  func (t *Type) IsPtrShaped() bool {
  1136  	return t.Etype == TPTR32 || t.Etype == TPTR64 || t.Etype == TUNSAFEPTR ||
  1137  		t.Etype == TMAP || t.Etype == TCHAN || t.Etype == TFUNC
  1138  }
  1139  
  1140  func (t *Type) IsString() bool {
  1141  	return t.Etype == TSTRING
  1142  }
  1143  
  1144  func (t *Type) IsMap() bool {
  1145  	return t.Etype == TMAP
  1146  }
  1147  
  1148  func (t *Type) IsChan() bool {
  1149  	return t.Etype == TCHAN
  1150  }
  1151  
  1152  func (t *Type) IsSlice() bool {
  1153  	return t.Etype == TSLICE
  1154  }
  1155  
  1156  func (t *Type) IsArray() bool {
  1157  	return t.Etype == TARRAY
  1158  }
  1159  
  1160  func (t *Type) IsStruct() bool {
  1161  	return t.Etype == TSTRUCT
  1162  }
  1163  
  1164  func (t *Type) IsInterface() bool {
  1165  	return t.Etype == TINTER
  1166  }
  1167  
  1168  // IsEmptyInterface reports whether t is an empty interface type.
  1169  func (t *Type) IsEmptyInterface() bool {
  1170  	return t.IsInterface() && t.NumFields() == 0
  1171  }
  1172  
  1173  func (t *Type) ElemType() ssa.Type {
  1174  	// TODO(josharian): If Type ever moves to a shared
  1175  	// internal package, remove this silly wrapper.
  1176  	return t.Elem()
  1177  }
  1178  func (t *Type) PtrTo() ssa.Type {
  1179  	return Ptrto(t)
  1180  }
  1181  
  1182  func (t *Type) NumFields() int {
  1183  	return t.Fields().Len()
  1184  }
  1185  func (t *Type) FieldType(i int) ssa.Type {
  1186  	return t.Field(i).Type
  1187  }
  1188  func (t *Type) FieldOff(i int) int64 {
  1189  	return t.Field(i).Offset
  1190  }
  1191  func (t *Type) FieldName(i int) string {
  1192  	return t.Field(i).Sym.Name
  1193  }
  1194  
  1195  func (t *Type) NumElem() int64 {
  1196  	t.wantEtype(TARRAY)
  1197  	at := t.Extra.(*ArrayType)
  1198  	if at.Bound < 0 {
  1199  		Fatalf("NumElem array %v does not have bound yet", t)
  1200  	}
  1201  	return at.Bound
  1202  }
  1203  
  1204  // SetNumElem sets the number of elements in an array type.
  1205  // The only allowed use is on array types created with typDDDArray.
  1206  // For other uses, create a new array with typArray instead.
  1207  func (t *Type) SetNumElem(n int64) {
  1208  	t.wantEtype(TARRAY)
  1209  	at := t.Extra.(*ArrayType)
  1210  	if at.Bound >= 0 {
  1211  		Fatalf("SetNumElem array %v already has bound %d", t, at.Bound)
  1212  	}
  1213  	at.Bound = n
  1214  }
  1215  
  1216  // ChanDir returns the direction of a channel type t.
  1217  // The direction will be one of Crecv, Csend, or Cboth.
  1218  func (t *Type) ChanDir() ChanDir {
  1219  	t.wantEtype(TCHAN)
  1220  	return t.Extra.(*ChanType).Dir
  1221  }
  1222  
  1223  func (t *Type) IsMemory() bool { return false }
  1224  func (t *Type) IsFlags() bool  { return false }
  1225  func (t *Type) IsVoid() bool   { return false }
  1226  func (t *Type) IsTuple() bool  { return false }
  1227  
  1228  // IsUntyped reports whether t is an untyped type.
  1229  func (t *Type) IsUntyped() bool {
  1230  	if t == nil {
  1231  		return false
  1232  	}
  1233  	if t == idealstring || t == idealbool {
  1234  		return true
  1235  	}
  1236  	switch t.Etype {
  1237  	case TNIL, TIDEAL:
  1238  		return true
  1239  	}
  1240  	return false
  1241  }