miniExpr
X Node
Sel *types.Sym
- Offset int64
Selection *types.Field
}
func NewSelectorExpr(pos src.XPos, op Op, x Node, sel *types.Sym) *SelectorExpr {
n := &SelectorExpr{X: x, Sel: sel}
n.pos = pos
- n.Offset = types.BADWIDTH
n.SetOp(op)
return n
}
func (n *SelectorExpr) Sym() *types.Sym { return n.Sel }
func (n *SelectorExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 }
func (n *SelectorExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) }
+func (n *SelectorExpr) Offset() int64 { return n.Selection.Offset }
// Before type-checking, bytes.Buffer is a SelectorExpr.
// After type-checking it becomes a Name.
case ir.ODOTPTR:
n := n.(*ir.SelectorExpr)
p := s.exprPtr(n.X, n.Bounded(), n.Pos())
- p = s.newValue1I(ssa.OpOffPtr, types.NewPtr(n.Type()), n.Offset, p)
+ p = s.newValue1I(ssa.OpOffPtr, types.NewPtr(n.Type()), n.Offset(), p)
return s.load(n.Type(), p)
case ir.OINDEX:
i := s.expr(fn.X)
itab := s.newValue1(ssa.OpITab, types.Types[types.TUINTPTR], i)
s.nilCheck(itab)
- itabidx := fn.Offset + 2*int64(types.PtrSize) + 8 // offset of fun field in runtime.itab
+ itabidx := fn.Offset() + 2*int64(types.PtrSize) + 8 // offset of fun field in runtime.itab
closure := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.UintptrPtr, itabidx, itab)
rcvr := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, i)
return closure, rcvr
case ir.ODOT:
n := n.(*ir.SelectorExpr)
p := s.addr(n.X)
- return s.newValue1I(ssa.OpOffPtr, t, n.Offset, p)
+ return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p)
case ir.ODOTPTR:
n := n.(*ir.SelectorExpr)
p := s.exprPtr(n.X, n.Bounded(), n.Pos())
- return s.newValue1I(ssa.OpOffPtr, t, n.Offset, p)
+ return s.newValue1I(ssa.OpOffPtr, t, n.Offset(), p)
case ir.OCLOSUREREAD:
n := n.(*ir.ClosureReadExpr)
return s.newValue1I(ssa.OpOffPtr, t, n.Offset,
// fieldIdx finds the index of the field referred to by the ODOT node n.
func fieldIdx(n *ir.SelectorExpr) int {
t := n.X.Type()
- f := n.Sel
if !t.IsStruct() {
panic("ODOT's LHS is not a struct")
}
- var i int
- for _, t1 := range t.Fields().Slice() {
- if t1.Sym != f {
- i++
- continue
- }
- if t1.Offset != n.Offset {
- panic("field offset doesn't match")
+ for i, f := range t.Fields().Slice() {
+ if f.Sym == n.Sel {
+ if f.Offset != n.Offset() {
+ panic("field offset doesn't match")
+ }
+ return i
}
- return i
}
panic(fmt.Sprintf("can't find field in expr %v\n", n))
case ir.ODOT, ir.ODOTPTR:
break
}
- if n.Sel == nil {
- // No field name. This DOTPTR was built by the compiler for access
- // to runtime data structures. Ignore.
- return
- }
- t := n.X.Type()
- if t.IsPtr() {
- t = t.Elem()
- }
field := n.Selection
if field == nil {
base.Fatalf("usefield %v %v without paramfld", n.X.Type(), n.Sel)
}
- if field.Sym != n.Sel || field.Offset != n.Offset {
- base.Fatalf("field inconsistency: %v,%v != %v,%v", field.Sym, field.Offset, n.Sel, n.Offset)
+ if field.Sym != n.Sel {
+ base.Fatalf("field inconsistency: %v != %v", field.Sym, n.Sel)
}
if !strings.Contains(field.Note, "go:\"track\"") {
return