types.Markdcl()
- if fn.Nname != nil && fn.Nname.Ntype != nil {
+ if fn.Nname.Ntype != nil {
funcargs(fn.Nname.Ntype.(*ir.FuncType))
} else {
funcargs2(fn.Type())
}
}
-func structfield(n *ir.Field) *types.Field {
- lno := base.Pos
- base.Pos = n.Pos
-
- if n.Ntype != nil {
- n.Ntype = typecheckNtype(n.Ntype)
- n.Type = n.Ntype.Type()
- n.Ntype = nil
- }
-
- f := types.NewField(n.Pos, n.Sym, n.Type)
- if n.Embedded {
- checkembeddedtype(n.Type)
- f.Embedded = 1
- }
- f.Note = n.Note
-
- base.Pos = lno
- return f
-}
-
// checkdupfields emits errors for duplicately named fields or methods in
// a list of struct or interface types.
func checkdupfields(what string, fss ...[]*types.Field) {
// convert a parsed id/type list into
// a type for struct/interface/arglist
func tostruct(l []*ir.Field) *types.Type {
- t := types.New(types.TSTRUCT)
+ lno := base.Pos
fields := make([]*types.Field, len(l))
for i, n := range l {
- f := structfield(n)
- if f.Broke() {
- t.SetBroke(true)
- }
- fields[i] = f
- }
- t.SetFields(fields)
-
- checkdupfields("field", t.FieldSlice())
-
- if !t.Broke() {
- checkwidth(t)
- }
+ base.Pos = n.Pos
- return t
-}
-
-func tofunargs(l []*ir.Field, funarg types.Funarg) *types.Type {
- t := types.New(types.TSTRUCT)
- t.StructType().Funarg = funarg
-
- fields := make([]*types.Field, len(l))
- for i, n := range l {
- f := structfield(n)
- f.SetIsDDD(n.IsDDD)
- if n.Decl != nil {
- n.Decl.SetType(f.Type)
- f.Nname = n.Decl
+ if n.Ntype != nil {
+ n.Type = typecheckNtype(n.Ntype).Type()
+ n.Ntype = nil
}
- if f.Broke() {
- t.SetBroke(true)
+ f := types.NewField(n.Pos, n.Sym, n.Type)
+ if n.Embedded {
+ checkembeddedtype(n.Type)
+ f.Embedded = 1
}
+ f.Note = n.Note
fields[i] = f
}
- t.SetFields(fields)
- return t
-}
+ checkdupfields("field", fields)
-func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
- t := types.New(types.TSTRUCT)
- t.StructType().Funarg = funarg
- t.SetFields(fields)
- return t
+ base.Pos = lno
+ return types.NewStruct(fields)
}
-func interfacefield(n *ir.Field) *types.Field {
- lno := base.Pos
- base.Pos = n.Pos
-
- if n.Note != "" {
- base.Errorf("interface method cannot have annotation")
+func tointerface(nmethods []*ir.Field) *types.Type {
+ if len(nmethods) == 0 {
+ return types.Types[types.TINTER]
}
- // MethodSpec = MethodName Signature | InterfaceTypeName .
- //
- // If Sym != nil, then Sym is MethodName and Left is Signature.
- // Otherwise, Left is InterfaceTypeName.
+ lno := base.Pos
- if n.Ntype != nil {
- n.Ntype = typecheckNtype(n.Ntype)
- n.Type = n.Ntype.Type()
- n.Ntype = nil
+ methods := make([]*types.Field, len(nmethods))
+ for i, n := range nmethods {
+ base.Pos = n.Pos
+ if n.Ntype != nil {
+ n.Type = typecheckNtype(n.Ntype).Type()
+ n.Ntype = nil
+ }
+ methods[i] = types.NewField(n.Pos, n.Sym, n.Type)
}
- f := types.NewField(n.Pos, n.Sym, n.Type)
-
base.Pos = lno
- return f
-}
-
-func tointerface(l []*ir.Field) *types.Type {
- if len(l) == 0 {
- return types.Types[types.TINTER]
- }
- t := types.New(types.TINTER)
- var fields []*types.Field
- for _, n := range l {
- f := interfacefield(n)
- if f.Broke() {
- t.SetBroke(true)
- }
- fields = append(fields, f)
- }
- t.SetInterface(fields)
- return t
+ return types.NewInterface(methods)
}
func fakeRecv() *ir.Field {
}
// turn a parsed function declaration into a type
-func functype(this *ir.Field, in, out []*ir.Field) *types.Type {
- t := types.New(types.TFUNC)
-
- var rcvr []*ir.Field
- if this != nil {
- rcvr = []*ir.Field{this}
- }
- t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
- t.FuncType().Params = tofunargs(in, types.FunargParams)
- t.FuncType().Results = tofunargs(out, types.FunargResults)
+func functype(nrecv *ir.Field, nparams, nresults []*ir.Field) *types.Type {
+ funarg := func(n *ir.Field) *types.Field {
+ lno := base.Pos
+ base.Pos = n.Pos
+
+ if n.Ntype != nil {
+ n.Type = typecheckNtype(n.Ntype).Type()
+ n.Ntype = nil
+ }
- checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
+ f := types.NewField(n.Pos, n.Sym, n.Type)
+ f.SetIsDDD(n.IsDDD)
+ if n.Decl != nil {
+ n.Decl.SetType(f.Type)
+ f.Nname = n.Decl
+ }
- if t.Recvs().Broke() || t.Results().Broke() || t.Params().Broke() {
- t.SetBroke(true)
+ base.Pos = lno
+ return f
+ }
+ funargs := func(nn []*ir.Field) []*types.Field {
+ res := make([]*types.Field, len(nn))
+ for i, n := range nn {
+ res[i] = funarg(n)
+ }
+ return res
}
- t.FuncType().Outnamed = t.NumResults() > 0 && ir.OrigSym(t.Results().Field(0).Sym) != nil
+ var recv *types.Field
+ if nrecv != nil {
+ recv = funarg(nrecv)
+ }
+ t := types.NewSignature(recv, funargs(nparams), funargs(nresults))
+ checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
return t
}
-func functypefield(this *types.Field, in, out []*types.Field) *types.Type {
- t := types.New(types.TFUNC)
-
- var rcvr []*types.Field
- if this != nil {
- rcvr = []*types.Field{this}
- }
- t.FuncType().Receiver = tofunargsfield(rcvr, types.FunargRcvr)
- t.FuncType().Params = tofunargsfield(in, types.FunargParams)
- t.FuncType().Results = tofunargsfield(out, types.FunargResults)
-
- t.FuncType().Outnamed = t.NumResults() > 0 && ir.OrigSym(t.Results().Field(0).Sym) != nil
-
- return t
+func hasNamedResults(fn *ir.Func) bool {
+ typ := fn.Type()
+ return typ.NumResults() > 0 && ir.OrigSym(typ.Results().Field(0).Sym) != nil
}
// methodSym returns the method symbol representing a method name
field = append(field, overflow)
// link up fields
- bucket := types.New(types.TSTRUCT)
+ bucket := types.NewStruct(field[:])
bucket.SetNoalg(true)
- bucket.SetFields(field[:])
dowidth(bucket)
// Check invariants that map code depends on.
makefield("extra", types.Types[types.TUNSAFEPTR]),
}
- hmap := types.New(types.TSTRUCT)
+ hmap := types.NewStruct(fields)
hmap.SetNoalg(true)
- hmap.SetFields(fields)
dowidth(hmap)
// The size of hmap should be 48 bytes on 64 bit
}
// build iterator struct holding the above fields
- hiter := types.New(types.TSTRUCT)
+ hiter := types.NewStruct(fields)
hiter.SetNoalg(true)
- hiter.SetFields(fields)
dowidth(hiter)
if hiter.Width != int64(12*Widthptr) {
base.Fatalf("hash_iter size not correct %d %d", hiter.Width, 12*Widthptr)
}
// build struct holding the above fields
- s := types.New(types.TSTRUCT)
+ s := types.NewStruct(fields)
s.SetNoalg(true)
- s.SetFields(fields)
s.Width = widstruct(s, s, 0, 1)
s.Align = uint8(Widthptr)
return s
// It gets calculated via a temporary TFUNCARGS type.
// Note that TFUNC's Width is Widthptr.
Argwid int64
-
- Outnamed bool
}
// FuncType returns t's extra func-specific fields.
t.nod = obj
return t
}
+
+// NewInterface returns a new interface for the given methods and
+// embedded types. Embedded types are specified as fields with no Sym.
+func NewInterface(methods []*Field) *Type {
+ t := New(TINTER)
+ t.SetInterface(methods)
+ if anyBroke(methods) {
+ t.SetBroke(true)
+ }
+ return t
+}
+
+// NewSignature returns a new function type for the given receiver,
+// parameters, and results, any of which may be nil.
+func NewSignature(recv *Field, params, results []*Field) *Type {
+ var recvs []*Field
+ if recv != nil {
+ recvs = []*Field{recv}
+ }
+
+ t := New(TFUNC)
+ ft := t.FuncType()
+
+ funargs := func(fields []*Field, funarg Funarg) *Type {
+ s := NewStruct(fields)
+ s.StructType().Funarg = funarg
+ if s.Broke() {
+ t.SetBroke(true)
+ }
+ return s
+ }
+
+ ft.Receiver = funargs(recvs, FunargRcvr)
+ ft.Params = funargs(params, FunargParams)
+ ft.Results = funargs(results, FunargResults)
+
+ return t
+}
+
+// NewStruct returns a new struct with the given fields.
+func NewStruct(fields []*Field) *Type {
+ t := New(TSTRUCT)
+ t.SetFields(fields)
+ if anyBroke(fields) {
+ t.SetBroke(true)
+ }
+ return t
+}
+
+func anyBroke(fields []*Field) bool {
+ for _, f := range fields {
+ if f.Broke() {
+ return true
+ }
+ }
+ return false
+}