lineno = autogeneratedPos // less confusing than end of input
dclcontext = PEXTERN
- types.Markdcl()
// func sym(p *T, h uintptr) uintptr
tfn := nod(OTFUNC, nil, nil)
- n := namedfield("p", types.NewPtr(t))
- tfn.List.Append(n)
- np := n.Left
- n = namedfield("h", types.Types[TUINTPTR])
- tfn.List.Append(n)
- nh := n.Left
- n = anonfield(types.Types[TUINTPTR]) // return value
- tfn.Rlist.Append(n)
+ tfn.List.Set2(
+ namedfield("p", types.NewPtr(t)),
+ namedfield("h", types.Types[TUINTPTR]),
+ )
+ tfn.Rlist.Set1(anonfield(types.Types[TUINTPTR]))
fn := dclfunc(sym, tfn)
+ np := asNode(tfn.Type.Params().Field(0).Nname)
+ nh := asNode(tfn.Type.Params().Field(1).Nname)
// genhash is only called for types that have equality but
// cannot be handled by the standard algorithms,
}
funcbody()
- Curfn = fn
+
fn.Func.SetDupok(true)
fn = typecheck(fn, Etop)
+
+ Curfn = fn
typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil
- types.Popdcl()
+
if debug_dclstack != 0 {
testdclstack()
}
lineno = autogeneratedPos // less confusing than end of input
dclcontext = PEXTERN
- types.Markdcl()
// func sym(p, q *T) bool
tfn := nod(OTFUNC, nil, nil)
- n := namedfield("p", types.NewPtr(t))
- tfn.List.Append(n)
- np := n.Left
- n = namedfield("q", types.NewPtr(t))
- tfn.List.Append(n)
- nq := n.Left
- n = anonfield(types.Types[TBOOL])
- tfn.Rlist.Append(n)
+ tfn.List.Set2(
+ namedfield("p", types.NewPtr(t)),
+ namedfield("q", types.NewPtr(t)),
+ )
+ tfn.Rlist.Set1(anonfield(types.Types[TBOOL]))
fn := dclfunc(sym, tfn)
+ np := asNode(tfn.Type.Params().Field(0).Nname)
+ nq := asNode(tfn.Type.Params().Field(1).Nname)
// geneq is only called for types that have equality but
// cannot be handled by the standard algorithms,
}
funcbody()
- Curfn = fn
+
fn.Func.SetDupok(true)
fn = typecheck(fn, Etop)
+
+ Curfn = fn
typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil
- types.Popdcl()
+
if debug_dclstack != 0 {
testdclstack()
}
}
xfunc.Func.Nname.Sym = closurename(Curfn)
- xfunc.Func.Nname.Sym.SetOnExportList(true) // disable export
+ disableExport(xfunc.Func.Nname.Sym)
declare(xfunc.Func.Nname, PFUNC)
xfunc = typecheck(xfunc, Etop)
savecurfn := Curfn
Curfn = nil
- xtype := nod(OTFUNC, nil, nil)
- var l []*Node
- var callargs []*Node
- ddd := false
- xfunc := nod(ODCLFUNC, nil, nil)
- Curfn = xfunc
- for i, t := range t0.Params().Fields().Slice() {
- n := newname(lookupN("a", i))
- n.SetClass(PPARAM)
- xfunc.Func.Dcl = append(xfunc.Func.Dcl, n)
- callargs = append(callargs, n)
- fld := nod(ODCLFIELD, n, typenod(t.Type))
- if t.Isddd() {
- fld.SetIsddd(true)
- ddd = true
- }
-
- l = append(l, fld)
- }
-
- xtype.List.Set(l)
- l = nil
- var retargs []*Node
- for i, t := range t0.Results().Fields().Slice() {
- n := newname(lookupN("r", i))
- n.SetClass(PPARAMOUT)
- xfunc.Func.Dcl = append(xfunc.Func.Dcl, n)
- retargs = append(retargs, n)
- l = append(l, nod(ODCLFIELD, n, typenod(t.Type)))
- }
-
- xtype.Rlist.Set(l)
+ tfn := nod(OTFUNC, nil, nil)
+ tfn.List.Set(structargs(t0.Params(), true))
+ tfn.Rlist.Set(structargs(t0.Results(), false))
+ disableExport(sym)
+ xfunc := dclfunc(sym, tfn)
xfunc.Func.SetDupok(true)
- xfunc.Func.Nname = newfuncname(sym)
- xfunc.Func.Nname.Sym.SetOnExportList(true) // disable export
- xfunc.Func.Nname.Name.Param.Ntype = xtype
- xfunc.Func.Nname.Name.Defn = xfunc
- declare(xfunc.Func.Nname, PFUNC)
+ xfunc.Func.SetNeedctxt(true)
// Declare and initialize variable holding receiver.
- xfunc.Func.SetNeedctxt(true)
-
cv := nod(OCLOSUREVAR, nil, nil)
cv.Type = rcvrtype
cv.Xoffset = Rnd(int64(Widthptr), int64(cv.Type.Align))
- ptr := newname(lookup("rcvr"))
- ptr.SetClass(PAUTO)
+ ptr := newname(lookup(".this"))
+ declare(ptr, PAUTO)
ptr.Name.SetUsed(true)
- ptr.Name.Curfn = xfunc
- xfunc.Func.Dcl = append(xfunc.Func.Dcl, ptr)
var body []*Node
if rcvrtype.IsPtr() || rcvrtype.IsInterface() {
ptr.Type = rcvrtype
}
call := nod(OCALL, nodSym(OXDOT, ptr, meth), nil)
- call.List.Set(callargs)
- call.SetIsddd(ddd)
- if t0.NumResults() == 0 {
- body = append(body, call)
- } else {
- n := nod(OAS2, nil, nil)
- n.List.Set(retargs)
- n.Rlist.Set1(call)
- body = append(body, n)
- n = nod(ORETURN, nil, nil)
- body = append(body, n)
+ call.List.Set(paramNnames(tfn.Type))
+ call.SetIsddd(tfn.Type.IsVariadic())
+ if t0.NumResults() != 0 {
+ n := nod(ORETURN, nil, nil)
+ n.List.Set1(call)
+ call = n
}
+ body = append(body, call)
xfunc.Nbody.Set(body)
+ funcbody()
xfunc = typecheck(xfunc, Etop)
sym.Def = asTypesNode(xfunc)
}
}
+// disableExport prevents sym from being included in package export
+// data. To be effectual, it must be called before declare.
+func disableExport(sym *types.Sym) {
+ sym.SetOnExportList(true)
+}
+
func dclfunc(sym *types.Sym, tfn *Node) *Node {
if tfn.Op != OTFUNC {
Fatalf("expected OTFUNC node, got %v", tfn)
}
lineno = autogeneratedPos
-
dclcontext = PEXTERN
- types.Markdcl()
-
- this := namedfield(".this", rcvr)
- this.Left.Name.Param.Ntype = this.Right
- in := structargs(method.Type.Params(), true)
- out := structargs(method.Type.Results(), false)
- t := nod(OTFUNC, nil, nil)
- t.List.Set(append([]*Node{this}, in...))
- t.Rlist.Set(out)
+ tfn := nod(OTFUNC, nil, nil)
+ tfn.Left = namedfield(".this", rcvr)
+ tfn.List.Set(structargs(method.Type.Params(), true))
+ tfn.Rlist.Set(structargs(method.Type.Results(), false))
- newnam.SetOnExportList(true) // prevent export; see closure.go
- fn := dclfunc(newnam, t)
+ disableExport(newnam)
+ fn := dclfunc(newnam, tfn)
fn.Func.SetDupok(true)
- // arg list
- var args []*Node
-
- isddd := false
- for _, n := range in {
- args = append(args, n.Left)
- isddd = n.Left.Isddd()
- }
+ nthis := asNode(tfn.Type.Recv().Nname)
methodrcvr := method.Type.Recv().Type
if rcvr.IsPtr() && rcvr.Elem() == methodrcvr {
// generating wrapper from *T to T.
n := nod(OIF, nil, nil)
- n.Left = nod(OEQ, this.Left, nodnil())
+ n.Left = nod(OEQ, nthis, nodnil())
call := nod(OCALL, syslook("panicwrap"), nil)
n.Nbody.Set1(call)
fn.Nbody.Append(n)
}
- dot := adddot(nodSym(OXDOT, this.Left, method.Sym))
+ dot := adddot(nodSym(OXDOT, nthis, method.Sym))
// generate call
// It's not possible to use a tail call when dynamic linking on ppc64le. The
if !dotlist[0].field.Type.IsPtr() {
dot = nod(OADDR, dot, nil)
}
- as := nod(OAS, this.Left, nod(OCONVNOP, dot, nil))
+ as := nod(OAS, nthis, nod(OCONVNOP, dot, nil))
as.Right.Type = rcvr
fn.Nbody.Append(as)
fn.Nbody.Append(nodSym(ORETJMP, nil, methodSym(methodrcvr, method.Sym)))
} else {
fn.Func.SetWrapper(true) // ignore frame for panic+recover matching
call := nod(OCALL, dot, nil)
- call.List.Set(args)
- call.SetIsddd(isddd)
+ call.List.Set(paramNnames(tfn.Type))
+ call.SetIsddd(tfn.Type.IsVariadic())
if method.Type.NumResults() > 0 {
n := nod(ORETURN, nil, nil)
n.List.Set1(call)
call = n
}
-
fn.Nbody.Append(call)
}
}
funcbody()
- Curfn = fn
- types.Popdcl()
if debug_dclstack != 0 {
testdclstack()
}
- // wrappers where T is anonymous (struct or interface) can be duplicated.
- if rcvr.IsStruct() || rcvr.IsInterface() || rcvr.IsPtr() && rcvr.Elem().IsStruct() {
- fn.Func.SetDupok(true)
- }
fn = typecheck(fn, Etop)
+
+ Curfn = fn
typecheckslice(fn.Nbody.Slice(), Etop)
inlcalls(fn)
funccompile(fn)
}
+func paramNnames(ft *types.Type) []*Node {
+ args := make([]*Node, ft.NumParams())
+ for i, f := range ft.Params().FieldSlice() {
+ args[i] = asNode(f.Nname)
+ }
+ return args
+}
+
func hashmem(t *types.Type) *Node {
sym := Runtimepkg.Lookup("memhash")
}
t := nod(OTFUNC, nil, nil)
- var args []*Node
for i, arg := range n.List.Slice() {
- buf := fmt.Sprintf("a%d", i)
- a := namedfield(buf, arg.Type)
- t.List.Append(a)
- args = append(args, a.Left)
+ s := lookupN("a", i)
+ t.List.Append(symfield(s, arg.Type))
}
wrapCall_prgen++
fn := dclfunc(sym, t)
a := nod(n.Op, nil, nil)
- a.List.Set(args)
+ a.List.Set(paramNnames(t.Type))
a = typecheck(a, Etop)
fn.Nbody.Set1(a)
func (t *Type) NumParams() int { return t.FuncType().Params.NumFields() }
func (t *Type) NumResults() int { return t.FuncType().Results.NumFields() }
+// IsVariadic reports whether function type t is variadic.
+func (t *Type) IsVariadic() bool {
+ n := t.NumParams()
+ return n > 0 && t.Params().Field(n-1).Isddd()
+}
+
// Recv returns the receiver of function type t, if any.
func (t *Type) Recv() *Field {
s := t.Recvs()