}
f.Offset = o
if n := ir.AsNode(f.Nname); n != nil {
+ n := n.Name()
// addrescapes has similar code to update these offsets.
// Usually addrescapes runs after widstruct,
// in which case we could drop this,
var outer ir.Node
outer = v.Outer
- outermost := v.Defn
+ outermost := v.Defn.(*ir.Name)
// out parameters will be assigned to implicitly upon return.
if outermost.Class() != ir.PPARAMOUT && !outermost.Name().Addrtaken() && !outermost.Name().Assigned() && v.Type().Width <= 128 {
return walkexpr(cfn, init)
}
-func typecheckpartialcall(dot ir.Node, sym *types.Sym) *ir.CallPartExpr {
- switch dot.Op() {
+func typecheckpartialcall(n ir.Node, sym *types.Sym) *ir.CallPartExpr {
+ switch n.Op() {
case ir.ODOTINTER, ir.ODOTMETH:
break
default:
base.Fatalf("invalid typecheckpartialcall")
}
+ dot := n.(*ir.SelectorExpr)
// Create top-level function.
fn := makepartialcall(dot, dot.Type(), sym)
fn.SetWrapper(true)
- return ir.NewCallPartExpr(dot.Pos(), dot.Left(), dot.(*ir.SelectorExpr).Selection, fn)
+ return ir.NewCallPartExpr(dot.Pos(), dot.Left(), dot.Selection, fn)
}
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
// for partial calls.
-func makepartialcall(dot ir.Node, t0 *types.Type, meth *types.Sym) *ir.Func {
+func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir.Func {
rcvrtype := dot.Left().Type()
sym := methodSymSuffix(rcvrtype, meth, "-fm")
// partialCallType returns the struct type used to hold all the information
// needed in the closure for n (n must be a OCALLPART node).
// The address of a variable of the returned type can be cast to a func.
-func partialCallType(n ir.Node) *types.Type {
+func partialCallType(n *ir.CallPartExpr) *types.Type {
t := tostruct([]*ir.Field{
namedfield("F", types.Types[types.TUINTPTR]),
namedfield("R", n.Left().Type()),
if Curfn != nil {
init = append(init, ir.Nod(ir.ODCL, v, nil))
}
- e = ir.Nod(ir.OAS, v, e)
- init = append(init, e)
- if e.Right() != nil {
- v.Defn = e
+ as := ir.Nod(ir.OAS, v, e)
+ init = append(init, as)
+ if e != nil {
+ v.Defn = as
}
}
}
}
// setNodeNameFunc marks a node as a function.
-func setNodeNameFunc(n ir.Node) {
+func setNodeNameFunc(n *ir.Name) {
if n.Op() != ir.ONAME || n.Class() != ir.Pxxx {
base.Fatalf("expected ONAME/Pxxx node, got %v", n)
}
return c
}
-func (c *nowritebarrierrecChecker) findExtraCalls(n ir.Node) {
- if n.Op() != ir.OCALLFUNC {
+func (c *nowritebarrierrecChecker) findExtraCalls(nn ir.Node) {
+ if nn.Op() != ir.OCALLFUNC {
return
}
- fn := n.Left()
- if fn == nil || fn.Op() != ir.ONAME || fn.Class() != ir.PFUNC || fn.Name().Defn == nil {
+ n := nn.(*ir.CallExpr)
+ if n.Left() == nil || n.Left().Op() != ir.ONAME {
+ return
+ }
+ fn := n.Left().(*ir.Name)
+ if fn.Class() != ir.PFUNC || fn.Name().Defn == nil {
return
}
if !isRuntimePkg(fn.Sym().Pkg) || fn.Sym().Name != "systemstack" {
}
}
- v := names[0]
+ v := names[0].(*ir.Name)
if dclcontext != ir.PEXTERN {
numLocalEmbed++
v = ir.NewNameAt(v.Pos(), lookupN("embed.", numLocalEmbed))
}
}
-func importsym(ipkg *types.Pkg, s *types.Sym, op ir.Op) ir.Node {
+func importsym(ipkg *types.Pkg, s *types.Sym, op ir.Op) *ir.Name {
n := ir.AsNode(s.PkgDef())
if n == nil {
// iimport should have created a stub ONONAME
if n.Op() != ir.ONONAME && n.Op() != op {
redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
}
- return n
+ return n.(*ir.Name)
}
// importtype returns the named type declared by symbol s.
n := importsym(ipkg, s, ir.OTYPE)
if n.Op() != ir.OTYPE {
t := types.NewNamed(n)
-
n.SetOp(ir.OTYPE)
n.SetPos(pos)
n.SetType(t)
func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class, t *types.Type) ir.Node {
n := importsym(ipkg, s, op)
if n.Op() != ir.ONONAME {
- if n.Op() == op && (n.Class() != ctxt || !types.Identical(n.Type(), t)) {
+ if n.Op() == op && (op == ir.ONAME && n.Class() != ctxt || !types.Identical(n.Type(), t)) {
redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
}
return nil
// isParamStackCopy reports whether this is the on-stack copy of a
// function parameter that moved to the heap.
func isParamStackCopy(n ir.Node) bool {
- return n.Op() == ir.ONAME && (n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Name().Heapaddr != nil
+ if n.Op() != ir.ONAME {
+ return false
+ }
+ name := n.(*ir.Name)
+ return (name.Class() == ir.PPARAM || name.Class() == ir.PPARAMOUT) && name.Heapaddr != nil
}
// isParamHeapCopy reports whether this is the on-heap copy of
// a function parameter that moved to the heap.
func isParamHeapCopy(n ir.Node) bool {
- return n.Op() == ir.ONAME && n.Class() == ir.PAUTOHEAP && n.Name().Stackcopy != nil
+ if n.Op() != ir.ONAME {
+ return false
+ }
+ name := n.(*ir.Name)
+ return name.Class() == ir.PAUTOHEAP && name.Name().Stackcopy != nil
}
// autotmpname returns the name for an autotmp variable numbered n.
if n.Op() == ir.ONONAME {
continue
}
- if n.Op() != ir.ONAME || n.Class() != ir.PEXTERN {
+ if n.Op() != ir.ONAME || n.(*ir.Name).Class() != ir.PEXTERN {
base.Fatalf("bad inittask: %v", n)
}
- deps = append(deps, n.Sym().Linksym())
+ deps = append(deps, n.(*ir.Name).Sym().Linksym())
}
// Make a function that contains all the initialization statements.
// Record user init functions.
for i := 0; i < renameinitgen; i++ {
s := lookupN("init.", i)
- fn := ir.AsNode(s.Def).Name().Defn
+ fn := ir.AsNode(s.Def).Name().Defn.(*ir.Func)
// Skip init functions with empty bodies.
if fn.Body().Len() == 1 {
- if stmt := fn.Body().First(); stmt.Op() == ir.OBLOCK && stmt.List().Len() == 0 {
+ if stmt := fn.Body().First(); stmt.Op() == ir.OBLOCK && stmt.(*ir.BlockStmt).List().Len() == 0 {
continue
}
}
}
d.seen.Add(n)
if d.transitive && n.Class() == ir.PFUNC {
- d.inspectList(n.Defn.Body())
+ d.inspectList(n.Defn.(*ir.Func).Body())
}
}
timings.Start("fe", "typecheck", "top1")
for i := 0; i < len(xtop); i++ {
n := xtop[i]
- if op := n.Op(); op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.Left().Name().Alias()) {
+ if op := n.Op(); op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.(*ir.Decl).Left().Name().Alias()) {
xtop[i] = typecheck(n, ctxStmt)
}
}
timings.Start("fe", "typecheck", "top2")
for i := 0; i < len(xtop); i++ {
n := xtop[i]
- if op := n.Op(); op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.Left().Name().Alias() {
+ if op := n.Op(); op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.(*ir.Decl).Left().Name().Alias() {
xtop[i] = typecheck(n, ctxStmt)
}
}
return s
}
-func typename(t *types.Type) ir.Node {
+func typename(t *types.Type) *ir.AddrExpr {
s := typenamesym(t)
if s.Def == nil {
n := ir.NewNameAt(src.NoXPos, s)
return n
}
-func itabname(t, itype *types.Type) ir.Node {
+func itabname(t, itype *types.Type) *ir.AddrExpr {
if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() || !itype.IsInterface() || itype.IsEmptyInterface() {
base.Fatalf("itabname(%v, %v)", t, itype)
}
}
case ir.OCALLPART:
fn := ir.AsNode(callpartMethod(n).Nname)
- if fn != nil && fn.Op() == ir.ONAME && fn.Class() == ir.PFUNC && fn.Name().Defn != nil {
- if m := v.visit(fn.Name().Defn.(*ir.Func)); m < min {
- min = m
+ if fn != nil && fn.Op() == ir.ONAME {
+ if fn := fn.(*ir.Name); fn.Class() == ir.PFUNC && fn.Name().Defn != nil {
+ if m := v.visit(fn.Name().Defn.(*ir.Func)); m < min {
+ min = m
+ }
}
}
case ir.OCLOSURE:
left := dot.Left() // skip final .M
// TODO(mdempsky): Remove dependency on dotlist.
if !dotlist[0].field.Type.IsPtr() {
- left = ir.Nod(ir.OADDR, left, nil)
+ left = nodAddr(left)
}
as := ir.Nod(ir.OAS, nthis, convnop(left, rcvr))
fn.PtrBody().Append(as)
// For *T, return &T{...}.
n.SetRight(ir.TypeNode(t.Elem()))
- addr := ir.NodAt(n.Pos(), ir.OADDR, n, nil)
+ addr := nodAddrAt(n.Pos(), n)
addr.SetImplicit(true)
return addr
}
for _, s := range &builtinFuncs {
s2 := types.BuiltinPkg.Lookup(s.name)
- s2.Def = NewName(s2)
- ir.AsNode(s2.Def).SetSubOp(s.op)
+ def := NewName(s2)
+ def.SetSubOp(s.op)
+ s2.Def = def
}
for _, s := range &unsafeFuncs {
s2 := unsafepkg.Lookup(s.name)
- s2.Def = NewName(s2)
- ir.AsNode(s2.Def).SetSubOp(s.op)
+ def := NewName(s2)
+ def.SetSubOp(s.op)
+ s2.Def = def
}
s = types.BuiltinPkg.Lookup("true")
- s.Def = nodbool(true)
- ir.AsNode(s.Def).SetSym(lookup("true"))
+ b := nodbool(true)
+ b.(*ir.Name).SetSym(lookup("true"))
+ s.Def = b
s = types.BuiltinPkg.Lookup("false")
- s.Def = nodbool(false)
- ir.AsNode(s.Def).SetSym(lookup("false"))
+ b = nodbool(false)
+ b.(*ir.Name).SetSym(lookup("false"))
+ s.Def = b
s = lookup("_")
types.BlankSym = s
types.Types[types.TNIL] = types.New(types.TNIL)
s = types.BuiltinPkg.Lookup("nil")
- s.Def = nodnil()
- ir.AsNode(s.Def).SetSym(s)
+ nnil := nodnil()
+ nnil.(*ir.NilExpr).SetSym(s)
+ s.Def = nnil
s = types.BuiltinPkg.Lookup("iota")
s.Def = ir.NewIota(base.Pos, s)
base.Errorf("invalid expression %v", n)
return 0
}
+ sel := n.Left().(*ir.SelectorExpr)
// Remember base of selector to find it back after dot insertion.
// Since r->left may be mutated by typechecking, check it explicitly
// first to track it correctly.
- n.Left().SetLeft(typecheck(n.Left().Left(), ctxExpr))
- sbase := n.Left().Left()
+ sel.SetLeft(typecheck(sel.Left(), ctxExpr))
+ sbase := sel.Left()
- n.SetLeft(typecheck(n.Left(), ctxExpr))
- if n.Left().Type() == nil {
+ tsel := typecheck(sel, ctxExpr)
+ n.SetLeft(tsel)
+ if tsel.Type() == nil {
return 0
}
- switch n.Left().Op() {
+ switch tsel.Op() {
case ir.ODOT, ir.ODOTPTR:
break
case ir.OCALLPART:
// Sum offsets for dots until we reach sbase.
var v int64
- for r := n.Left(); r != sbase; r = r.Left() {
+ var next ir.Node
+ for r := tsel; r != sbase; r = next {
switch r.Op() {
case ir.ODOTPTR:
// For Offsetof(s.f), s may itself be a pointer,
fallthrough
case ir.ODOT:
v += r.Offset()
+ next = r.Left()
default:
- ir.Dump("unsafenmagic", n.Left())
+ ir.Dump("unsafenmagic", tsel)
base.Fatalf("impossible %v node after dot insertion", r.Op())
}
}