call := n.(*ir.CallExpr)
inst := call.X.(*ir.InstExpr)
st := g.getInstantiationForNode(inst)
- // Replace the OFUNCINST with a direct reference to the
- // new stenciled function
- call.X = st.Nname
if inst.X.Op() == ir.OCALLPART {
- // When we create an instantiation of a method
- // call, we make it a function. So, move the
- // receiver to be the first arg of the function
- // call.
- withRecv := make([]ir.Node, len(call.Args)+1)
- dot := inst.X.(*ir.SelectorExpr)
- withRecv[0] = dot.X
- copy(withRecv[1:], call.Args)
- call.Args = withRecv
+ // Replace the OFUNCINST with the selector
+ // expression, and update the selector expression
+ // to refer to the new stenciled function.
+ call.X = inst.X
+ se := call.X.(*ir.SelectorExpr)
+ se.Selection = types.NewField(se.Pos(), se.Sel, st.Type())
+ se.Selection.Nname = st.Nname
+ se.SetOp(ir.ODOTMETH)
+ se.SetType(st.Type())
+ } else {
+ // Replace the OFUNCINST with a direct reference to the
+ // new stenciled function
+ call.X = st.Nname
}
// Transform the Call now, which changes OCALL
// to OCALLFUNC and does typecheckaste/assignconvfn.
baseSym := typ.Sym().Pkg.Lookup(genericTypeName(typ.Sym()))
baseType := baseSym.Def.(*ir.Name).Type()
for j, m := range typ.Methods().Slice() {
- name := m.Nname.(*ir.Name)
targs := make([]ir.Node, len(typ.RParams()))
for k, targ := range typ.RParams() {
targs[k] = ir.TypeNode(targ)
}
baseNname := baseType.Methods().Slice()[j].Nname.(*ir.Name)
- name.Func = g.getInstantiation(baseNname, targs, true)
+ f := g.getInstantiation(baseNname, targs, true)
+ m.Nname = f.Nname
}
}
g.instTypeList = nil
newf.Dcl[i] = subst.node(n).(*ir.Name)
}
- // Ugly: we have to insert the Name nodes of the parameters/results into
+ // Replace the types in the function signature.
+ // Ugly: also, we have to insert the Name nodes of the parameters/results into
// the function type. The current function type has no Nname fields set,
// because it came via conversion from the types2 type.
oldt := nameNode.Type()
- // We also transform a generic method type to the corresponding
- // instantiated function type where the receiver is the first parameter.
- newt := types.NewSignature(oldt.Pkg(), nil, nil,
- subst.fields(ir.PPARAM, append(oldt.Recvs().FieldSlice(), oldt.Params().FieldSlice()...), newf.Dcl),
- subst.fields(ir.PPARAMOUT, oldt.Results().FieldSlice(), newf.Dcl))
+ dcl := newf.Dcl
+ var newrecv *types.Field
+ if oldt.Recv() != nil {
+ newrecv = subst.fields(ir.PPARAM, oldt.Recvs().FieldSlice(), dcl)[0]
+ if newrecv.Nname != nil {
+ // If we found the receiver in the dcl list, then skip it
+ // when we scan for the remaining params below.
+ assert(newrecv.Nname == dcl[0])
+ dcl = dcl[1:]
+ }
+ }
+ newt := types.NewSignature(oldt.Pkg(), newrecv, nil,
+ subst.fields(ir.PPARAM, oldt.Params().FieldSlice(), dcl),
+ subst.fields(ir.PPARAMOUT, oldt.Results().FieldSlice(), dcl))
newf.Nname.SetType(newt)
ir.MarkFunc(newf.Nname)