...

Source file src/pkg/cmd/compile/internal/types/type.go

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

View as plain text