func buildFunc(b *builder, f *tast.Func, irFunc *ir.Func) { b.f = irFunc if f.Receiver != nil { // bind the receiver t := f.Receiver.ObjType.(types.T) ref := newAddressableRef(t, irFunc.ThisRef()) f.Receiver.Obj = &objVar{f.Receiver.Name(), ref} } else if f.This != nil { // bind this pointer b.this = newRef(f.This, irFunc.ThisRef()) } // bind arg symbols args := irFunc.ArgRefs() if f.IsMethod() { args = args[1:] // skip <this> } for i, s := range f.Args { if s != nil { t := s.ObjType.(types.T) ref := newAddressableRef(t, args[i]) s.Obj = &objVar{s.Name(), ref} } } // bind named return symbols rets := irFunc.RetRefs() t := f.Sym.ObjType.(*types.Func) b.fretRef = makeRetRef(t.Rets, rets) if f.NamedRets != nil { for i, s := range f.NamedRets { if s != nil { s.Obj = &objVar{s.Name(), b.fretRef.At(i)} } } } b.b = b.f.NewBlock(nil) for _, stmt := range f.Body { b.buildStmt(stmt) } }
func buildFunc(b *builder, f *pkgFunc) *tast.Func { b.scope.Push() defer scopePopAndCheck(b) t := f.sym.ObjType.(*types.Func) b.retNamed = f.f.NamedRet() b.retType = t.RetTypes ret := new(tast.Func) ret.Sym = f.sym if b.this != nil { if f.f.Recv != nil { if recvTok := f.f.Recv.Recv; recvTok != nil { recvSym := declareVar(b, recvTok, b.thisType, true) if recvSym == nil { return nil } ret.Receiver = recvSym } } else { // marking keyword <this> if it is an inlined method ret.This = b.thisType } } if b.this != nil { ret.Args = declareParas(b, f.f.Args, t.Args[1:]) } else { ret.Args = declareParas(b, f.f.Args, t.Args) } if b.retNamed { ret.NamedRets = declareParas(b, f.f.Rets, t.Rets) } ret.Body = buildStmts(b, f.f.Body.Stmts) if len(b.retType) > 0 && !isBlockTerminal(f.f.Body) { b.Errorf(f.f.Body.Rbrace.Pos, "missing return at the end of function") } // clear for safety b.retType = nil b.retNamed = false return ret }
func buildFunc(b *builder, f *pkgFunc) *tast.Func { b.scope.Push() defer b.scope.Pop() t := f.sym.ObjType.(*types.Func) b.retNamed = f.f.NamedRet() b.retType = t.RetTypes ret := new(tast.Func) ret.Sym = f.sym if b.this != nil { if f.f.Recv != nil { if recvTok := f.f.Recv.Recv; recvTok != nil { recvSym := declareVar(b, recvTok, b.thisType) if recvSym == nil { return nil } ret.Receiver = recvSym } } else { // marking keyword <this> if it is an inlined method ret.This = b.thisType } } if b.this != nil { ret.Args = declareParas(b, f.f.Args, t.Args[1:]) } else { ret.Args = declareParas(b, f.f.Args, t.Args) } if b.retNamed { ret.NamedRets = declareParas(b, f.f.Rets, t.Rets) } ret.Body = buildStmts(b, f.f.Body.Stmts) // clear for safety b.retType = nil b.retNamed = false return ret }