params := p.paramList()
result := p.paramList()
- sig := functype(nil, params, result)
+ sig := functypefield(nil, params, result)
importsym(sym, ONAME)
if sym.Def != nil && sym.Def.Op == ONAME {
// function was imported before (via another import)
result := p.paramList()
nointerface := p.bool()
- n := methodname(newname(sym), recv[0].Right)
- n.Type = functype(recv[0], params, result)
+ base := recv[0].Type
+ star := false
+ if base.IsPtr() {
+ base = base.Elem()
+ star = true
+ }
+
+ n := methodname0(sym, star, base.Sym)
+ n.Type = functypefield(recv[0], params, result)
checkwidth(n.Type)
addmethod(sym, n.Type, false, nointerface)
p.funcList = append(p.funcList, n)
case structTag:
t = p.newtyp(TSTRUCT)
- tostruct0(t, p.fieldList())
+ t.SetFields(p.fieldList())
+ checkwidth(t)
case pointerTag:
t = p.newtyp(Tptr)
t = p.newtyp(TFUNC)
params := p.paramList()
result := p.paramList()
- functype0(t, nil, params, result)
+ functypefield0(t, nil, params, result)
case interfaceTag:
t = p.newtyp(TINTER)
if p.int() != 0 {
formatErrorf("unexpected embedded interface")
}
- tointerface0(t, p.methodList())
+ t.SetFields(p.methodList())
+ checkwidth(t)
case mapTag:
t = p.newtyp(TMAP)
}
// parser.go:hidden_structdcl_list
-func (p *importer) fieldList() (fields []*Node) {
+func (p *importer) fieldList() (fields []*Field) {
if n := p.int(); n > 0 {
- fields = make([]*Node, n)
+ fields = make([]*Field, n)
for i := range fields {
fields[i] = p.field()
}
}
// parser.go:hidden_structdcl
-func (p *importer) field() *Node {
+func (p *importer) field() *Field {
p.pos()
sym := p.fieldName()
typ := p.typ()
note := p.string()
- var n *Node
- if sym.Name != "" {
- n = nod(ODCLFIELD, newname(sym), typenod(typ))
- } else {
+ f := newField()
+ if sym.Name == "" {
// anonymous field - typ must be T or *T and T must be a type name
s := typ.Sym
if s == nil && typ.IsPtr() {
s = typ.Elem().Sym // deref
}
- pkg := importpkg
- if sym != nil {
- pkg = sym.Pkg
- }
- n = embedded(s, pkg)
- n.Right = typenod(typ)
+ sym = sym.Pkg.Lookup(s.Name)
+ f.Embedded = 1
}
- n.SetVal(Val{U: note})
- return n
+ f.Sym = sym
+ f.Nname = newname(sym)
+ f.Type = typ
+ f.Note = note
+
+ return f
}
// parser.go:hidden_interfacedcl_list
-func (p *importer) methodList() (methods []*Node) {
+func (p *importer) methodList() (methods []*Field) {
if n := p.int(); n > 0 {
- methods = make([]*Node, n)
+ methods = make([]*Field, n)
for i := range methods {
methods[i] = p.method()
}
}
// parser.go:hidden_interfacedcl
-func (p *importer) method() *Node {
+func (p *importer) method() *Field {
p.pos()
sym := p.fieldName()
params := p.paramList()
result := p.paramList()
- return nod(ODCLFIELD, newname(sym), typenod(functype(fakethis(), params, result)))
+
+ f := newField()
+ f.Sym = sym
+ f.Nname = newname(sym)
+ f.Type = functypefield(fakethisfield(), params, result)
+ return f
}
// parser.go:sym,hidden_importsym
}
// parser.go:ohidden_funarg_list
-func (p *importer) paramList() []*Node {
+func (p *importer) paramList() []*Field {
i := p.int()
if i == 0 {
return nil
named = false
}
// i > 0
- n := make([]*Node, i)
- for i := range n {
- n[i] = p.param(named)
+ fs := make([]*Field, i)
+ for i := range fs {
+ fs[i] = p.param(named)
}
- return n
+ return fs
}
// parser.go:hidden_funarg
-func (p *importer) param(named bool) *Node {
- typ := p.typ()
-
- isddd := false
- if typ.Etype == TDDDFIELD {
+func (p *importer) param(named bool) *Field {
+ f := newField()
+ f.Type = p.typ()
+ if f.Type.Etype == TDDDFIELD {
// TDDDFIELD indicates wrapped ... slice type
- typ = typSlice(typ.DDDField())
- isddd = true
+ f.Type = typSlice(f.Type.DDDField())
+ f.Isddd = true
}
- n := nod(ODCLFIELD, nil, typenod(typ))
- n.Isddd = isddd
-
if named {
name := p.string()
if name == "" {
if name != "_" {
pkg = p.pkg()
}
- n.Left = newname(pkg.Lookup(name))
+ f.Sym = pkg.Lookup(name)
+ f.Nname = newname(f.Sym)
}
// TODO(gri) This is compiler-specific (escape info).
// Move into compiler-specific section eventually?
- n.SetVal(Val{U: p.string()})
+ f.Note = p.string()
- return n
+ return f
}
func (p *importer) value(typ *Type) (x Val) {
return t
}
+func tofunargsfield(fields []*Field, funarg Funarg) *Type {
+ t := typ(TSTRUCT)
+ t.StructType().Funarg = funarg
+
+ for _, f := range fields {
+ f.Funarg = funarg
+
+ // esc.go needs to find f given a PPARAM to add the tag.
+ if f.Nname != nil && f.Nname.Class == PPARAM {
+ f.Nname.Name.Param.Field = f
+ }
+ }
+ t.SetFields(fields)
+ return t
+}
+
func interfacefield(n *Node) *Field {
lno := lineno
lineno = n.Lineno
return n
}
+func fakethisfield() *Field {
+ f := newField()
+ f.Type = ptrto(typ(TSTRUCT))
+ return f
+}
+
// Is this field a method on an interface?
// Those methods have an anonymous *struct{} as the receiver.
// (See fakethis above.)
}
}
+func functypefield(this *Field, in, out []*Field) *Type {
+ t := typ(TFUNC)
+ functypefield0(t, this, in, out)
+ return t
+}
+
+func functypefield0(t *Type, this *Field, in, out []*Field) {
+ var rcvr []*Field
+ if this != nil {
+ rcvr = []*Field{this}
+ }
+ t.FuncType().Receiver = tofunargsfield(rcvr, FunargRcvr)
+ t.FuncType().Results = tofunargsfield(out, FunargRcvr)
+ t.FuncType().Params = tofunargsfield(in, FunargRcvr)
+
+ t.FuncType().Outnamed = false
+ if len(out) > 0 && out[0].Nname != nil && out[0].Nname.Orig != nil {
+ s := out[0].Nname.Orig.Sym
+ if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
+ t.FuncType().Outnamed = true
+ }
+ }
+}
+
var methodsym_toppkg *Pkg
func methodsym(nsym *Sym, t0 *Type, iface int) *Sym {
}
func methodname(n *Node, t *Node) *Node {
- star := ""
+ star := false
if t.Op == OIND {
- star = "*"
+ star = true
t = t.Left
}
- if t.Sym == nil || isblank(n) {
- return newfuncname(n.Sym)
+ return methodname0(n.Sym, star, t.Sym)
+}
+
+func methodname0(s *Sym, star bool, tsym *Sym) *Node {
+ if tsym == nil || isblanksym(s) {
+ return newfuncname(s)
}
var p string
- if star != "" {
- p = fmt.Sprintf("(%s%v).%v", star, t.Sym, n.Sym)
+ if star {
+ p = fmt.Sprintf("(*%v).%v", tsym, s)
} else {
- p = fmt.Sprintf("%v.%v", t.Sym, n.Sym)
+ p = fmt.Sprintf("%v.%v", tsym, s)
}
- if exportname(t.Sym.Name) {
- n = newfuncname(lookup(p))
+ if exportname(tsym.Name) {
+ s = lookup(p)
} else {
- n = newfuncname(Pkglookup(p, t.Sym.Pkg))
+ s = Pkglookup(p, tsym.Pkg)
}
- return n
+ return newfuncname(s)
}
// Add a method, declared as a function.
}
}
- n := nod(ODCLFIELD, newname(msym), nil)
- n.Type = t
-
for _, f := range mt.Methods().Slice() {
if msym.Name != f.Sym.Name {
continue
return
}
- f := structfield(n)
+ f := newField()
+ f.Sym = msym
+ f.Nname = newname(msym)
+ f.Type = t
f.Nointerface = nointerface
mt.Methods().Append(f)