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