import (
"bytes"
"cmd/compile/internal/base"
- "cmd/compile/internal/ir"
"cmd/compile/internal/types"
"fmt"
"sort"
)
+// MaxWidth is the maximum size of a value on the target architecture.
+var MaxWidth int64
+
// sizeCalculationDisabled indicates whether it is safe
// to calculate Types' widths and alignments. See dowidth.
var sizeCalculationDisabled bool
sort.Sort(methcmp(methods))
- if int64(len(methods)) >= thearch.MAXWIDTH/int64(Widthptr) {
+ if int64(len(methods)) >= MaxWidth/int64(Widthptr) {
base.ErrorfAt(typePos(t), "interface too large")
}
for i, m := range methods {
o = Rnd(o, int64(f.Type.Align))
}
f.Offset = o
- if n := ir.AsNode(f.Nname); n != nil {
- n := n.Name()
+ if f.Nname != nil {
// addrescapes has similar code to update these offsets.
// Usually addrescapes runs after widstruct,
// in which case we could drop this,
// NOTE(rsc): This comment may be stale.
// It's possible the ordering has changed and this is
// now the common case. I'm not sure.
- if n.Name().Stackcopy != nil {
- n.Name().Stackcopy.SetFrameOffset(o)
- n.SetFrameOffset(0)
- } else {
- n.SetFrameOffset(o)
- }
+ f.Nname.(types.VarObject).RecordFrameOffset(o)
}
w := f.Type.Width
lastzero = o
}
o += w
- maxwidth := thearch.MAXWIDTH
+ maxwidth := MaxWidth
// On 32-bit systems, reflect tables impose an additional constraint
// that each field start offset must fit in 31 bits.
if maxwidth < 1<<32 {
}
*path = append(*path, t)
- if findTypeLoop(t.Obj().(*ir.Name).Ntype.Type(), path) {
+ if findTypeLoop(t.Obj().(types.TypeObject).TypeDefn(), path) {
return true
}
*path = (*path)[:len(*path)-1]
dowidth(t.Elem())
if t.Elem().Width != 0 {
- cap := (uint64(thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
+ cap := (uint64(MaxWidth) - 1) / uint64(t.Elem().Width)
if uint64(t.NumElem()) > cap {
base.ErrorfAt(typePos(t), "type %L larger than address space", t)
}
resumecheckwidth()
}
+// CalcStructSize calculates the size of s,
+// filling in s.Width and s.Align,
+// even if size calculation is otherwise disabled.
+func CalcStructSize(s *types.Type) {
+ s.Width = widstruct(s, s, 0, 1) // sets align
+}
+
// when a type's width should be known, we call checkwidth
// to compute it. during a declaration like
//
// Callers must use n.CloneName to make clear they intend to create a separate name.
func (n *Name) CloneName() *Name { c := *n; return &c }
+// TypeDefn returns the type definition for a named OTYPE.
+// That is, given "type T Defn", it returns Defn.
+// It is used by package types.
+func (n *Name) TypeDefn() *types.Type {
+ return n.Ntype.Type()
+}
+
+// RecordFrameOffset records the frame offset for the name.
+// It is used by package types when laying out function arguments.
+func (n *Name) RecordFrameOffset(offset int64) {
+ if n.Stackcopy != nil {
+ n.Stackcopy.SetFrameOffset(offset)
+ n.SetFrameOffset(0)
+ } else {
+ n.SetFrameOffset(offset)
+ }
+}
+
// NewNameAt returns a new ONAME Node associated with symbol s at position pos.
// The caller is responsible for setting Curfn.
func NewNameAt(pos src.XPos, sym *types.Sym) *Name {
Type() *Type
}
+// A TypeObject is an Object representing a named type.
+type TypeObject interface {
+ Object
+ TypeDefn() *Type // for "type T Defn", returns Defn
+}
+
+// A VarObject is an Object representing a function argument, variable, or struct field.
+type VarObject interface {
+ Object
+ RecordFrameOffset(int64) // save frame offset
+}
+
//go:generate stringer -type EType -trimprefix T
// EType describes a kind of type.