Source file src/cmd/compile/internal/noder/func.go

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package noder
     6  
     7  import (
     8  	"cmd/compile/internal/base"
     9  	"cmd/compile/internal/ir"
    10  	"cmd/compile/internal/syntax"
    11  	"cmd/compile/internal/typecheck"
    12  	"cmd/compile/internal/types"
    13  	"cmd/internal/src"
    14  )
    15  
    16  func (g *irgen) funcBody(fn *ir.Func, recv *syntax.Field, sig *syntax.FuncType, block *syntax.BlockStmt) {
    17  	typecheck.Func(fn)
    18  
    19  	// TODO(mdempsky): Remove uses of ir.CurFunc and
    20  	// typecheck.DeclContext after we stop relying on typecheck
    21  	// for desugaring.
    22  	outerfn, outerctxt := ir.CurFunc, typecheck.DeclContext
    23  	ir.CurFunc = fn
    24  
    25  	typ := fn.Type()
    26  	if param := typ.Recv(); param != nil {
    27  		g.defParam(param, recv, ir.PPARAM)
    28  	}
    29  	for i, param := range typ.Params().FieldSlice() {
    30  		g.defParam(param, sig.ParamList[i], ir.PPARAM)
    31  	}
    32  	for i, result := range typ.Results().FieldSlice() {
    33  		g.defParam(result, sig.ResultList[i], ir.PPARAMOUT)
    34  	}
    35  
    36  	// We may have type-checked a call to this function already and
    37  	// calculated its size, including parameter offsets. Now that we've
    38  	// created the parameter Names, force a recalculation to ensure
    39  	// their offsets are correct.
    40  	types.RecalcSize(typ)
    41  
    42  	if block != nil {
    43  		typecheck.DeclContext = ir.PAUTO
    44  
    45  		fn.Body = g.stmts(block.List)
    46  		if fn.Body == nil {
    47  			fn.Body = []ir.Node{ir.NewBlockStmt(src.NoXPos, nil)}
    48  		}
    49  		fn.Endlineno = g.makeXPos(block.Rbrace)
    50  
    51  		if base.Flag.Dwarf {
    52  			g.recordScopes(fn, sig)
    53  		}
    54  	}
    55  
    56  	ir.CurFunc, typecheck.DeclContext = outerfn, outerctxt
    57  }
    58  
    59  func (g *irgen) defParam(param *types.Field, decl *syntax.Field, class ir.Class) {
    60  	typecheck.DeclContext = class
    61  
    62  	var name *ir.Name
    63  	if decl.Name != nil {
    64  		name, _ = g.def(decl.Name)
    65  	} else if class == ir.PPARAMOUT {
    66  		name = g.obj(g.info.Implicits[decl])
    67  	}
    68  
    69  	if name != nil {
    70  		param.Nname = name
    71  		param.Sym = name.Sym() // in case it was renamed
    72  	}
    73  }
    74  

View as plain text