call := Nod(OCALL, Nod(OXDOT, ptr, meth), nil)
call.List.Set(callargs)
call.Isddd = ddd
- if t0.Outtuple == 0 {
+ if t0.Results().NumFields() == 0 {
body = append(body, call)
} else {
n := Nod(OAS2, nil, nil)
Fatalf("funcargs2 %v", t)
}
- if t.Thistuple != 0 {
- for _, ft := range t.Recvs().Fields().Slice() {
- if ft.Nname == nil || ft.Nname.Sym == nil {
- continue
- }
- n := ft.Nname // no need for newname(ft->nname->sym)
- n.Type = ft.Type
- declare(n, PPARAM)
+ for _, ft := range t.Recvs().Fields().Slice() {
+ if ft.Nname == nil || ft.Nname.Sym == nil {
+ continue
}
+ n := ft.Nname // no need for newname(ft->nname->sym)
+ n.Type = ft.Type
+ declare(n, PPARAM)
}
- if t.Intuple != 0 {
- for _, ft := range t.Params().Fields().Slice() {
- if ft.Nname == nil || ft.Nname.Sym == nil {
- continue
- }
- n := ft.Nname
- n.Type = ft.Type
- declare(n, PPARAM)
+ for _, ft := range t.Params().Fields().Slice() {
+ if ft.Nname == nil || ft.Nname.Sym == nil {
+ continue
}
+ n := ft.Nname
+ n.Type = ft.Type
+ declare(n, PPARAM)
}
- if t.Outtuple != 0 {
- for _, ft := range t.Results().Fields().Slice() {
- if ft.Nname == nil || ft.Nname.Sym == nil {
- continue
- }
- n := ft.Nname
- n.Type = ft.Type
- declare(n, PPARAMOUT)
+ for _, ft := range t.Results().Fields().Slice() {
+ if ft.Nname == nil || ft.Nname.Sym == nil {
+ continue
}
+ n := ft.Nname
+ n.Type = ft.Type
+ declare(n, PPARAMOUT)
}
}
t.Broke = true
}
- if this != nil {
- t.Thistuple = 1
- }
- t.Outtuple = len(out)
- t.Intuple = len(in)
t.Outnamed = false
- if t.Outtuple > 0 && out[0].Left != nil && out[0].Left.Orig != nil {
+ if len(out) > 0 && out[0].Left != nil && out[0].Left.Orig != nil {
s := out[0].Left.Orig.Sym
if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
t.Outnamed = true
case ORETURN:
ll := n.List
- if n.List.Len() == 1 && Curfn.Type.Outtuple > 1 {
+ if n.List.Len() == 1 && Curfn.Type.Results().NumFields() > 1 {
// OAS2FUNC in disguise
// esccall already done on n->list->n
// tie n->list->n->escretval to curfn->dcl PPARAMOUT's
}
// nodes for method calls.
- if n.Type == nil || n.Type.Thistuple > 0 {
+ if n.Type == nil || n.Type.Recv() != nil {
break
}
fallthrough
if flag&FmtShort != 0 {
// no leading func
} else {
- if t.Thistuple != 0 {
+ if t.Recv() != nil {
buf.WriteString("method")
buf.WriteString(Tconv(t.Recvs(), 0))
buf.WriteString(" ")
}
buf.WriteString(Tconv(t.Params(), 0))
- switch t.Outtuple {
+ switch t.Results().NumFields() {
case 0:
break
// Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
// the ->sym can be re-used in the local package, so peel it off the receiver's type.
func fnpkg(fn *Node) *Pkg {
- if fn.Type.Thistuple != 0 {
+ if fn.Type.Recv() != nil {
// method
rcvr := fn.Type.Recv().Type
}
// assign receiver.
- if fn.Type.Thistuple != 0 && n.Left.Op == ODOTMETH {
+ if fn.Type.Recv() != nil && n.Left.Op == ODOTMETH {
// method call with a receiver.
t := fn.Type.Recv()
if n.List.Len() == 1 {
switch n.List.First().Op {
case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH:
- if n.List.First().Left.Type.Outtuple > 1 {
- multiret = n.List.First().Left.Type.Outtuple - 1
+ if n.List.First().Left.Type.Results().NumFields() > 1 {
+ multiret = n.List.First().Left.Type.Results().NumFields() - 1
}
}
}
if variadic {
varargcount = n.List.Len() + multiret
if n.Left.Op != ODOTMETH {
- varargcount -= fn.Type.Thistuple
+ varargcount -= fn.Type.Recvs().NumFields()
}
- varargcount -= fn.Type.Intuple - 1
+ varargcount -= fn.Type.Params().NumFields() - 1
}
// assign arguments to the parameters' temp names
li := 0
// TODO: if len(nlist) == 1 but multiple args, check that n->list->n is a call?
- if fn.Type.Thistuple != 0 && n.Left.Op != ODOTMETH {
+ if fn.Type.Recv() != nil && n.Left.Op != ODOTMETH {
// non-method call to method
if n.List.Len() == 0 {
Fatalf("non-method call to method without first arg: %v", Nconv(n, FmtSign))
}
// call must return multiple values
- return n.Left.Type.Outtuple > 1
+ return n.Left.Type.Results().NumFields() > 1
}
// Copyret emits t1, t2, ... = n, where n is a function call,
// and then returns the list t1, t2, ....
func copyret(n *Node, order *Order) []*Node {
if n.Type.Etype != TSTRUCT || !n.Type.Funarg {
- Fatalf("copyret %v %d", n.Type, n.Left.Type.Outtuple)
+ Fatalf("copyret %v %d", n.Type, n.Left.Type.Results().NumFields())
}
var l1 []*Node
nptr := int(Curfn.Type.Argwid / int64(Widthptr))
bv := bvalloc(int32(nptr) * 2)
nbitmap := 1
- if Curfn.Type.Outtuple > 0 {
+ if Curfn.Type.Results().NumFields() > 0 {
nbitmap = 2
}
off := duint32(sym, 0, uint32(nbitmap))
off = duint32(sym, off, uint32(bv.n))
var xoffset int64
- if Curfn.Type.Thistuple > 0 {
+ if Curfn.Type.Recv() != nil {
xoffset = 0
onebitwalktype1(Curfn.Type.Recvs(), &xoffset, bv)
}
- if Curfn.Type.Intuple > 0 {
+ if Curfn.Type.Params().NumFields() > 0 {
xoffset = 0
onebitwalktype1(Curfn.Type.Params(), &xoffset, bv)
}
for j := 0; int32(j) < bv.n; j += 32 {
off = duint32(sym, off, bv.b[j/32])
}
- if Curfn.Type.Outtuple > 0 {
+ if Curfn.Type.Results().NumFields() > 0 {
xoffset = 0
onebitwalktype1(Curfn.Type.Results(), &xoffset, bv)
for j := 0; int32(j) < bv.n; j += 32 {
lineno = Curfn.Func.Endlineno
}
- if Curfn.Type.Outtuple != 0 {
+ if Curfn.Type.Results().NumFields() != 0 {
Ginscall(throwreturn, 0)
}
// generating code if necessary.
var ms []*Sig
for _, f := range mt.AllMethods().Slice() {
- if f.Type.Etype != TFUNC || f.Type.Thistuple == 0 {
+ if f.Type.Etype != TFUNC || f.Type.Recv() == nil {
Fatalf("non-method on %v method %v %v\n", mt, f.Sym, f)
}
if f.Type.Recv() == nil {
}
ot = dcommontype(s, ot, t)
- inCount := t.Thistuple + t.Intuple
- outCount := t.Outtuple
+ inCount := t.Recvs().NumFields() + t.Params().NumFields()
+ outCount := t.Results().NumFields()
if isddd {
outCount |= 1 << 15
}
ot += 4 // align for *rtype
}
- dataAdd := (inCount + t.Outtuple) * Widthptr
+ dataAdd := (inCount + t.Results().NumFields()) * Widthptr
ot = dextratype(s, ot, t, dataAdd)
// Array of rtype pointers follows funcType.
{Name{}, 52, 80},
{Node{}, 92, 144},
{Sym{}, 60, 112},
- {Type{}, 132, 224},
+ {Type{}, 116, 184},
}
for _, tt := range tests {
c := 0
if u.Etype == TSTRUCT || u.Etype == TINTER {
for _, f := range u.Fields().Slice() {
- if f.Sym == s || (ignorecase && f.Type.Etype == TFUNC && f.Type.Thistuple > 0 && strings.EqualFold(f.Sym.Name, s.Name)) {
+ if f.Sym == s || (ignorecase && f.Type.Etype == TFUNC && f.Type.Recv() != nil && strings.EqualFold(f.Sym.Name, s.Name)) {
if save != nil {
*save = f
}
}
// dotpath may have dug out arbitrary fields, we only want methods.
- if f.Type.Etype != TFUNC || f.Type.Thistuple == 0 {
+ if f.Type.Etype != TFUNC || f.Type.Recv() == nil {
continue
}
call := Nod(OCALL, dot, nil)
call.List.Set(args)
call.Isddd = isddd
- if method.Type.Outtuple > 0 {
+ if method.Type.Results().NumFields() > 0 {
n := Nod(ORETURN, nil, nil)
n.List.Set1(call)
call = n
}
}
- if m.Type.Etype != TFUNC || m.Type.Thistuple == 0 {
+ if m.Type.Etype != TFUNC || m.Type.Recv() == nil {
Yyerror("%v.%v is a field, not a method", t, s)
return nil
}
Broke bool // broken type definition.
Align uint8
Haspointers uint8 // 0 unknown, 1 no, 2 yes
+ Outnamed bool // on TFUNC
- Nod *Node // canonical OTYPE node
- Orig *Type // original type (type literal or predefined type)
- Lineno int32
-
- // TFUNC
- Thistuple int
- Outtuple int
- Intuple int
- Outnamed bool
+ Nod *Node // canonical OTYPE node
+ Orig *Type // original type (type literal or predefined type)
methods Fields
allMethods Fields
Sym *Sym
Vargen int32 // unique name for OTYPE/ONAME
+ Lineno int32
Nname *Node
Argwid int64
return
}
- if n.Type.Etype != TFUNC || n.Type.Thistuple != 1 {
+ if n.Type.Etype != TFUNC || n.Type.Recv() == nil {
Yyerror("type %v has no method %v", n.Left.Type, Sconv(n.Right.Sym, FmtShort))
n.Type = nil
n.Type = nil
typecheckaste(OCALL, n.Left, n.Isddd, t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
ok |= Etop
- if t.Outtuple == 0 {
+ if t.Results().NumFields() == 0 {
break OpSwitch
}
ok |= Erv
- if t.Outtuple == 1 {
+ if t.Results().NumFields() == 1 {
n.Type = l.Type.Results().Field(0).Type
if n.Op == OCALLFUNC && n.Left.Op == ONAME && (compiling_runtime != 0 || n.Left.Sym.Pkg == Runtimepkg) && n.Left.Sym.Name == "getg" {
}
t := n.List.First().Left.Type
- if t.Outtuple != 2 {
- Yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.First(), t.Outtuple)
+ if t.Results().NumFields() != 2 {
+ Yyerror("invalid operation: complex expects two arguments, %v returns %d results", n.List.First(), t.Results().NumFields())
n.Type = nil
return
}
}
func checkreturn(fn *Node) {
- if fn.Type.Outtuple != 0 && len(fn.Nbody.Slice()) != 0 {
+ if fn.Type.Results().NumFields() != 0 && len(fn.Nbody.Slice()) != 0 {
markbreaklist(fn.Nbody, nil)
if !fn.Nbody.isterminating() {
yyerrorl(fn.Func.Endlineno, "missing return at end of function")
*f.RecvsP() = rcvr
*f.ResultsP() = out
*f.ParamsP() = in
- f.Thistuple = 1
- f.Intuple = 0
- f.Outnamed = false
- f.Outtuple = 1
t := typ(TINTER)
field = newField()
// Update type of OCALLFUNC node.
// Output arguments had not changed, but their offsets could.
- if n.Left.Type.Outtuple == 1 {
+ if n.Left.Type.Results().NumFields() == 1 {
n.Type = n.Left.Type.Results().Field(0).Type
} else {
n.Type = n.Left.Type.Results()
Fatalf("mkcall %v %v", fn, fn.Type)
}
- n := fn.Type.Intuple
+ n := fn.Type.Params().NumFields()
r := Nod(OCALL, fn, nil)
r.List.Set(va[:n])
- if fn.Type.Outtuple > 0 {
+ if fn.Type.Results().NumFields() > 0 {
typecheck(&r, Erv|Efnstruct)
} else {
typecheck(&r, Etop)