Help us shape the future of Go! Take the 2026 Go Developer Survey

Source file src/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/compile/internal/base"
     9  	"cmd/internal/objabi"
    10  	"cmd/internal/src"
    11  	"fmt"
    12  	"go/constant"
    13  	"internal/types/errors"
    14  	"sync"
    15  )
    16  
    17  // Object represents an ir.Node, but without needing to import cmd/compile/internal/ir,
    18  // which would cause an import cycle. The uses in other packages must type assert
    19  // values of type Object to ir.Node or a more specific type.
    20  type Object interface {
    21  	Pos() src.XPos
    22  	Sym() *Sym
    23  	Type() *Type
    24  }
    25  
    26  //go:generate stringer -type Kind -trimprefix T type.go
    27  
    28  // Kind describes a kind of type.
    29  type Kind uint8
    30  
    31  const (
    32  	Txxx Kind = iota
    33  
    34  	TINT8
    35  	TUINT8
    36  	TINT16
    37  	TUINT16
    38  	TINT32
    39  	TUINT32
    40  	TINT64
    41  	TUINT64
    42  	TINT
    43  	TUINT
    44  	TUINTPTR
    45  
    46  	TCOMPLEX64
    47  	TCOMPLEX128
    48  
    49  	TFLOAT32
    50  	TFLOAT64
    51  
    52  	TBOOL
    53  
    54  	TPTR
    55  	TFUNC
    56  	TSLICE
    57  	TARRAY
    58  	TSTRUCT
    59  	TCHAN
    60  	TMAP
    61  	TINTER
    62  	TFORW
    63  	TANY
    64  	TSTRING
    65  	TUNSAFEPTR
    66  
    67  	// pseudo-types for literals
    68  	TIDEAL // untyped numeric constants
    69  	TNIL
    70  	TBLANK
    71  
    72  	// pseudo-types used temporarily only during frame layout (CalcSize())
    73  	TFUNCARGS
    74  	TCHANARGS
    75  
    76  	// SSA backend types
    77  	TSSA     // internal types used by SSA backend (flags, memory, etc.)
    78  	TTUPLE   // a pair of types, used by SSA backend
    79  	TRESULTS // multiple types; the result of calling a function or method, with a memory at the end.
    80  
    81  	NTYPE
    82  )
    83  
    84  // ChanDir is whether a channel can send, receive, or both.
    85  type ChanDir uint8
    86  
    87  func (c ChanDir) CanRecv() bool { return c&Crecv != 0 }
    88  func (c ChanDir) CanSend() bool { return c&Csend != 0 }
    89  
    90  const (
    91  	// types of channel
    92  	// must match ../../../../reflect/type.go:/ChanDir
    93  	Crecv ChanDir = 1 << 0
    94  	Csend ChanDir = 1 << 1
    95  	Cboth ChanDir = Crecv | Csend
    96  )
    97  
    98  // Types stores pointers to predeclared named types.
    99  //
   100  // It also stores pointers to several special types:
   101  //   - Types[TANY] is the placeholder "any" type recognized by SubstArgTypes.
   102  //   - Types[TBLANK] represents the blank variable's type.
   103  //   - Types[TINTER] is the canonical "interface{}" type.
   104  //   - Types[TNIL] represents the predeclared "nil" value's type.
   105  //   - Types[TUNSAFEPTR] is package unsafe's Pointer type.
   106  var Types [NTYPE]*Type
   107  
   108  var (
   109  	// Predeclared alias types. These are actually created as distinct
   110  	// defined types for better error messages, but are then specially
   111  	// treated as identical to their respective underlying types.
   112  	AnyType  *Type
   113  	ByteType *Type
   114  	RuneType *Type
   115  
   116  	// Predeclared error interface type.
   117  	ErrorType *Type
   118  	// Predeclared comparable interface type.
   119  	ComparableType *Type
   120  
   121  	// Types to represent untyped string and boolean constants.
   122  	UntypedString = newType(TSTRING)
   123  	UntypedBool   = newType(TBOOL)
   124  
   125  	// Types to represent untyped numeric constants.
   126  	UntypedInt     = newType(TIDEAL)
   127  	UntypedRune    = newType(TIDEAL)
   128  	UntypedFloat   = newType(TIDEAL)
   129  	UntypedComplex = newType(TIDEAL)
   130  )
   131  
   132  // UntypedTypes maps from a constant.Kind to its untyped Type
   133  // representation.
   134  var UntypedTypes = [...]*Type{
   135  	constant.Bool:    UntypedBool,
   136  	constant.String:  UntypedString,
   137  	constant.Int:     UntypedInt,
   138  	constant.Float:   UntypedFloat,
   139  	constant.Complex: UntypedComplex,
   140  }
   141  
   142  // DefaultKinds maps from a constant.Kind to its default Kind.
   143  var DefaultKinds = [...]Kind{
   144  	constant.Bool:    TBOOL,
   145  	constant.String:  TSTRING,
   146  	constant.Int:     TINT,
   147  	constant.Float:   TFLOAT64,
   148  	constant.Complex: TCOMPLEX128,
   149  }
   150  
   151  // A Type represents a Go type.
   152  //
   153  // There may be multiple unnamed types with identical structure. However, there must
   154  // be a unique Type object for each unique named (defined) type. After noding, a
   155  // package-level type can be looked up by building its unique symbol sym (sym =
   156  // package.Lookup(name)) and checking sym.Def. If sym.Def is non-nil, the type
   157  // already exists at package scope and is available at sym.Def.(*ir.Name).Type().
   158  // Local types (which may have the same name as a package-level type) are
   159  // distinguished by their vargen, which is embedded in their symbol name.
   160  type Type struct {
   161  	// extra contains extra etype-specific fields.
   162  	// As an optimization, those etype-specific structs which contain exactly
   163  	// one pointer-shaped field are stored as values rather than pointers when possible.
   164  	//
   165  	// TMAP: *Map
   166  	// TFORW: *Forward
   167  	// TFUNC: *Func
   168  	// TSTRUCT: *Struct
   169  	// TINTER: *Interface
   170  	// TFUNCARGS: FuncArgs
   171  	// TCHANARGS: ChanArgs
   172  	// TCHAN: *Chan
   173  	// TPTR: Ptr
   174  	// TARRAY: *Array
   175  	// TSLICE: Slice
   176  	// TSSA: string
   177  	extra any
   178  
   179  	// width is the width of this Type in bytes.
   180  	width int64 // valid if Align > 0
   181  
   182  	// list of base methods (excluding embedding)
   183  	methods fields
   184  	// list of all methods (including embedding)
   185  	allMethods fields
   186  
   187  	// canonical OTYPE node for a named type (should be an ir.Name node with same sym)
   188  	obj Object
   189  	// the underlying type (type literal or predeclared type) for a defined type
   190  	underlying *Type
   191  
   192  	// Cache of composite types, with this type being the element type.
   193  	cache struct {
   194  		ptr   *Type // *T, or nil
   195  		slice *Type // []T, or nil
   196  	}
   197  
   198  	kind  Kind  // kind of type
   199  	align uint8 // the required alignment of this type, in bytes (0 means Width and Align have not yet been computed)
   200  
   201  	intRegs, floatRegs uint8 // registers needed for ABIInternal
   202  
   203  	flags bitset16
   204  	alg   AlgKind // valid if Align > 0
   205  
   206  	tflag uint8
   207  
   208  	// size of prefix of object that contains all pointers. valid if Align > 0.
   209  	// Note that for pointers, this is always PtrSize even if the element type
   210  	// is NotInHeap. See size.go:PtrDataSize for details.
   211  	ptrBytes int64
   212  }
   213  
   214  // Registers returns the number of integer and floating-point
   215  // registers required to represent a parameter of this type under the
   216  // ABIInternal calling conventions.
   217  //
   218  // If t must be passed by memory, Registers returns (math.MaxUint8,
   219  // math.MaxUint8).
   220  func (t *Type) Registers() (uint8, uint8) {
   221  	CalcSize(t)
   222  	return t.intRegs, t.floatRegs
   223  }
   224  
   225  func (*Type) CanBeAnSSAAux() {}
   226  
   227  const (
   228  	typeNotInHeap  = 1 << iota // type cannot be heap allocated
   229  	typeNoalg                  // suppress hash and eq algorithm generation
   230  	typeDeferwidth             // width computation has been deferred and type is on deferredTypeStack
   231  	typeRecur
   232  	typeIsShape  // represents a set of closely related types, for generics
   233  	typeHasShape // there is a shape somewhere in the type
   234  	// typeIsFullyInstantiated reports whether a type is fully instantiated generic type; i.e.
   235  	// an instantiated generic type where all type arguments are non-generic or fully instantiated generic types.
   236  	typeIsFullyInstantiated
   237  	typeIsSIMDTag // type is the SIMD marker type
   238  	typeIsSIMD    // type contains the SIMD marker type
   239  	typeMethodsComputed
   240  )
   241  
   242  func (t *Type) NotInHeap() bool           { return t.flags&typeNotInHeap != 0 }
   243  func (t *Type) Noalg() bool               { return t.flags&typeNoalg != 0 }
   244  func (t *Type) Deferwidth() bool          { return t.flags&typeDeferwidth != 0 }
   245  func (t *Type) Recur() bool               { return t.flags&typeRecur != 0 }
   246  func (t *Type) IsShape() bool             { return t.flags&typeIsShape != 0 }
   247  func (t *Type) HasShape() bool            { return t.flags&typeHasShape != 0 }
   248  func (t *Type) IsFullyInstantiated() bool { return t.flags&typeIsFullyInstantiated != 0 }
   249  func (t *Type) MethodsComputed() bool     { return t.flags&typeMethodsComputed != 0 }
   250  
   251  func (t *Type) SetNotInHeap(b bool)           { t.flags.set(typeNotInHeap, b) }
   252  func (t *Type) SetNoalg(b bool)               { t.flags.set(typeNoalg, b) }
   253  func (t *Type) SetDeferwidth(b bool)          { t.flags.set(typeDeferwidth, b) }
   254  func (t *Type) SetRecur(b bool)               { t.flags.set(typeRecur, b) }
   255  func (t *Type) SetIsFullyInstantiated(b bool) { t.flags.set(typeIsFullyInstantiated, b) }
   256  func (t *Type) SetMethodsComputed(b bool)     { t.flags.set(typeMethodsComputed, b) }
   257  
   258  // Should always do SetHasShape(true) when doing SetIsShape(true).
   259  func (t *Type) SetIsShape(b bool)  { t.flags.set(typeIsShape, b) }
   260  func (t *Type) SetHasShape(b bool) { t.flags.set(typeHasShape, b) }
   261  
   262  // Kind returns the kind of type t.
   263  func (t *Type) Kind() Kind { return t.kind }
   264  
   265  // Sym returns the name of type t.
   266  func (t *Type) Sym() *Sym {
   267  	if t.obj != nil {
   268  		return t.obj.Sym()
   269  	}
   270  	return nil
   271  }
   272  
   273  // Underlying returns the underlying type of type t.
   274  func (t *Type) Underlying() *Type { return t.underlying }
   275  
   276  // Pos returns a position associated with t, if any.
   277  // This should only be used for diagnostics.
   278  func (t *Type) Pos() src.XPos {
   279  	if t.obj != nil {
   280  		return t.obj.Pos()
   281  	}
   282  	return src.NoXPos
   283  }
   284  
   285  // Map contains Type fields specific to maps.
   286  type Map struct {
   287  	Key  *Type // Key type
   288  	Elem *Type // Val (elem) type
   289  
   290  	Group *Type // internal struct type representing a slot group
   291  }
   292  
   293  // MapType returns t's extra map-specific fields.
   294  func (t *Type) MapType() *Map {
   295  	t.wantEtype(TMAP)
   296  	return t.extra.(*Map)
   297  }
   298  
   299  // Forward contains Type fields specific to forward types.
   300  type Forward struct {
   301  	Copyto      []*Type  // where to copy the eventual value to
   302  	Embedlineno src.XPos // first use of this type as an embedded type
   303  }
   304  
   305  // forwardType returns t's extra forward-type-specific fields.
   306  func (t *Type) forwardType() *Forward {
   307  	t.wantEtype(TFORW)
   308  	return t.extra.(*Forward)
   309  }
   310  
   311  // Func contains Type fields specific to func types.
   312  type Func struct {
   313  	allParams []*Field // slice of all parameters, in receiver/params/results order
   314  
   315  	startParams  int // index of the start of the (regular) parameters section
   316  	startResults int // index of the start of the results section
   317  
   318  	resultsTuple *Type // struct-like type representing multi-value results
   319  
   320  	// Argwid is the total width of the function receiver, params, and results.
   321  	// It gets calculated via a temporary TFUNCARGS type.
   322  	// Note that TFUNC's Width is Widthptr.
   323  	Argwid int64
   324  }
   325  
   326  func (ft *Func) recvs() []*Field         { return ft.allParams[:ft.startParams] }
   327  func (ft *Func) params() []*Field        { return ft.allParams[ft.startParams:ft.startResults] }
   328  func (ft *Func) results() []*Field       { return ft.allParams[ft.startResults:] }
   329  func (ft *Func) recvParams() []*Field    { return ft.allParams[:ft.startResults] }
   330  func (ft *Func) paramsResults() []*Field { return ft.allParams[ft.startParams:] }
   331  
   332  // funcType returns t's extra func-specific fields.
   333  func (t *Type) funcType() *Func {
   334  	t.wantEtype(TFUNC)
   335  	return t.extra.(*Func)
   336  }
   337  
   338  // Struct contains Type fields specific to struct types.
   339  type Struct struct {
   340  	fields fields
   341  
   342  	// Maps have three associated internal structs (see struct MapType).
   343  	// Map links such structs back to their map type.
   344  	Map *Type
   345  
   346  	ParamTuple bool // whether this struct is actually a tuple of signature parameters
   347  }
   348  
   349  // StructType returns t's extra struct-specific fields.
   350  func (t *Type) StructType() *Struct {
   351  	t.wantEtype(TSTRUCT)
   352  	return t.extra.(*Struct)
   353  }
   354  
   355  // Interface contains Type fields specific to interface types.
   356  type Interface struct {
   357  }
   358  
   359  // Ptr contains Type fields specific to pointer types.
   360  type Ptr struct {
   361  	Elem *Type // element type
   362  }
   363  
   364  // ChanArgs contains Type fields specific to TCHANARGS types.
   365  type ChanArgs struct {
   366  	T *Type // reference to a chan type whose elements need a width check
   367  }
   368  
   369  // FuncArgs contains Type fields specific to TFUNCARGS types.
   370  type FuncArgs struct {
   371  	T *Type // reference to a func type whose elements need a width check
   372  }
   373  
   374  // Chan contains Type fields specific to channel types.
   375  type Chan struct {
   376  	Elem *Type   // element type
   377  	Dir  ChanDir // channel direction
   378  }
   379  
   380  // chanType returns t's extra channel-specific fields.
   381  func (t *Type) chanType() *Chan {
   382  	t.wantEtype(TCHAN)
   383  	return t.extra.(*Chan)
   384  }
   385  
   386  type Tuple struct {
   387  	first  *Type
   388  	second *Type
   389  	// Any tuple with a memory type must put that memory type second.
   390  }
   391  
   392  // Results are the output from calls that will be late-expanded.
   393  type Results struct {
   394  	Types []*Type // Last element is memory output from call.
   395  }
   396  
   397  // Array contains Type fields specific to array types.
   398  type Array struct {
   399  	Elem  *Type // element type
   400  	Bound int64 // number of elements; <0 if unknown yet
   401  }
   402  
   403  // Slice contains Type fields specific to slice types.
   404  type Slice struct {
   405  	Elem *Type // element type
   406  }
   407  
   408  // A Field is a (Sym, Type) pairing along with some other information, and,
   409  // depending on the context, is used to represent:
   410  //   - a field in a struct
   411  //   - a method in an interface or associated with a named type
   412  //   - a function parameter
   413  type Field struct {
   414  	flags bitset8
   415  
   416  	Embedded uint8 // embedded field
   417  
   418  	Pos src.XPos
   419  
   420  	// Name of field/method/parameter. Can be nil for interface fields embedded
   421  	// in interfaces and unnamed parameters.
   422  	Sym  *Sym
   423  	Type *Type  // field type
   424  	Note string // literal string annotation
   425  
   426  	// For fields that represent function parameters, Nname points to the
   427  	// associated ONAME Node. For fields that represent methods, Nname points to
   428  	// the function name node.
   429  	Nname Object
   430  
   431  	// Offset in bytes of this field within its enclosing struct. For interface
   432  	// methods, this is the byte offset of the method's entry in an itab's Fun
   433  	// array. For promoted, non-interface methods, this is the offset from the
   434  	// wrapper receiver to the wrapped receiver. For parameters, this is BADWIDTH.
   435  	Offset int64
   436  }
   437  
   438  const (
   439  	fieldIsDDD = 1 << iota // field is ... argument
   440  	fieldNointerface
   441  )
   442  
   443  func (f *Field) IsDDD() bool       { return f.flags&fieldIsDDD != 0 }
   444  func (f *Field) Nointerface() bool { return f.flags&fieldNointerface != 0 }
   445  
   446  func (f *Field) SetIsDDD(b bool)       { f.flags.set(fieldIsDDD, b) }
   447  func (f *Field) SetNointerface(b bool) { f.flags.set(fieldNointerface, b) }
   448  
   449  // End returns the offset of the first byte immediately after this field.
   450  func (f *Field) End() int64 {
   451  	return f.Offset + f.Type.width
   452  }
   453  
   454  // IsMethod reports whether f represents a method rather than a struct field.
   455  func (f *Field) IsMethod() bool {
   456  	return f.Type.kind == TFUNC && f.Type.Recv() != nil
   457  }
   458  
   459  // CompareFields compares two Field values by name.
   460  func CompareFields(a, b *Field) int {
   461  	return CompareSyms(a.Sym, b.Sym)
   462  }
   463  
   464  // fields is a pointer to a slice of *Field.
   465  // This saves space in Types that do not have fields or methods
   466  // compared to a simple slice of *Field.
   467  type fields struct {
   468  	s *[]*Field
   469  }
   470  
   471  // Slice returns the entries in f as a slice.
   472  // Changes to the slice entries will be reflected in f.
   473  func (f *fields) Slice() []*Field {
   474  	if f.s == nil {
   475  		return nil
   476  	}
   477  	return *f.s
   478  }
   479  
   480  // Set sets f to a slice.
   481  // This takes ownership of the slice.
   482  func (f *fields) Set(s []*Field) {
   483  	if len(s) == 0 {
   484  		f.s = nil
   485  	} else {
   486  		// Copy s and take address of t rather than s to avoid
   487  		// allocation in the case where len(s) == 0.
   488  		t := s
   489  		f.s = &t
   490  	}
   491  }
   492  
   493  // newType returns a new Type of the specified kind.
   494  func newType(et Kind) *Type {
   495  	t := &Type{
   496  		kind:  et,
   497  		width: BADWIDTH,
   498  	}
   499  	t.underlying = t
   500  	// TODO(josharian): lazily initialize some of these?
   501  	switch t.kind {
   502  	case TMAP:
   503  		t.extra = new(Map)
   504  	case TFORW:
   505  		t.extra = new(Forward)
   506  	case TFUNC:
   507  		t.extra = new(Func)
   508  	case TSTRUCT:
   509  		t.extra = new(Struct)
   510  	case TINTER:
   511  		t.extra = new(Interface)
   512  	case TPTR:
   513  		t.extra = Ptr{}
   514  	case TCHANARGS:
   515  		t.extra = ChanArgs{}
   516  	case TFUNCARGS:
   517  		t.extra = FuncArgs{}
   518  	case TCHAN:
   519  		t.extra = new(Chan)
   520  	case TTUPLE:
   521  		t.extra = new(Tuple)
   522  	case TRESULTS:
   523  		t.extra = new(Results)
   524  	}
   525  	return t
   526  }
   527  
   528  // NewArray returns a new fixed-length array Type.
   529  func NewArray(elem *Type, bound int64) *Type {
   530  	if bound < 0 {
   531  		base.Fatalf("NewArray: invalid bound %v", bound)
   532  	}
   533  	t := newType(TARRAY)
   534  	t.extra = &Array{Elem: elem, Bound: bound}
   535  	if elem.HasShape() {
   536  		t.SetHasShape(true)
   537  	}
   538  	if elem.NotInHeap() {
   539  		t.SetNotInHeap(true)
   540  	}
   541  	return t
   542  }
   543  
   544  // NewSlice returns the slice Type with element type elem.
   545  func NewSlice(elem *Type) *Type {
   546  	if t := elem.cache.slice; t != nil {
   547  		if t.Elem() != elem {
   548  			base.Fatalf("elem mismatch")
   549  		}
   550  		if elem.HasShape() != t.HasShape() {
   551  			base.Fatalf("Incorrect HasShape flag for cached slice type")
   552  		}
   553  		return t
   554  	}
   555  
   556  	t := newType(TSLICE)
   557  	t.extra = Slice{Elem: elem}
   558  	elem.cache.slice = t
   559  	if elem.HasShape() {
   560  		t.SetHasShape(true)
   561  	}
   562  	return t
   563  }
   564  
   565  // NewChan returns a new chan Type with direction dir.
   566  func NewChan(elem *Type, dir ChanDir) *Type {
   567  	t := newType(TCHAN)
   568  	ct := t.chanType()
   569  	ct.Elem = elem
   570  	ct.Dir = dir
   571  	if elem.HasShape() {
   572  		t.SetHasShape(true)
   573  	}
   574  	return t
   575  }
   576  
   577  func NewTuple(t1, t2 *Type) *Type {
   578  	t := newType(TTUPLE)
   579  	t.extra.(*Tuple).first = t1
   580  	t.extra.(*Tuple).second = t2
   581  	if t1.HasShape() || t2.HasShape() {
   582  		t.SetHasShape(true)
   583  	}
   584  	return t
   585  }
   586  
   587  func newResults(types []*Type) *Type {
   588  	t := newType(TRESULTS)
   589  	t.extra.(*Results).Types = types
   590  	return t
   591  }
   592  
   593  func NewResults(types []*Type) *Type {
   594  	if len(types) == 1 && types[0] == TypeMem {
   595  		return TypeResultMem
   596  	}
   597  	return newResults(types)
   598  }
   599  
   600  func newSSA(name string) *Type {
   601  	t := newType(TSSA)
   602  	t.extra = name
   603  	return t
   604  }
   605  
   606  func newSIMD(name string) *Type {
   607  	t := newSSA(name)
   608  	t.flags |= typeIsSIMD
   609  	return t
   610  }
   611  
   612  // NewMap returns a new map Type with key type k and element (aka value) type v.
   613  func NewMap(k, v *Type) *Type {
   614  	t := newType(TMAP)
   615  	mt := t.MapType()
   616  	mt.Key = k
   617  	mt.Elem = v
   618  	if k.HasShape() || v.HasShape() {
   619  		t.SetHasShape(true)
   620  	}
   621  	return t
   622  }
   623  
   624  // NewPtrCacheEnabled controls whether *T Types are cached in T.
   625  // Caching is disabled just before starting the backend.
   626  // This allows the backend to run concurrently.
   627  var NewPtrCacheEnabled = true
   628  
   629  // NewPtr returns the pointer type pointing to t.
   630  func NewPtr(elem *Type) *Type {
   631  	if elem == nil {
   632  		base.Fatalf("NewPtr: pointer to elem Type is nil")
   633  	}
   634  
   635  	if t := elem.cache.ptr; t != nil {
   636  		if t.Elem() != elem {
   637  			base.Fatalf("NewPtr: elem mismatch")
   638  		}
   639  		if elem.HasShape() != t.HasShape() {
   640  			base.Fatalf("Incorrect HasShape flag for cached pointer type")
   641  		}
   642  		return t
   643  	}
   644  
   645  	t := newType(TPTR)
   646  	t.extra = Ptr{Elem: elem}
   647  	t.width = int64(PtrSize)
   648  	t.align = uint8(PtrSize)
   649  	t.intRegs = 1
   650  	if NewPtrCacheEnabled {
   651  		elem.cache.ptr = t
   652  	}
   653  	if elem.HasShape() {
   654  		t.SetHasShape(true)
   655  	}
   656  	t.alg = AMEM
   657  	if elem.Noalg() {
   658  		t.SetNoalg(true)
   659  		t.alg = ANOALG
   660  	}
   661  	// Note: we can't check elem.NotInHeap here because it might
   662  	// not be set yet. See size.go:PtrDataSize.
   663  	t.ptrBytes = int64(PtrSize)
   664  	return t
   665  }
   666  
   667  // NewChanArgs returns a new TCHANARGS type for channel type c.
   668  func NewChanArgs(c *Type) *Type {
   669  	t := newType(TCHANARGS)
   670  	t.extra = ChanArgs{T: c}
   671  	return t
   672  }
   673  
   674  // NewFuncArgs returns a new TFUNCARGS type for func type f.
   675  func NewFuncArgs(f *Type) *Type {
   676  	t := newType(TFUNCARGS)
   677  	t.extra = FuncArgs{T: f}
   678  	return t
   679  }
   680  
   681  func NewField(pos src.XPos, sym *Sym, typ *Type) *Field {
   682  	f := &Field{
   683  		Pos:    pos,
   684  		Sym:    sym,
   685  		Type:   typ,
   686  		Offset: BADWIDTH,
   687  	}
   688  	if typ == nil {
   689  		base.Fatalf("typ is nil")
   690  	}
   691  	return f
   692  }
   693  
   694  // SubstAny walks t, replacing instances of "any" with successive
   695  // elements removed from types.  It returns the substituted type.
   696  func SubstAny(t *Type, types *[]*Type) *Type {
   697  	if t == nil {
   698  		return nil
   699  	}
   700  
   701  	switch t.kind {
   702  	default:
   703  		// Leave the type unchanged.
   704  
   705  	case TANY:
   706  		if len(*types) == 0 {
   707  			base.Fatalf("SubstArgTypes: not enough argument types")
   708  		}
   709  		t = (*types)[0]
   710  		*types = (*types)[1:]
   711  
   712  	case TPTR:
   713  		elem := SubstAny(t.Elem(), types)
   714  		if elem != t.Elem() {
   715  			t = t.copy()
   716  			t.extra = Ptr{Elem: elem}
   717  		}
   718  
   719  	case TARRAY:
   720  		elem := SubstAny(t.Elem(), types)
   721  		if elem != t.Elem() {
   722  			t = t.copy()
   723  			t.extra.(*Array).Elem = elem
   724  		}
   725  
   726  	case TSLICE:
   727  		elem := SubstAny(t.Elem(), types)
   728  		if elem != t.Elem() {
   729  			t = t.copy()
   730  			t.extra = Slice{Elem: elem}
   731  		}
   732  
   733  	case TCHAN:
   734  		elem := SubstAny(t.Elem(), types)
   735  		if elem != t.Elem() {
   736  			t = t.copy()
   737  			t.extra.(*Chan).Elem = elem
   738  		}
   739  
   740  	case TMAP:
   741  		key := SubstAny(t.Key(), types)
   742  		elem := SubstAny(t.Elem(), types)
   743  		if key != t.Key() || elem != t.Elem() {
   744  			t = t.copy()
   745  			t.extra.(*Map).Key = key
   746  			t.extra.(*Map).Elem = elem
   747  		}
   748  
   749  	case TFUNC:
   750  		ft := t.funcType()
   751  		allParams := substFields(ft.allParams, types)
   752  
   753  		t = t.copy()
   754  		ft = t.funcType()
   755  		ft.allParams = allParams
   756  
   757  		rt := ft.resultsTuple
   758  		rt = rt.copy()
   759  		ft.resultsTuple = rt
   760  		rt.setFields(t.Results())
   761  
   762  	case TSTRUCT:
   763  		// Make a copy of all fields, including ones whose type does not change.
   764  		// This prevents aliasing across functions, which can lead to later
   765  		// fields getting their Offset incorrectly overwritten.
   766  		nfs := substFields(t.Fields(), types)
   767  		t = t.copy()
   768  		t.setFields(nfs)
   769  	}
   770  
   771  	return t
   772  }
   773  
   774  func substFields(fields []*Field, types *[]*Type) []*Field {
   775  	nfs := make([]*Field, len(fields))
   776  	for i, f := range fields {
   777  		nft := SubstAny(f.Type, types)
   778  		nfs[i] = f.Copy()
   779  		nfs[i].Type = nft
   780  	}
   781  	return nfs
   782  }
   783  
   784  // copy returns a shallow copy of the Type.
   785  func (t *Type) copy() *Type {
   786  	if t == nil {
   787  		return nil
   788  	}
   789  	nt := *t
   790  	// copy any *T Extra fields, to avoid aliasing
   791  	switch t.kind {
   792  	case TMAP:
   793  		x := *t.extra.(*Map)
   794  		nt.extra = &x
   795  	case TFORW:
   796  		x := *t.extra.(*Forward)
   797  		nt.extra = &x
   798  	case TFUNC:
   799  		x := *t.extra.(*Func)
   800  		nt.extra = &x
   801  	case TSTRUCT:
   802  		x := *t.extra.(*Struct)
   803  		nt.extra = &x
   804  	case TINTER:
   805  		x := *t.extra.(*Interface)
   806  		nt.extra = &x
   807  	case TCHAN:
   808  		x := *t.extra.(*Chan)
   809  		nt.extra = &x
   810  	case TARRAY:
   811  		x := *t.extra.(*Array)
   812  		nt.extra = &x
   813  	case TTUPLE, TSSA, TRESULTS:
   814  		base.Fatalf("ssa types cannot be copied")
   815  	}
   816  	// TODO(mdempsky): Find out why this is necessary and explain.
   817  	if t.underlying == t {
   818  		nt.underlying = &nt
   819  	}
   820  	return &nt
   821  }
   822  
   823  func (f *Field) Copy() *Field {
   824  	nf := *f
   825  	return &nf
   826  }
   827  
   828  func (t *Type) wantEtype(et Kind) {
   829  	if t.kind != et {
   830  		base.Fatalf("want %v, but have %v", et, t)
   831  	}
   832  }
   833  
   834  // ResultsTuple returns the result type of signature type t as a tuple.
   835  // This can be used as the type of multi-valued call expressions.
   836  func (t *Type) ResultsTuple() *Type { return t.funcType().resultsTuple }
   837  
   838  // Recvs returns a slice of receiver parameters of signature type t.
   839  // The returned slice always has length 0 or 1.
   840  func (t *Type) Recvs() []*Field { return t.funcType().recvs() }
   841  
   842  // Params returns a slice of regular parameters of signature type t.
   843  func (t *Type) Params() []*Field { return t.funcType().params() }
   844  
   845  // Results returns a slice of result parameters of signature type t.
   846  func (t *Type) Results() []*Field { return t.funcType().results() }
   847  
   848  // RecvParamsResults returns a slice containing all of the
   849  // signature's parameters in receiver (if any), (normal) parameters,
   850  // and then results.
   851  func (t *Type) RecvParamsResults() []*Field { return t.funcType().allParams }
   852  
   853  // RecvParams returns a slice containing the signature's receiver (if
   854  // any) followed by its (normal) parameters.
   855  func (t *Type) RecvParams() []*Field { return t.funcType().recvParams() }
   856  
   857  // ParamsResults returns a slice containing the signature's (normal)
   858  // parameters followed by its results.
   859  func (t *Type) ParamsResults() []*Field { return t.funcType().paramsResults() }
   860  
   861  func (t *Type) NumRecvs() int   { return len(t.Recvs()) }
   862  func (t *Type) NumParams() int  { return len(t.Params()) }
   863  func (t *Type) NumResults() int { return len(t.Results()) }
   864  
   865  // IsVariadic reports whether function type t is variadic.
   866  func (t *Type) IsVariadic() bool {
   867  	n := t.NumParams()
   868  	return n > 0 && t.Param(n-1).IsDDD()
   869  }
   870  
   871  // Recv returns the receiver of function type t, if any.
   872  func (t *Type) Recv() *Field {
   873  	if s := t.Recvs(); len(s) == 1 {
   874  		return s[0]
   875  	}
   876  	return nil
   877  }
   878  
   879  // Param returns the i'th parameter of signature type t.
   880  func (t *Type) Param(i int) *Field { return t.Params()[i] }
   881  
   882  // Result returns the i'th result of signature type t.
   883  func (t *Type) Result(i int) *Field { return t.Results()[i] }
   884  
   885  // Key returns the key type of map type t.
   886  func (t *Type) Key() *Type {
   887  	t.wantEtype(TMAP)
   888  	return t.extra.(*Map).Key
   889  }
   890  
   891  // Elem returns the type of elements of t.
   892  // Usable with pointers, channels, arrays, slices, and maps.
   893  func (t *Type) Elem() *Type {
   894  	switch t.kind {
   895  	case TPTR:
   896  		return t.extra.(Ptr).Elem
   897  	case TARRAY:
   898  		return t.extra.(*Array).Elem
   899  	case TSLICE:
   900  		return t.extra.(Slice).Elem
   901  	case TCHAN:
   902  		return t.extra.(*Chan).Elem
   903  	case TMAP:
   904  		return t.extra.(*Map).Elem
   905  	}
   906  	base.Fatalf("Type.Elem %s", t.kind)
   907  	return nil
   908  }
   909  
   910  // ChanArgs returns the channel type for TCHANARGS type t.
   911  func (t *Type) ChanArgs() *Type {
   912  	t.wantEtype(TCHANARGS)
   913  	return t.extra.(ChanArgs).T
   914  }
   915  
   916  // FuncArgs returns the func type for TFUNCARGS type t.
   917  func (t *Type) FuncArgs() *Type {
   918  	t.wantEtype(TFUNCARGS)
   919  	return t.extra.(FuncArgs).T
   920  }
   921  
   922  // IsFuncArgStruct reports whether t is a struct representing function parameters or results.
   923  func (t *Type) IsFuncArgStruct() bool {
   924  	return t.kind == TSTRUCT && t.extra.(*Struct).ParamTuple
   925  }
   926  
   927  // Methods returns a pointer to the base methods (excluding embedding) for type t.
   928  // These can either be concrete methods (for non-interface types) or interface
   929  // methods (for interface types).
   930  func (t *Type) Methods() []*Field {
   931  	return t.methods.Slice()
   932  }
   933  
   934  // AllMethods returns a pointer to all the methods (including embedding) for type t.
   935  // For an interface type, this is the set of methods that are typically iterated
   936  // over. For non-interface types, AllMethods() only returns a valid result after
   937  // CalcMethods() has been called at least once.
   938  func (t *Type) AllMethods() []*Field {
   939  	if t.kind == TINTER {
   940  		// Calculate the full method set of an interface type on the fly
   941  		// now, if not done yet.
   942  		CalcSize(t)
   943  	}
   944  	return t.allMethods.Slice()
   945  }
   946  
   947  // SetMethods sets the direct method set for type t (i.e., *not*
   948  // including promoted methods from embedded types).
   949  func (t *Type) SetMethods(fs []*Field) {
   950  	t.methods.Set(fs)
   951  }
   952  
   953  // SetAllMethods sets the set of all methods for type t (i.e.,
   954  // including promoted methods from embedded types).
   955  func (t *Type) SetAllMethods(fs []*Field) {
   956  	t.allMethods.Set(fs)
   957  }
   958  
   959  // fields returns the fields of struct type t.
   960  func (t *Type) fields() *fields {
   961  	t.wantEtype(TSTRUCT)
   962  	return &t.extra.(*Struct).fields
   963  }
   964  
   965  // Field returns the i'th field of struct type t.
   966  func (t *Type) Field(i int) *Field { return t.Fields()[i] }
   967  
   968  // Fields returns a slice of containing all fields of
   969  // a struct type t.
   970  func (t *Type) Fields() []*Field { return t.fields().Slice() }
   971  
   972  // setFields sets struct type t's fields to fields.
   973  func (t *Type) setFields(fields []*Field) {
   974  	// If we've calculated the width of t before,
   975  	// then some other type such as a function signature
   976  	// might now have the wrong type.
   977  	// Rather than try to track and invalidate those,
   978  	// enforce that SetFields cannot be called once
   979  	// t's width has been calculated.
   980  	if t.widthCalculated() {
   981  		base.Fatalf("SetFields of %v: width previously calculated", t)
   982  	}
   983  	t.wantEtype(TSTRUCT)
   984  	t.fields().Set(fields)
   985  }
   986  
   987  // SetInterface sets the base methods of an interface type t.
   988  func (t *Type) SetInterface(methods []*Field) {
   989  	t.wantEtype(TINTER)
   990  	t.methods.Set(methods)
   991  }
   992  
   993  // ArgWidth returns the total aligned argument size for a function.
   994  // It includes the receiver, parameters, and results.
   995  func (t *Type) ArgWidth() int64 {
   996  	t.wantEtype(TFUNC)
   997  	return t.extra.(*Func).Argwid
   998  }
   999  
  1000  // Size returns the width of t in bytes.
  1001  func (t *Type) Size() int64 {
  1002  	if t.kind == TSSA {
  1003  		return t.width
  1004  	}
  1005  	CalcSize(t)
  1006  	return t.width
  1007  }
  1008  
  1009  // Alignment returns the alignment of t in bytes.
  1010  func (t *Type) Alignment() int64 {
  1011  	CalcSize(t)
  1012  	return int64(t.align)
  1013  }
  1014  
  1015  func (t *Type) SimpleString() string {
  1016  	return t.kind.String()
  1017  }
  1018  
  1019  // Cmp is a comparison between values a and b.
  1020  //
  1021  //	-1 if a < b
  1022  //	 0 if a == b
  1023  //	 1 if a > b
  1024  type Cmp int8
  1025  
  1026  const (
  1027  	CMPlt = Cmp(-1)
  1028  	CMPeq = Cmp(0)
  1029  	CMPgt = Cmp(1)
  1030  )
  1031  
  1032  // Compare compares types for purposes of the SSA back
  1033  // end, returning a Cmp (one of CMPlt, CMPeq, CMPgt).
  1034  // The answers are correct for an optimizer
  1035  // or code generator, but not necessarily typechecking.
  1036  // The order chosen is arbitrary, only consistency and division
  1037  // into equivalence classes (Types that compare CMPeq) matters.
  1038  func (t *Type) Compare(x *Type) Cmp {
  1039  	if x == t {
  1040  		return CMPeq
  1041  	}
  1042  	return t.cmp(x)
  1043  }
  1044  
  1045  func cmpForNe(x bool) Cmp {
  1046  	if x {
  1047  		return CMPlt
  1048  	}
  1049  	return CMPgt
  1050  }
  1051  
  1052  func (r *Sym) cmpsym(s *Sym) Cmp {
  1053  	if r == s {
  1054  		return CMPeq
  1055  	}
  1056  	if r == nil {
  1057  		return CMPlt
  1058  	}
  1059  	if s == nil {
  1060  		return CMPgt
  1061  	}
  1062  	// Fast sort, not pretty sort
  1063  	if len(r.Name) != len(s.Name) {
  1064  		return cmpForNe(len(r.Name) < len(s.Name))
  1065  	}
  1066  	if r.Pkg != s.Pkg {
  1067  		if len(r.Pkg.Prefix) != len(s.Pkg.Prefix) {
  1068  			return cmpForNe(len(r.Pkg.Prefix) < len(s.Pkg.Prefix))
  1069  		}
  1070  		if r.Pkg.Prefix != s.Pkg.Prefix {
  1071  			return cmpForNe(r.Pkg.Prefix < s.Pkg.Prefix)
  1072  		}
  1073  	}
  1074  	if r.Name != s.Name {
  1075  		return cmpForNe(r.Name < s.Name)
  1076  	}
  1077  	return CMPeq
  1078  }
  1079  
  1080  // cmp compares two *Types t and x, returning CMPlt,
  1081  // CMPeq, CMPgt as t<x, t==x, t>x, for an arbitrary
  1082  // and optimizer-centric notion of comparison.
  1083  // TODO(josharian): make this safe for recursive interface types
  1084  // and use in signatlist sorting. See issue 19869.
  1085  func (t *Type) cmp(x *Type) Cmp {
  1086  	// This follows the structure of function identical in identity.go
  1087  	// with two exceptions.
  1088  	// 1. Symbols are compared more carefully because a <,=,> result is desired.
  1089  	// 2. Maps are treated specially to avoid endless recursion -- maps
  1090  	//    contain an internal data type not expressible in Go source code.
  1091  	if t == x {
  1092  		return CMPeq
  1093  	}
  1094  	if t == nil {
  1095  		return CMPlt
  1096  	}
  1097  	if x == nil {
  1098  		return CMPgt
  1099  	}
  1100  
  1101  	if t.kind != x.kind {
  1102  		return cmpForNe(t.kind < x.kind)
  1103  	}
  1104  
  1105  	if t.obj != nil || x.obj != nil {
  1106  		// Special case: we keep byte and uint8 separate
  1107  		// for error messages. Treat them as equal.
  1108  		switch t.kind {
  1109  		case TUINT8:
  1110  			if (t == Types[TUINT8] || t == ByteType) && (x == Types[TUINT8] || x == ByteType) {
  1111  				return CMPeq
  1112  			}
  1113  
  1114  		case TINT32:
  1115  			if (t == Types[RuneType.kind] || t == RuneType) && (x == Types[RuneType.kind] || x == RuneType) {
  1116  				return CMPeq
  1117  			}
  1118  
  1119  		case TINTER:
  1120  			// Make sure named any type matches any empty interface.
  1121  			if t == AnyType && x.IsEmptyInterface() || x == AnyType && t.IsEmptyInterface() {
  1122  				return CMPeq
  1123  			}
  1124  		}
  1125  	}
  1126  
  1127  	if c := t.Sym().cmpsym(x.Sym()); c != CMPeq {
  1128  		return c
  1129  	}
  1130  
  1131  	if x.obj != nil {
  1132  		return CMPeq
  1133  	}
  1134  	// both syms nil, look at structure below.
  1135  
  1136  	switch t.kind {
  1137  	case TBOOL, TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, TUNSAFEPTR, TUINTPTR,
  1138  		TINT8, TINT16, TINT32, TINT64, TINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINT:
  1139  		return CMPeq
  1140  
  1141  	case TSSA:
  1142  		tname := t.extra.(string)
  1143  		xname := x.extra.(string)
  1144  		// desire fast sorting, not pretty sorting.
  1145  		if len(tname) == len(xname) {
  1146  			if tname == xname {
  1147  				return CMPeq
  1148  			}
  1149  			if tname < xname {
  1150  				return CMPlt
  1151  			}
  1152  			return CMPgt
  1153  		}
  1154  		if len(tname) > len(xname) {
  1155  			return CMPgt
  1156  		}
  1157  		return CMPlt
  1158  
  1159  	case TTUPLE:
  1160  		xtup := x.extra.(*Tuple)
  1161  		ttup := t.extra.(*Tuple)
  1162  		if c := ttup.first.Compare(xtup.first); c != CMPeq {
  1163  			return c
  1164  		}
  1165  		return ttup.second.Compare(xtup.second)
  1166  
  1167  	case TRESULTS:
  1168  		xResults := x.extra.(*Results)
  1169  		tResults := t.extra.(*Results)
  1170  		xl, tl := len(xResults.Types), len(tResults.Types)
  1171  		if tl != xl {
  1172  			if tl < xl {
  1173  				return CMPlt
  1174  			}
  1175  			return CMPgt
  1176  		}
  1177  		for i := 0; i < tl; i++ {
  1178  			if c := tResults.Types[i].Compare(xResults.Types[i]); c != CMPeq {
  1179  				return c
  1180  			}
  1181  		}
  1182  		return CMPeq
  1183  
  1184  	case TMAP:
  1185  		if c := t.Key().cmp(x.Key()); c != CMPeq {
  1186  			return c
  1187  		}
  1188  		return t.Elem().cmp(x.Elem())
  1189  
  1190  	case TPTR, TSLICE:
  1191  		// No special cases for these, they are handled
  1192  		// by the general code after the switch.
  1193  
  1194  	case TSTRUCT:
  1195  		// Is this a map group type?
  1196  		if t.StructType().Map == nil {
  1197  			if x.StructType().Map != nil {
  1198  				return CMPlt // nil < non-nil
  1199  			}
  1200  			// to the general case
  1201  		} else if x.StructType().Map == nil {
  1202  			return CMPgt // nil > non-nil
  1203  		}
  1204  		// Both have non-nil Map, fallthrough to the general
  1205  		// case. Note that the map type does not directly refer
  1206  		// to the group type (it uses unsafe.Pointer). If it
  1207  		// did, this would need special handling to avoid
  1208  		// infinite recursion.
  1209  
  1210  		tfs := t.Fields()
  1211  		xfs := x.Fields()
  1212  		for i := 0; i < len(tfs) && i < len(xfs); i++ {
  1213  			t1, x1 := tfs[i], xfs[i]
  1214  			if t1.Embedded != x1.Embedded {
  1215  				return cmpForNe(t1.Embedded < x1.Embedded)
  1216  			}
  1217  			if t1.Note != x1.Note {
  1218  				return cmpForNe(t1.Note < x1.Note)
  1219  			}
  1220  			if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
  1221  				return c
  1222  			}
  1223  			if c := t1.Type.cmp(x1.Type); c != CMPeq {
  1224  				return c
  1225  			}
  1226  		}
  1227  		if len(tfs) != len(xfs) {
  1228  			return cmpForNe(len(tfs) < len(xfs))
  1229  		}
  1230  		return CMPeq
  1231  
  1232  	case TINTER:
  1233  		tfs := t.AllMethods()
  1234  		xfs := x.AllMethods()
  1235  		for i := 0; i < len(tfs) && i < len(xfs); i++ {
  1236  			t1, x1 := tfs[i], xfs[i]
  1237  			if c := t1.Sym.cmpsym(x1.Sym); c != CMPeq {
  1238  				return c
  1239  			}
  1240  			if c := t1.Type.cmp(x1.Type); c != CMPeq {
  1241  				return c
  1242  			}
  1243  		}
  1244  		if len(tfs) != len(xfs) {
  1245  			return cmpForNe(len(tfs) < len(xfs))
  1246  		}
  1247  		return CMPeq
  1248  
  1249  	case TFUNC:
  1250  		if tn, xn := t.NumRecvs(), x.NumRecvs(); tn != xn {
  1251  			return cmpForNe(tn < xn)
  1252  		}
  1253  		if tn, xn := t.NumParams(), x.NumParams(); tn != xn {
  1254  			return cmpForNe(tn < xn)
  1255  		}
  1256  		if tn, xn := t.NumResults(), x.NumResults(); tn != xn {
  1257  			return cmpForNe(tn < xn)
  1258  		}
  1259  		if tv, xv := t.IsVariadic(), x.IsVariadic(); tv != xv {
  1260  			return cmpForNe(!tv)
  1261  		}
  1262  
  1263  		tfs := t.RecvParamsResults()
  1264  		xfs := x.RecvParamsResults()
  1265  		for i, tf := range tfs {
  1266  			if c := tf.Type.cmp(xfs[i].Type); c != CMPeq {
  1267  				return c
  1268  			}
  1269  		}
  1270  		return CMPeq
  1271  
  1272  	case TARRAY:
  1273  		if t.NumElem() != x.NumElem() {
  1274  			return cmpForNe(t.NumElem() < x.NumElem())
  1275  		}
  1276  
  1277  	case TCHAN:
  1278  		if t.ChanDir() != x.ChanDir() {
  1279  			return cmpForNe(t.ChanDir() < x.ChanDir())
  1280  		}
  1281  
  1282  	default:
  1283  		e := fmt.Sprintf("Do not know how to compare %v with %v", t, x)
  1284  		panic(e)
  1285  	}
  1286  
  1287  	// Common element type comparison for TARRAY, TCHAN, TPTR, and TSLICE.
  1288  	return t.Elem().cmp(x.Elem())
  1289  }
  1290  
  1291  // IsKind reports whether t is a Type of the specified kind.
  1292  func (t *Type) IsKind(et Kind) bool {
  1293  	return t != nil && t.kind == et
  1294  }
  1295  
  1296  func (t *Type) IsBoolean() bool {
  1297  	return t.kind == TBOOL
  1298  }
  1299  
  1300  var unsignedEType = [...]Kind{
  1301  	TINT8:    TUINT8,
  1302  	TUINT8:   TUINT8,
  1303  	TINT16:   TUINT16,
  1304  	TUINT16:  TUINT16,
  1305  	TINT32:   TUINT32,
  1306  	TUINT32:  TUINT32,
  1307  	TINT64:   TUINT64,
  1308  	TUINT64:  TUINT64,
  1309  	TINT:     TUINT,
  1310  	TUINT:    TUINT,
  1311  	TUINTPTR: TUINTPTR,
  1312  }
  1313  
  1314  // ToUnsigned returns the unsigned equivalent of integer type t.
  1315  func (t *Type) ToUnsigned() *Type {
  1316  	if !t.IsInteger() {
  1317  		base.Fatalf("unsignedType(%v)", t)
  1318  	}
  1319  	return Types[unsignedEType[t.kind]]
  1320  }
  1321  
  1322  func (t *Type) IsInteger() bool {
  1323  	switch t.kind {
  1324  	case TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32, TINT64, TUINT64, TINT, TUINT, TUINTPTR:
  1325  		return true
  1326  	}
  1327  	return t == UntypedInt || t == UntypedRune
  1328  }
  1329  
  1330  func (t *Type) IsSigned() bool {
  1331  	switch t.kind {
  1332  	case TINT8, TINT16, TINT32, TINT64, TINT:
  1333  		return true
  1334  	}
  1335  	return false
  1336  }
  1337  
  1338  func (t *Type) IsUnsigned() bool {
  1339  	switch t.kind {
  1340  	case TUINT8, TUINT16, TUINT32, TUINT64, TUINT, TUINTPTR:
  1341  		return true
  1342  	}
  1343  	return false
  1344  }
  1345  
  1346  func (t *Type) IsFloat() bool {
  1347  	return t.kind == TFLOAT32 || t.kind == TFLOAT64 || t == UntypedFloat
  1348  }
  1349  
  1350  func (t *Type) IsComplex() bool {
  1351  	return t.kind == TCOMPLEX64 || t.kind == TCOMPLEX128 || t == UntypedComplex
  1352  }
  1353  
  1354  // IsPtr reports whether t is a regular Go pointer type.
  1355  // This does not include unsafe.Pointer.
  1356  func (t *Type) IsPtr() bool {
  1357  	return t.kind == TPTR
  1358  }
  1359  
  1360  // IsPtrElem reports whether t is the element of a pointer (to t).
  1361  func (t *Type) IsPtrElem() bool {
  1362  	return t.cache.ptr != nil
  1363  }
  1364  
  1365  // IsUnsafePtr reports whether t is an unsafe pointer.
  1366  func (t *Type) IsUnsafePtr() bool {
  1367  	return t.kind == TUNSAFEPTR
  1368  }
  1369  
  1370  // IsUintptr reports whether t is a uintptr.
  1371  func (t *Type) IsUintptr() bool {
  1372  	return t.kind == TUINTPTR
  1373  }
  1374  
  1375  // IsPtrShaped reports whether t is represented by a single machine pointer.
  1376  // In addition to regular Go pointer types, this includes map, channel, and
  1377  // function types and unsafe.Pointer. It does not include array or struct types
  1378  // that consist of a single pointer shaped type.
  1379  // TODO(mdempsky): Should it? See golang.org/issue/15028.
  1380  func (t *Type) IsPtrShaped() bool {
  1381  	return t.kind == TPTR || t.kind == TUNSAFEPTR ||
  1382  		t.kind == TMAP || t.kind == TCHAN || t.kind == TFUNC
  1383  }
  1384  
  1385  // HasNil reports whether the set of values determined by t includes nil.
  1386  func (t *Type) HasNil() bool {
  1387  	switch t.kind {
  1388  	case TCHAN, TFUNC, TINTER, TMAP, TNIL, TPTR, TSLICE, TUNSAFEPTR:
  1389  		return true
  1390  	}
  1391  	return false
  1392  }
  1393  
  1394  func (t *Type) IsString() bool {
  1395  	return t.kind == TSTRING
  1396  }
  1397  
  1398  func (t *Type) IsMap() bool {
  1399  	return t.kind == TMAP
  1400  }
  1401  
  1402  func (t *Type) IsChan() bool {
  1403  	return t.kind == TCHAN
  1404  }
  1405  
  1406  func (t *Type) IsSlice() bool {
  1407  	return t.kind == TSLICE
  1408  }
  1409  
  1410  func (t *Type) IsArray() bool {
  1411  	return t.kind == TARRAY
  1412  }
  1413  
  1414  func (t *Type) IsStruct() bool {
  1415  	return t.kind == TSTRUCT
  1416  }
  1417  
  1418  func (t *Type) IsInterface() bool {
  1419  	return t.kind == TINTER
  1420  }
  1421  
  1422  // IsEmptyInterface reports whether t is an empty interface type.
  1423  func (t *Type) IsEmptyInterface() bool {
  1424  	return t.IsInterface() && len(t.AllMethods()) == 0
  1425  }
  1426  
  1427  // IsScalar reports whether 't' is a scalar Go type, e.g.
  1428  // bool/int/float/complex. Note that struct and array types consisting
  1429  // of a single scalar element are not considered scalar, likewise
  1430  // pointer types are also not considered scalar.
  1431  func (t *Type) IsScalar() bool {
  1432  	switch t.kind {
  1433  	case TBOOL, TINT8, TUINT8, TINT16, TUINT16, TINT32,
  1434  		TUINT32, TINT64, TUINT64, TINT, TUINT,
  1435  		TUINTPTR, TCOMPLEX64, TCOMPLEX128, TFLOAT32, TFLOAT64:
  1436  		return true
  1437  	}
  1438  	return false
  1439  }
  1440  
  1441  func (t *Type) PtrTo() *Type {
  1442  	return NewPtr(t)
  1443  }
  1444  
  1445  func (t *Type) NumFields() int {
  1446  	if t.kind == TRESULTS {
  1447  		return len(t.extra.(*Results).Types)
  1448  	}
  1449  	return len(t.Fields())
  1450  }
  1451  func (t *Type) FieldType(i int) *Type {
  1452  	if t.kind == TTUPLE {
  1453  		switch i {
  1454  		case 0:
  1455  			return t.extra.(*Tuple).first
  1456  		case 1:
  1457  			return t.extra.(*Tuple).second
  1458  		default:
  1459  			panic("bad tuple index")
  1460  		}
  1461  	}
  1462  	if t.kind == TRESULTS {
  1463  		return t.extra.(*Results).Types[i]
  1464  	}
  1465  	return t.Field(i).Type
  1466  }
  1467  func (t *Type) FieldOff(i int) int64 {
  1468  	return t.Field(i).Offset
  1469  }
  1470  func (t *Type) FieldName(i int) string {
  1471  	return t.Field(i).Sym.Name
  1472  }
  1473  
  1474  // OffsetOf reports the offset of the field of a struct.
  1475  // The field is looked up by name.
  1476  func (t *Type) OffsetOf(name string) int64 {
  1477  	if t.kind != TSTRUCT {
  1478  		base.Fatalf("can't call OffsetOf on non-struct %v", t)
  1479  	}
  1480  	for _, f := range t.Fields() {
  1481  		if f.Sym.Name == name {
  1482  			return f.Offset
  1483  		}
  1484  	}
  1485  	base.Fatalf("couldn't find field %s in %v", name, t)
  1486  	return -1
  1487  }
  1488  
  1489  func (t *Type) NumElem() int64 {
  1490  	t.wantEtype(TARRAY)
  1491  	return t.extra.(*Array).Bound
  1492  }
  1493  
  1494  type componentsIncludeBlankFields bool
  1495  
  1496  const (
  1497  	IgnoreBlankFields componentsIncludeBlankFields = false
  1498  	CountBlankFields  componentsIncludeBlankFields = true
  1499  )
  1500  
  1501  // NumComponents returns the number of primitive elements that compose t.
  1502  // Struct and array types are flattened for the purpose of counting.
  1503  // All other types (including string, slice, and interface types) count as one element.
  1504  // If countBlank is IgnoreBlankFields, then blank struct fields
  1505  // (and their comprised elements) are excluded from the count.
  1506  // struct { x, y [3]int } has six components; [10]struct{ x, y string } has twenty.
  1507  func (t *Type) NumComponents(countBlank componentsIncludeBlankFields) int64 {
  1508  	switch t.kind {
  1509  	case TSTRUCT:
  1510  		if t.IsFuncArgStruct() {
  1511  			base.Fatalf("NumComponents func arg struct")
  1512  		}
  1513  		var n int64
  1514  		for _, f := range t.Fields() {
  1515  			if countBlank == IgnoreBlankFields && f.Sym.IsBlank() {
  1516  				continue
  1517  			}
  1518  			n += f.Type.NumComponents(countBlank)
  1519  		}
  1520  		return n
  1521  	case TARRAY:
  1522  		return t.NumElem() * t.Elem().NumComponents(countBlank)
  1523  	}
  1524  	return 1
  1525  }
  1526  
  1527  // SoleComponent returns the only primitive component in t,
  1528  // if there is exactly one. Otherwise, it returns nil.
  1529  // Components are counted as in NumComponents, including blank fields.
  1530  // Keep in sync with cmd/compile/internal/walk/convert.go:soleComponent.
  1531  func (t *Type) SoleComponent() *Type {
  1532  	switch t.kind {
  1533  	case TSTRUCT:
  1534  		if t.IsFuncArgStruct() {
  1535  			base.Fatalf("SoleComponent func arg struct")
  1536  		}
  1537  		if t.NumFields() != 1 {
  1538  			return nil
  1539  		}
  1540  		return t.Field(0).Type.SoleComponent()
  1541  	case TARRAY:
  1542  		if t.NumElem() != 1 {
  1543  			return nil
  1544  		}
  1545  		return t.Elem().SoleComponent()
  1546  	}
  1547  	return t
  1548  }
  1549  
  1550  // ChanDir returns the direction of a channel type t.
  1551  // The direction will be one of Crecv, Csend, or Cboth.
  1552  func (t *Type) ChanDir() ChanDir {
  1553  	t.wantEtype(TCHAN)
  1554  	return t.extra.(*Chan).Dir
  1555  }
  1556  
  1557  func (t *Type) IsMemory() bool {
  1558  	if t == TypeMem || t.kind == TTUPLE && t.extra.(*Tuple).second == TypeMem {
  1559  		return true
  1560  	}
  1561  	if t.kind == TRESULTS {
  1562  		if types := t.extra.(*Results).Types; len(types) > 0 && types[len(types)-1] == TypeMem {
  1563  			return true
  1564  		}
  1565  	}
  1566  	return false
  1567  }
  1568  func (t *Type) IsFlags() bool   { return t == TypeFlags }
  1569  func (t *Type) IsVoid() bool    { return t == TypeVoid }
  1570  func (t *Type) IsTuple() bool   { return t.kind == TTUPLE }
  1571  func (t *Type) IsResults() bool { return t.kind == TRESULTS }
  1572  
  1573  // IsUntyped reports whether t is an untyped type.
  1574  func (t *Type) IsUntyped() bool {
  1575  	if t == nil {
  1576  		return false
  1577  	}
  1578  	if t == UntypedString || t == UntypedBool {
  1579  		return true
  1580  	}
  1581  	switch t.kind {
  1582  	case TNIL, TIDEAL:
  1583  		return true
  1584  	}
  1585  	return false
  1586  }
  1587  
  1588  // HasPointers reports whether t contains a heap pointer.
  1589  // Note that this function ignores pointers to not-in-heap types.
  1590  func (t *Type) HasPointers() bool {
  1591  	return PtrDataSize(t) > 0
  1592  }
  1593  
  1594  var recvType *Type
  1595  
  1596  // FakeRecvType returns the singleton type used for interface method receivers.
  1597  func FakeRecvType() *Type {
  1598  	if recvType == nil {
  1599  		recvType = NewPtr(newType(TSTRUCT))
  1600  	}
  1601  	return recvType
  1602  }
  1603  
  1604  func FakeRecv() *Field {
  1605  	return NewField(base.AutogeneratedPos, nil, FakeRecvType())
  1606  }
  1607  
  1608  var (
  1609  	// TSSA types. HasPointers assumes these are pointer-free.
  1610  	TypeInvalid   = newSSA("invalid")
  1611  	TypeMem       = newSSA("mem")
  1612  	TypeFlags     = newSSA("flags")
  1613  	TypeVoid      = newSSA("void")
  1614  	TypeInt128    = newSSA("int128")
  1615  	TypeVec128    = newSIMD("vec128")
  1616  	TypeVec256    = newSIMD("vec256")
  1617  	TypeVec512    = newSIMD("vec512")
  1618  	TypeMask      = newSIMD("mask") // not a vector, not 100% sure what this should be.
  1619  	TypeResultMem = newResults([]*Type{TypeMem})
  1620  )
  1621  
  1622  func init() {
  1623  	TypeInt128.width = 16
  1624  	TypeInt128.align = 8
  1625  
  1626  	TypeVec128.width = 16
  1627  	TypeVec128.align = 8
  1628  	TypeVec256.width = 32
  1629  	TypeVec256.align = 8
  1630  	TypeVec512.width = 64
  1631  	TypeVec512.align = 8
  1632  
  1633  	TypeMask.width = 8 // This will depend on the architecture; spilling will be "interesting".
  1634  	TypeMask.align = 8
  1635  }
  1636  
  1637  // NewNamed returns a new named type for the given type name. obj should be an
  1638  // ir.Name. The new type is incomplete (marked as TFORW kind), and the underlying
  1639  // type should be set later via SetUnderlying(). References to the type are
  1640  // maintained until the type is filled in, so those references can be updated when
  1641  // the type is complete.
  1642  func NewNamed(obj Object) *Type {
  1643  	t := newType(TFORW)
  1644  	t.obj = obj
  1645  	sym := obj.Sym()
  1646  	if sym.Pkg == ShapePkg {
  1647  		t.SetIsShape(true)
  1648  		t.SetHasShape(true)
  1649  	}
  1650  	if sym.Pkg.Path == "internal/runtime/sys" && sym.Name == "nih" {
  1651  		// Recognize the special not-in-heap type. Any type including
  1652  		// this type will also be not-in-heap.
  1653  		// This logic is duplicated in go/types and
  1654  		// cmd/compile/internal/types2.
  1655  		t.SetNotInHeap(true)
  1656  	}
  1657  	return t
  1658  }
  1659  
  1660  // Obj returns the canonical type name node for a named type t, nil for an unnamed type.
  1661  func (t *Type) Obj() Object {
  1662  	return t.obj
  1663  }
  1664  
  1665  // SetUnderlying sets the underlying type of an incomplete type (i.e. type whose kind
  1666  // is currently TFORW). SetUnderlying automatically updates any types that were waiting
  1667  // for this type to be completed.
  1668  func (t *Type) SetUnderlying(underlying *Type) {
  1669  	if underlying.kind == TFORW {
  1670  		// This type isn't computed yet; when it is, update n.
  1671  		underlying.forwardType().Copyto = append(underlying.forwardType().Copyto, t)
  1672  		return
  1673  	}
  1674  
  1675  	ft := t.forwardType()
  1676  
  1677  	// TODO(mdempsky): Fix Type rekinding.
  1678  	t.kind = underlying.kind
  1679  	t.extra = underlying.extra
  1680  	t.width = underlying.width
  1681  	t.align = underlying.align
  1682  	t.alg = underlying.alg
  1683  	t.ptrBytes = underlying.ptrBytes
  1684  	t.intRegs = underlying.intRegs
  1685  	t.floatRegs = underlying.floatRegs
  1686  	t.underlying = underlying.underlying
  1687  
  1688  	if underlying.NotInHeap() {
  1689  		t.SetNotInHeap(true)
  1690  	}
  1691  	if underlying.HasShape() {
  1692  		t.SetHasShape(true)
  1693  	}
  1694  	if underlying.flags&typeIsSIMD != 0 {
  1695  		simdify(t, underlying.flags&typeIsSIMDTag != 0)
  1696  		// simdify assigns the register counts of a vector; keep the
  1697  		// underlying type's, which differ for an SVE predicate (passed in
  1698  		// memory, see CalcStructSize).
  1699  		t.intRegs = underlying.intRegs
  1700  		t.floatRegs = underlying.floatRegs
  1701  	}
  1702  
  1703  	// spec: "The declared type does not inherit any methods bound
  1704  	// to the existing type, but the method set of an interface
  1705  	// type [...] remains unchanged."
  1706  	if t.IsInterface() {
  1707  		t.methods = underlying.methods
  1708  		t.allMethods = underlying.allMethods
  1709  	}
  1710  
  1711  	// Update types waiting on this type.
  1712  	for _, w := range ft.Copyto {
  1713  		w.SetUnderlying(t)
  1714  	}
  1715  
  1716  	// Double-check use of type as embedded type.
  1717  	if ft.Embedlineno.IsKnown() {
  1718  		if t.IsPtr() || t.IsUnsafePtr() {
  1719  			base.ErrorfAt(ft.Embedlineno, errors.InvalidPtrEmbed, "embedded type cannot be a pointer")
  1720  		}
  1721  	}
  1722  }
  1723  
  1724  func fieldsHasShape(fields []*Field) bool {
  1725  	for _, f := range fields {
  1726  		if f.Type != nil && f.Type.HasShape() {
  1727  			return true
  1728  		}
  1729  	}
  1730  	return false
  1731  }
  1732  
  1733  // NewInterface returns a new interface for the given methods and
  1734  // embedded types. Embedded types are specified as fields with no Sym.
  1735  func NewInterface(methods []*Field) *Type {
  1736  	t := newType(TINTER)
  1737  	t.SetInterface(methods)
  1738  	for _, f := range methods {
  1739  		// f.Type could be nil for a broken interface declaration
  1740  		if f.Type != nil && f.Type.HasShape() {
  1741  			t.SetHasShape(true)
  1742  			break
  1743  		}
  1744  	}
  1745  	return t
  1746  }
  1747  
  1748  // NewSignature returns a new function type for the given receiver,
  1749  // parameters, and results, any of which may be nil.
  1750  func NewSignature(recv *Field, params, results []*Field) *Type {
  1751  	startParams := 0
  1752  	if recv != nil {
  1753  		startParams = 1
  1754  	}
  1755  	startResults := startParams + len(params)
  1756  
  1757  	allParams := make([]*Field, startResults+len(results))
  1758  	if recv != nil {
  1759  		allParams[0] = recv
  1760  	}
  1761  	copy(allParams[startParams:], params)
  1762  	copy(allParams[startResults:], results)
  1763  
  1764  	t := newType(TFUNC)
  1765  	ft := t.funcType()
  1766  
  1767  	funargs := func(fields []*Field) *Type {
  1768  		s := NewStruct(fields)
  1769  		s.StructType().ParamTuple = true
  1770  		return s
  1771  	}
  1772  
  1773  	ft.allParams = allParams
  1774  	ft.startParams = startParams
  1775  	ft.startResults = startResults
  1776  
  1777  	ft.resultsTuple = funargs(allParams[startResults:])
  1778  
  1779  	if fieldsHasShape(allParams) {
  1780  		t.SetHasShape(true)
  1781  	}
  1782  
  1783  	return t
  1784  }
  1785  
  1786  // NewStruct returns a new struct with the given fields.
  1787  func NewStruct(fields []*Field) *Type {
  1788  	t := newType(TSTRUCT)
  1789  	t.setFields(fields)
  1790  	if fieldsHasShape(fields) {
  1791  		t.SetHasShape(true)
  1792  	}
  1793  	for _, f := range fields {
  1794  		if f.Type.NotInHeap() {
  1795  			t.SetNotInHeap(true)
  1796  			break
  1797  		}
  1798  	}
  1799  
  1800  	return t
  1801  }
  1802  
  1803  var (
  1804  	IsInt     [NTYPE]bool
  1805  	IsFloat   [NTYPE]bool
  1806  	IsComplex [NTYPE]bool
  1807  	IsSimple  [NTYPE]bool
  1808  )
  1809  
  1810  var IsOrdered [NTYPE]bool
  1811  
  1812  // IsReflexive reports whether t has a reflexive equality operator.
  1813  // That is, if x==x for all x of type t.
  1814  func IsReflexive(t *Type) bool {
  1815  	switch t.Kind() {
  1816  	case TBOOL,
  1817  		TINT,
  1818  		TUINT,
  1819  		TINT8,
  1820  		TUINT8,
  1821  		TINT16,
  1822  		TUINT16,
  1823  		TINT32,
  1824  		TUINT32,
  1825  		TINT64,
  1826  		TUINT64,
  1827  		TUINTPTR,
  1828  		TPTR,
  1829  		TUNSAFEPTR,
  1830  		TSTRING,
  1831  		TCHAN:
  1832  		return true
  1833  
  1834  	case TFLOAT32,
  1835  		TFLOAT64,
  1836  		TCOMPLEX64,
  1837  		TCOMPLEX128,
  1838  		TINTER:
  1839  		return false
  1840  
  1841  	case TARRAY:
  1842  		return IsReflexive(t.Elem())
  1843  
  1844  	case TSTRUCT:
  1845  		for _, t1 := range t.Fields() {
  1846  			if !IsReflexive(t1.Type) {
  1847  				return false
  1848  			}
  1849  		}
  1850  		return true
  1851  
  1852  	default:
  1853  		base.Fatalf("bad type for map key: %v", t)
  1854  		return false
  1855  	}
  1856  }
  1857  
  1858  // Can this type be stored directly in an interface word?
  1859  // Yes, if the representation is a single pointer.
  1860  func IsDirectIface(t *Type) bool {
  1861  	return t.Size() == int64(PtrSize) && PtrDataSize(t) == int64(PtrSize)
  1862  }
  1863  
  1864  // IsInterfaceMethod reports whether (field) m is
  1865  // an interface method. Such methods have the
  1866  // special receiver type types.FakeRecvType().
  1867  func IsInterfaceMethod(f *Type) bool {
  1868  	return f.Recv().Type == FakeRecvType()
  1869  }
  1870  
  1871  // IsMethodApplicable reports whether method m can be called on a
  1872  // value of type t. This is necessary because we compute a single
  1873  // method set for both T and *T, but some *T methods are not
  1874  // applicable to T receivers.
  1875  func IsMethodApplicable(t *Type, m *Field) bool {
  1876  	return t.IsPtr() || !m.Type.Recv().Type.IsPtr() || IsInterfaceMethod(m.Type) || m.Embedded == 2
  1877  }
  1878  
  1879  // RuntimeSymName returns the name of s if it's in package "runtime"; otherwise
  1880  // it returns "".
  1881  func RuntimeSymName(s *Sym) string {
  1882  	if s.Pkg.Path == "runtime" {
  1883  		return s.Name
  1884  	}
  1885  	return ""
  1886  }
  1887  
  1888  // ReflectSymName returns the name of s if it's in package "reflect"; otherwise
  1889  // it returns "".
  1890  func ReflectSymName(s *Sym) string {
  1891  	if s.Pkg.Path == "reflect" {
  1892  		return s.Name
  1893  	}
  1894  	return ""
  1895  }
  1896  
  1897  // IsNoInstrumentPkg reports whether p is a package that
  1898  // should not be instrumented.
  1899  func IsNoInstrumentPkg(p *Pkg) bool {
  1900  	return objabi.LookupPkgSpecial(p.Path).NoInstrument
  1901  }
  1902  
  1903  // IsNoRacePkg reports whether p is a package that
  1904  // should not be race instrumented.
  1905  func IsNoRacePkg(p *Pkg) bool {
  1906  	return objabi.LookupPkgSpecial(p.Path).NoRaceFunc
  1907  }
  1908  
  1909  // IsRuntimePkg reports whether p is a runtime package.
  1910  func IsRuntimePkg(p *Pkg) bool {
  1911  	return objabi.LookupPkgSpecial(p.Path).Runtime
  1912  }
  1913  
  1914  // ReceiverBaseType returns the underlying type, if any,
  1915  // that owns methods with receiver parameter t.
  1916  // The result is either a named type or an anonymous struct.
  1917  func ReceiverBaseType(t *Type) *Type {
  1918  	if t == nil {
  1919  		return nil
  1920  	}
  1921  
  1922  	// Strip away pointer if it's there.
  1923  	if t.IsPtr() {
  1924  		if t.Sym() != nil {
  1925  			return nil
  1926  		}
  1927  		t = t.Elem()
  1928  		if t == nil {
  1929  			return nil
  1930  		}
  1931  	}
  1932  
  1933  	// Must be a named type or anonymous struct.
  1934  	if t.Sym() == nil && !t.IsStruct() {
  1935  		return nil
  1936  	}
  1937  
  1938  	// Check types.
  1939  	if IsSimple[t.Kind()] {
  1940  		return t
  1941  	}
  1942  	switch t.Kind() {
  1943  	case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT:
  1944  		return t
  1945  	}
  1946  	return nil
  1947  }
  1948  
  1949  func FloatForComplex(t *Type) *Type {
  1950  	switch t.Kind() {
  1951  	case TCOMPLEX64:
  1952  		return Types[TFLOAT32]
  1953  	case TCOMPLEX128:
  1954  		return Types[TFLOAT64]
  1955  	}
  1956  	base.Fatalf("unexpected type: %v", t)
  1957  	return nil
  1958  }
  1959  
  1960  func ComplexForFloat(t *Type) *Type {
  1961  	switch t.Kind() {
  1962  	case TFLOAT32:
  1963  		return Types[TCOMPLEX64]
  1964  	case TFLOAT64:
  1965  		return Types[TCOMPLEX128]
  1966  	}
  1967  	base.Fatalf("unexpected type: %v", t)
  1968  	return nil
  1969  }
  1970  
  1971  func TypeSym(t *Type) *Sym {
  1972  	return TypeSymLookup(TypeSymName(t))
  1973  }
  1974  
  1975  func TypeSymLookup(name string) *Sym {
  1976  	typepkgmu.Lock()
  1977  	s := typepkg.Lookup(name)
  1978  	typepkgmu.Unlock()
  1979  	return s
  1980  }
  1981  
  1982  func TypeSymName(t *Type) string {
  1983  	return t.LinkString()
  1984  }
  1985  
  1986  // Fake package for runtime type info (headers)
  1987  // Don't access directly, use typeLookup below.
  1988  var (
  1989  	typepkgmu sync.Mutex // protects typepkg lookups
  1990  	typepkg   = NewPkg("type", "type")
  1991  )
  1992  
  1993  var SimType [NTYPE]Kind
  1994  
  1995  // Fake package for shape types (see typecheck.Shapify()).
  1996  var ShapePkg = NewPkg("go.shape", "go.shape")
  1997  
  1998  func (t *Type) IsSIMD() bool {
  1999  	return t.flags&typeIsSIMD != 0
  2000  }
  2001  func (t *Type) ContainsSIMD() bool {
  2002  	if t.IsSIMD() {
  2003  		return true
  2004  	}
  2005  	switch t.Kind() {
  2006  	case TARRAY:
  2007  		return t.Elem().ContainsSIMD()
  2008  	case TSTRUCT:
  2009  		for _, f := range t.Fields() {
  2010  			if f.Type.ContainsSIMD() {
  2011  				return true
  2012  			}
  2013  		}
  2014  	}
  2015  	return false
  2016  }
  2017  

View as plain text