// A Type represents a Go type.
type Type struct {
- // Extra contains extra etype-specific fields.
+ // extra contains extra etype-specific fields.
// As an optimization, those etype-specific structs which contain exactly
// one pointer-shaped field are stored as values rather than pointers when possible.
//
// TSLICE: Slice
// TSSA: string
// TTYPEPARAM: *Typeparam
- Extra interface{}
+ extra interface{}
// Width is the width of this Type in bytes.
Width int64 // valid if Align > 0
func (t *Type) Pkg() *Pkg {
switch t.kind {
case TFUNC:
- return t.Extra.(*Func).pkg
+ return t.extra.(*Func).pkg
case TSTRUCT:
- return t.Extra.(*Struct).pkg
+ return t.extra.(*Struct).pkg
case TINTER:
- return t.Extra.(*Interface).pkg
+ return t.extra.(*Interface).pkg
default:
base.Fatalf("Pkg: unexpected kind: %v", t)
return nil
// MapType returns t's extra map-specific fields.
func (t *Type) MapType() *Map {
t.wantEtype(TMAP)
- return t.Extra.(*Map)
+ return t.extra.(*Map)
}
// Forward contains Type fields specific to forward types.
// ForwardType returns t's extra forward-type-specific fields.
func (t *Type) ForwardType() *Forward {
t.wantEtype(TFORW)
- return t.Extra.(*Forward)
+ return t.extra.(*Forward)
}
// Func contains Type fields specific to func types.
// FuncType returns t's extra func-specific fields.
func (t *Type) FuncType() *Func {
t.wantEtype(TFUNC)
- return t.Extra.(*Func)
+ return t.extra.(*Func)
}
// StructType contains Type fields specific to struct types.
// StructType returns t's extra struct-specific fields.
func (t *Type) StructType() *Struct {
t.wantEtype(TSTRUCT)
- return t.Extra.(*Struct)
+ return t.extra.(*Struct)
}
// Interface contains Type fields specific to interface types.
// ChanType returns t's extra channel-specific fields.
func (t *Type) ChanType() *Chan {
t.wantEtype(TCHAN)
- return t.Extra.(*Chan)
+ return t.extra.(*Chan)
}
type Tuple struct {
// TODO(josharian): lazily initialize some of these?
switch t.kind {
case TMAP:
- t.Extra = new(Map)
+ t.extra = new(Map)
case TFORW:
- t.Extra = new(Forward)
+ t.extra = new(Forward)
case TFUNC:
- t.Extra = new(Func)
+ t.extra = new(Func)
case TSTRUCT:
- t.Extra = new(Struct)
+ t.extra = new(Struct)
case TINTER:
- t.Extra = new(Interface)
+ t.extra = new(Interface)
case TPTR:
- t.Extra = Ptr{}
+ t.extra = Ptr{}
case TCHANARGS:
- t.Extra = ChanArgs{}
+ t.extra = ChanArgs{}
case TFUNCARGS:
- t.Extra = FuncArgs{}
+ t.extra = FuncArgs{}
case TCHAN:
- t.Extra = new(Chan)
+ t.extra = new(Chan)
case TTUPLE:
- t.Extra = new(Tuple)
+ t.extra = new(Tuple)
case TRESULTS:
- t.Extra = new(Results)
+ t.extra = new(Results)
case TTYPEPARAM:
- t.Extra = new(Typeparam)
+ t.extra = new(Typeparam)
case TUNION:
- t.Extra = new(Union)
+ t.extra = new(Union)
}
return t
}
base.Fatalf("NewArray: invalid bound %v", bound)
}
t := New(TARRAY)
- t.Extra = &Array{Elem: elem, Bound: bound}
+ t.extra = &Array{Elem: elem, Bound: bound}
t.SetNotInHeap(elem.NotInHeap())
if elem.HasTParam() {
t.SetHasTParam(true)
}
t := New(TSLICE)
- t.Extra = Slice{Elem: elem}
+ t.extra = Slice{Elem: elem}
elem.cache.slice = t
if elem.HasTParam() {
t.SetHasTParam(true)
func NewTuple(t1, t2 *Type) *Type {
t := New(TTUPLE)
- t.Extra.(*Tuple).first = t1
- t.Extra.(*Tuple).second = t2
+ t.extra.(*Tuple).first = t1
+ t.extra.(*Tuple).second = t2
if t1.HasTParam() || t2.HasTParam() {
t.SetHasTParam(true)
}
func newResults(types []*Type) *Type {
t := New(TRESULTS)
- t.Extra.(*Results).Types = types
+ t.extra.(*Results).Types = types
return t
}
func newSSA(name string) *Type {
t := New(TSSA)
- t.Extra = name
+ t.extra = name
return t
}
}
t := New(TPTR)
- t.Extra = Ptr{Elem: elem}
+ t.extra = Ptr{Elem: elem}
t.Width = int64(PtrSize)
t.Align = uint8(PtrSize)
if NewPtrCacheEnabled {
// NewChanArgs returns a new TCHANARGS type for channel type c.
func NewChanArgs(c *Type) *Type {
t := New(TCHANARGS)
- t.Extra = ChanArgs{T: c}
+ t.extra = ChanArgs{T: c}
return t
}
// NewFuncArgs returns a new TFUNCARGS type for func type f.
func NewFuncArgs(f *Type) *Type {
t := New(TFUNCARGS)
- t.Extra = FuncArgs{T: f}
+ t.extra = FuncArgs{T: f}
return t
}
elem := SubstAny(t.Elem(), types)
if elem != t.Elem() {
t = t.copy()
- t.Extra = Ptr{Elem: elem}
+ t.extra = Ptr{Elem: elem}
}
case TARRAY:
elem := SubstAny(t.Elem(), types)
if elem != t.Elem() {
t = t.copy()
- t.Extra.(*Array).Elem = elem
+ t.extra.(*Array).Elem = elem
}
case TSLICE:
elem := SubstAny(t.Elem(), types)
if elem != t.Elem() {
t = t.copy()
- t.Extra = Slice{Elem: elem}
+ t.extra = Slice{Elem: elem}
}
case TCHAN:
elem := SubstAny(t.Elem(), types)
if elem != t.Elem() {
t = t.copy()
- t.Extra.(*Chan).Elem = elem
+ t.extra.(*Chan).Elem = elem
}
case TMAP:
elem := SubstAny(t.Elem(), types)
if key != t.Key() || elem != t.Elem() {
t = t.copy()
- t.Extra.(*Map).Key = key
- t.Extra.(*Map).Elem = elem
+ t.extra.(*Map).Key = key
+ t.extra.(*Map).Elem = elem
}
case TFUNC:
// copy any *T Extra fields, to avoid aliasing
switch t.kind {
case TMAP:
- x := *t.Extra.(*Map)
- nt.Extra = &x
+ x := *t.extra.(*Map)
+ nt.extra = &x
case TFORW:
- x := *t.Extra.(*Forward)
- nt.Extra = &x
+ x := *t.extra.(*Forward)
+ nt.extra = &x
case TFUNC:
- x := *t.Extra.(*Func)
- nt.Extra = &x
+ x := *t.extra.(*Func)
+ nt.extra = &x
case TSTRUCT:
- x := *t.Extra.(*Struct)
- nt.Extra = &x
+ x := *t.extra.(*Struct)
+ nt.extra = &x
case TINTER:
- x := *t.Extra.(*Interface)
- nt.Extra = &x
+ x := *t.extra.(*Interface)
+ nt.extra = &x
case TCHAN:
- x := *t.Extra.(*Chan)
- nt.Extra = &x
+ x := *t.extra.(*Chan)
+ nt.extra = &x
case TARRAY:
- x := *t.Extra.(*Array)
- nt.Extra = &x
+ x := *t.extra.(*Array)
+ nt.extra = &x
case TTYPEPARAM:
base.Fatalf("typeparam types cannot be copied")
case TTUPLE, TSSA, TRESULTS:
// Key returns the key type of map type t.
func (t *Type) Key() *Type {
t.wantEtype(TMAP)
- return t.Extra.(*Map).Key
+ return t.extra.(*Map).Key
}
// Elem returns the type of elements of t.
func (t *Type) Elem() *Type {
switch t.kind {
case TPTR:
- return t.Extra.(Ptr).Elem
+ return t.extra.(Ptr).Elem
case TARRAY:
- return t.Extra.(*Array).Elem
+ return t.extra.(*Array).Elem
case TSLICE:
- return t.Extra.(Slice).Elem
+ return t.extra.(Slice).Elem
case TCHAN:
- return t.Extra.(*Chan).Elem
+ return t.extra.(*Chan).Elem
case TMAP:
- return t.Extra.(*Map).Elem
+ return t.extra.(*Map).Elem
}
base.Fatalf("Type.Elem %s", t.kind)
return nil
// ChanArgs returns the channel type for TCHANARGS type t.
func (t *Type) ChanArgs() *Type {
t.wantEtype(TCHANARGS)
- return t.Extra.(ChanArgs).T
+ return t.extra.(ChanArgs).T
}
// FuncArgs returns the func type for TFUNCARGS type t.
func (t *Type) FuncArgs() *Type {
t.wantEtype(TFUNCARGS)
- return t.Extra.(FuncArgs).T
+ return t.extra.(FuncArgs).T
}
// IsFuncArgStruct reports whether t is a struct representing function parameters or results.
func (t *Type) IsFuncArgStruct() bool {
- return t.kind == TSTRUCT && t.Extra.(*Struct).Funarg != FunargNone
+ return t.kind == TSTRUCT && t.extra.(*Struct).Funarg != FunargNone
}
// Methods returns a pointer to the base methods (excluding embedding) for type t.
// Fields returns the fields of struct type t.
func (t *Type) Fields() *Fields {
t.wantEtype(TSTRUCT)
- return &t.Extra.(*Struct).fields
+ return &t.extra.(*Struct).fields
}
// Field returns the i'th field of struct type t.
// It includes the receiver, parameters, and results.
func (t *Type) ArgWidth() int64 {
t.wantEtype(TFUNC)
- return t.Extra.(*Func).Argwid
+ return t.extra.(*Func).Argwid
}
func (t *Type) Size() int64 {
return CMPeq
case TSSA:
- tname := t.Extra.(string)
- xname := x.Extra.(string)
+ tname := t.extra.(string)
+ xname := x.extra.(string)
// desire fast sorting, not pretty sorting.
if len(tname) == len(xname) {
if tname == xname {
return CMPlt
case TTUPLE:
- xtup := x.Extra.(*Tuple)
- ttup := t.Extra.(*Tuple)
+ xtup := x.extra.(*Tuple)
+ ttup := t.extra.(*Tuple)
if c := ttup.first.Compare(xtup.first); c != CMPeq {
return c
}
return ttup.second.Compare(xtup.second)
case TRESULTS:
- xResults := x.Extra.(*Results)
- tResults := t.Extra.(*Results)
+ xResults := x.extra.(*Results)
+ tResults := t.extra.(*Results)
xl, tl := len(xResults.Types), len(tResults.Types)
if tl != xl {
if tl < xl {
func (t *Type) NumFields() int {
if t.kind == TRESULTS {
- return len(t.Extra.(*Results).Types)
+ return len(t.extra.(*Results).Types)
}
return t.Fields().Len()
}
if t.kind == TTUPLE {
switch i {
case 0:
- return t.Extra.(*Tuple).first
+ return t.extra.(*Tuple).first
case 1:
- return t.Extra.(*Tuple).second
+ return t.extra.(*Tuple).second
default:
panic("bad tuple index")
}
}
if t.kind == TRESULTS {
- return t.Extra.(*Results).Types[i]
+ return t.extra.(*Results).Types[i]
}
return t.Field(i).Type
}
func (t *Type) NumElem() int64 {
t.wantEtype(TARRAY)
- return t.Extra.(*Array).Bound
+ return t.extra.(*Array).Bound
}
type componentsIncludeBlankFields bool
// The direction will be one of Crecv, Csend, or Cboth.
func (t *Type) ChanDir() ChanDir {
t.wantEtype(TCHAN)
- return t.Extra.(*Chan).Dir
+ return t.extra.(*Chan).Dir
}
func (t *Type) IsMemory() bool {
- if t == TypeMem || t.kind == TTUPLE && t.Extra.(*Tuple).second == TypeMem {
+ if t == TypeMem || t.kind == TTUPLE && t.extra.(*Tuple).second == TypeMem {
return true
}
if t.kind == TRESULTS {
- if types := t.Extra.(*Results).Types; len(types) > 0 && types[len(types)-1] == TypeMem {
+ if types := t.extra.(*Results).Types; len(types) > 0 && types[len(types)-1] == TypeMem {
return true
}
}
return !t.Elem().NotInHeap()
case TTUPLE:
- ttup := t.Extra.(*Tuple)
+ ttup := t.extra.(*Tuple)
return ttup.first.HasPointers() || ttup.second.HasPointers()
case TRESULTS:
- types := t.Extra.(*Results).Types
+ types := t.extra.(*Results).Types
for _, et := range types {
if et.HasPointers() {
return true
// TODO(mdempsky): Fix Type rekinding.
t.kind = underlying.kind
- t.Extra = underlying.Extra
+ t.extra = underlying.extra
t.Width = underlying.Width
t.Align = underlying.Align
t.underlying = underlying.underlying
if anyBroke(methods) {
t.SetBroke(true)
}
- t.Extra.(*Interface).pkg = pkg
+ t.extra.(*Interface).pkg = pkg
return t
}
func NewTypeParam(sym *Sym, index int) *Type {
t := New(TTYPEPARAM)
t.sym = sym
- t.Extra.(*Typeparam).index = index
+ t.extra.(*Typeparam).index = index
t.SetHasTParam(true)
return t
}
// Index returns the index of the type param within its param list.
func (t *Type) Index() int {
t.wantEtype(TTYPEPARAM)
- return t.Extra.(*Typeparam).index
+ return t.extra.(*Typeparam).index
}
// SetIndex sets the index of the type param within its param list.
func (t *Type) SetIndex(i int) {
t.wantEtype(TTYPEPARAM)
- t.Extra.(*Typeparam).index = i
+ t.extra.(*Typeparam).index = i
}
// SetBound sets the bound of a typeparam.
func (t *Type) SetBound(bound *Type) {
t.wantEtype(TTYPEPARAM)
- t.Extra.(*Typeparam).bound = bound
+ t.extra.(*Typeparam).bound = bound
}
// Bound returns the bound of a typeparam.
func (t *Type) Bound() *Type {
t.wantEtype(TTYPEPARAM)
- return t.Extra.(*Typeparam).bound
+ return t.extra.(*Typeparam).bound
}
// NewUnion returns a new union with the specified set of terms (types). If
if len(terms) != len(tildes) {
base.Fatalf("Mismatched terms and tildes for NewUnion")
}
- t.Extra.(*Union).terms = terms
- t.Extra.(*Union).tildes = tildes
+ t.extra.(*Union).terms = terms
+ t.extra.(*Union).tildes = tildes
nt := len(terms)
for i := 0; i < nt; i++ {
if terms[i].HasTParam() {
// NumTerms returns the number of terms in a union type.
func (t *Type) NumTerms() int {
t.wantEtype(TUNION)
- return len(t.Extra.(*Union).terms)
+ return len(t.extra.(*Union).terms)
}
// Term returns ith term of a union type as (term, tilde). If tilde is true, term
// represents ~T, rather than just T.
func (t *Type) Term(i int) (*Type, bool) {
t.wantEtype(TUNION)
- u := t.Extra.(*Union)
+ u := t.extra.(*Union)
return u.terms[i], u.tildes[i]
}
if anyBroke(fields) {
t.SetBroke(true)
}
- t.Extra.(*Struct).pkg = pkg
+ t.extra.(*Struct).pkg = pkg
if fieldsHasTParam(fields) {
t.SetHasTParam(true)
}