Exemplo n.º 1
0
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)
	}
}
Exemplo n.º 2
0
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
}
Exemplo n.º 3
0
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
}