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