}
}
-// A CallUse records how the result of the call is used:
-type CallUse byte
-
-const (
- _ CallUse = iota
-
- CallUseExpr // single expression result is used
- CallUseList // list of results are used
- CallUseStmt // results not used - call is a statement
-)
-
// A CallExpr is a function call X(Args).
type CallExpr struct {
miniExpr
Args Nodes
KeepAlive []*Name // vars to be kept alive until call returns
IsDDD bool
- Use CallUse
NoInline bool
}
func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool) ir.Node {
n := ir.NewCallExpr(pos, ir.OCALL, fun, args)
n.IsDDD = dots
- // n.Use will be changed to ir.CallUseStmt in g.stmt() if this call is
- // just a statement (any return values are ignored).
- n.Use = ir.CallUseExpr
if fun.Op() == ir.OTYPE {
// Actually a type conversion, not a function call.
case *syntax.BlockStmt:
return ir.NewBlockStmt(g.pos(stmt), g.blockStmt(stmt))
case *syntax.ExprStmt:
- x := g.expr(stmt.X)
- if call, ok := x.(*ir.CallExpr); ok {
- call.Use = ir.CallUseStmt
- }
- return x
+ return g.expr(stmt.X)
case *syntax.SendStmt:
n := ir.NewSendStmt(g.pos(stmt), g.expr(stmt.Chan), g.expr(stmt.Value))
if n.Chan.Type().HasTParam() || n.Value.Type().HasTParam() {
stmt := stmt.(*ir.AssignListStmt)
stmt.SetOp(ir.OAS2FUNC)
r := rhs[0].(*ir.CallExpr)
- r.Use = ir.CallUseList
rtyp := r.Type()
mismatched := false
// tcCall typechecks an OCALL node.
func tcCall(n *ir.CallExpr, top int) ir.Node {
- n.Use = ir.CallUseExpr
- if top == ctxStmt {
- n.Use = ir.CallUseStmt
- }
Stmts(n.Init()) // imported rewritten f(g()) calls (#30907)
n.X = typecheck(n.X, ctxExpr|ctxType|ctxCallee)
if n.X.Diag() {
w.bool(n.IsDDD)
if go117ExportTypes {
w.exoticType(n.Type())
- w.uint64(uint64(n.Use))
}
case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
n.IsDDD = r.bool()
if go117ExportTypes {
n.SetType(r.exoticType())
- n.Use = ir.CallUse(r.uint64())
}
return n
stmt := stmt.(*ir.AssignListStmt)
stmt.SetOp(ir.OAS2FUNC)
r := rhs[0].(*ir.CallExpr)
- r.Use = ir.CallUseList
rtyp := r.Type()
mismatched := false