github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/ssa/func.go (about)

     1  // Copyright 2013 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 ssa
     6  
     7  // This file implements the Function type.
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"go/ast"
    13  	"go/token"
    14  	"go/types"
    15  	"io"
    16  	"os"
    17  	"strings"
    18  
    19  	"github.com/powerman/golang-tools/internal/typeparams"
    20  )
    21  
    22  // Like ObjectOf, but panics instead of returning nil.
    23  // Only valid during f's create and build phases.
    24  func (f *Function) objectOf(id *ast.Ident) types.Object {
    25  	if o := f.info.ObjectOf(id); o != nil {
    26  		return o
    27  	}
    28  	panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s",
    29  		id.Name, f.Prog.Fset.Position(id.Pos())))
    30  }
    31  
    32  // Like TypeOf, but panics instead of returning nil.
    33  // Only valid during f's create and build phases.
    34  func (f *Function) typeOf(e ast.Expr) types.Type {
    35  	if T := f.info.TypeOf(e); T != nil {
    36  		return T
    37  	}
    38  	panic(fmt.Sprintf("no type for %T @ %s", e, f.Prog.Fset.Position(e.Pos())))
    39  }
    40  
    41  // instanceArgs returns the Instance[id].TypeArgs within the context of fn.
    42  func (fn *Function) instanceArgs(id *ast.Ident) []types.Type {
    43  	targList := typeparams.GetInstances(fn.info)[id].TypeArgs
    44  	if targList == nil {
    45  		return nil
    46  	}
    47  
    48  	targs := make([]types.Type, targList.Len())
    49  	for i, n := 0, targList.Len(); i < n; i++ {
    50  		targs[i] = targList.At(i)
    51  	}
    52  	return targs
    53  }
    54  
    55  // Destinations associated with unlabelled for/switch/select stmts.
    56  // We push/pop one of these as we enter/leave each construct and for
    57  // each BranchStmt we scan for the innermost target of the right type.
    58  //
    59  type targets struct {
    60  	tail         *targets // rest of stack
    61  	_break       *BasicBlock
    62  	_continue    *BasicBlock
    63  	_fallthrough *BasicBlock
    64  }
    65  
    66  // Destinations associated with a labelled block.
    67  // We populate these as labels are encountered in forward gotos or
    68  // labelled statements.
    69  //
    70  type lblock struct {
    71  	_goto     *BasicBlock
    72  	_break    *BasicBlock
    73  	_continue *BasicBlock
    74  }
    75  
    76  // labelledBlock returns the branch target associated with the
    77  // specified label, creating it if needed.
    78  //
    79  func (f *Function) labelledBlock(label *ast.Ident) *lblock {
    80  	lb := f.lblocks[label.Obj]
    81  	if lb == nil {
    82  		lb = &lblock{_goto: f.newBasicBlock(label.Name)}
    83  		if f.lblocks == nil {
    84  			f.lblocks = make(map[*ast.Object]*lblock)
    85  		}
    86  		f.lblocks[label.Obj] = lb
    87  	}
    88  	return lb
    89  }
    90  
    91  // addParam adds a (non-escaping) parameter to f.Params of the
    92  // specified name, type and source position.
    93  //
    94  func (f *Function) addParam(name string, typ types.Type, pos token.Pos) *Parameter {
    95  	v := &Parameter{
    96  		name:   name,
    97  		typ:    typ,
    98  		pos:    pos,
    99  		parent: f,
   100  	}
   101  	f.Params = append(f.Params, v)
   102  	return v
   103  }
   104  
   105  func (f *Function) addParamObj(obj types.Object) *Parameter {
   106  	name := obj.Name()
   107  	if name == "" {
   108  		name = fmt.Sprintf("arg%d", len(f.Params))
   109  	}
   110  	param := f.addParam(name, obj.Type(), obj.Pos())
   111  	param.object = obj
   112  	return param
   113  }
   114  
   115  // addSpilledParam declares a parameter that is pre-spilled to the
   116  // stack; the function body will load/store the spilled location.
   117  // Subsequent lifting will eliminate spills where possible.
   118  //
   119  func (f *Function) addSpilledParam(obj types.Object) {
   120  	param := f.addParamObj(obj)
   121  	spill := &Alloc{Comment: obj.Name()}
   122  	spill.setType(types.NewPointer(obj.Type()))
   123  	spill.setPos(obj.Pos())
   124  	f.objects[obj] = spill
   125  	f.Locals = append(f.Locals, spill)
   126  	f.emit(spill)
   127  	f.emit(&Store{Addr: spill, Val: param})
   128  }
   129  
   130  // startBody initializes the function prior to generating SSA code for its body.
   131  // Precondition: f.Type() already set.
   132  //
   133  func (f *Function) startBody() {
   134  	f.currentBlock = f.newBasicBlock("entry")
   135  	f.objects = make(map[types.Object]Value) // needed for some synthetics, e.g. init
   136  }
   137  
   138  // createSyntacticParams populates f.Params and generates code (spills
   139  // and named result locals) for all the parameters declared in the
   140  // syntax.  In addition it populates the f.objects mapping.
   141  //
   142  // Preconditions:
   143  // f.startBody() was called. f.info != nil.
   144  // Postcondition:
   145  // len(f.Params) == len(f.Signature.Params) + (f.Signature.Recv() ? 1 : 0)
   146  //
   147  func (f *Function) createSyntacticParams(recv *ast.FieldList, functype *ast.FuncType) {
   148  	// Receiver (at most one inner iteration).
   149  	if recv != nil {
   150  		for _, field := range recv.List {
   151  			for _, n := range field.Names {
   152  				f.addSpilledParam(f.info.Defs[n])
   153  			}
   154  			// Anonymous receiver?  No need to spill.
   155  			if field.Names == nil {
   156  				f.addParamObj(f.Signature.Recv())
   157  			}
   158  		}
   159  	}
   160  
   161  	// Parameters.
   162  	if functype.Params != nil {
   163  		n := len(f.Params) // 1 if has recv, 0 otherwise
   164  		for _, field := range functype.Params.List {
   165  			for _, n := range field.Names {
   166  				f.addSpilledParam(f.info.Defs[n])
   167  			}
   168  			// Anonymous parameter?  No need to spill.
   169  			if field.Names == nil {
   170  				f.addParamObj(f.Signature.Params().At(len(f.Params) - n))
   171  			}
   172  		}
   173  	}
   174  
   175  	// Named results.
   176  	if functype.Results != nil {
   177  		for _, field := range functype.Results.List {
   178  			// Implicit "var" decl of locals for named results.
   179  			for _, n := range field.Names {
   180  				f.namedResults = append(f.namedResults, f.addLocalForIdent(n))
   181  			}
   182  		}
   183  	}
   184  }
   185  
   186  type setNumable interface {
   187  	setNum(int)
   188  }
   189  
   190  // numberRegisters assigns numbers to all SSA registers
   191  // (value-defining Instructions) in f, to aid debugging.
   192  // (Non-Instruction Values are named at construction.)
   193  //
   194  func numberRegisters(f *Function) {
   195  	v := 0
   196  	for _, b := range f.Blocks {
   197  		for _, instr := range b.Instrs {
   198  			switch instr.(type) {
   199  			case Value:
   200  				instr.(setNumable).setNum(v)
   201  				v++
   202  			}
   203  		}
   204  	}
   205  }
   206  
   207  // buildReferrers populates the def/use information in all non-nil
   208  // Value.Referrers slice.
   209  // Precondition: all such slices are initially empty.
   210  func buildReferrers(f *Function) {
   211  	var rands []*Value
   212  	for _, b := range f.Blocks {
   213  		for _, instr := range b.Instrs {
   214  			rands = instr.Operands(rands[:0]) // recycle storage
   215  			for _, rand := range rands {
   216  				if r := *rand; r != nil {
   217  					if ref := r.Referrers(); ref != nil {
   218  						*ref = append(*ref, instr)
   219  					}
   220  				}
   221  			}
   222  		}
   223  	}
   224  }
   225  
   226  // mayNeedRuntimeTypes returns all of the types in the body of fn that might need runtime types.
   227  func mayNeedRuntimeTypes(fn *Function) []types.Type {
   228  	var ts []types.Type
   229  	for _, bb := range fn.Blocks {
   230  		for _, instr := range bb.Instrs {
   231  			if mi, ok := instr.(*MakeInterface); ok {
   232  				ts = append(ts, mi.X.Type())
   233  			}
   234  		}
   235  	}
   236  	return ts
   237  }
   238  
   239  // finishBody() finalizes the contents of the function after SSA code generation of its body.
   240  //
   241  // The function is not done being built until done() is called.
   242  func (f *Function) finishBody() {
   243  	f.objects = nil
   244  	f.currentBlock = nil
   245  	f.lblocks = nil
   246  
   247  	// Don't pin the AST in memory (except in debug mode).
   248  	if n := f.syntax; n != nil && !f.debugInfo() {
   249  		f.syntax = extentNode{n.Pos(), n.End()}
   250  	}
   251  
   252  	// Remove from f.Locals any Allocs that escape to the heap.
   253  	j := 0
   254  	for _, l := range f.Locals {
   255  		if !l.Heap {
   256  			f.Locals[j] = l
   257  			j++
   258  		}
   259  	}
   260  	// Nil out f.Locals[j:] to aid GC.
   261  	for i := j; i < len(f.Locals); i++ {
   262  		f.Locals[i] = nil
   263  	}
   264  	f.Locals = f.Locals[:j]
   265  
   266  	optimizeBlocks(f)
   267  
   268  	buildReferrers(f)
   269  
   270  	buildDomTree(f)
   271  
   272  	if f.Prog.mode&NaiveForm == 0 {
   273  		// For debugging pre-state of lifting pass:
   274  		// numberRegisters(f)
   275  		// f.WriteTo(os.Stderr)
   276  		lift(f)
   277  	}
   278  
   279  	// clear remaining stateful variables
   280  	f.namedResults = nil // (used by lifting)
   281  	f.info = nil
   282  	f.subst = nil
   283  
   284  	numberRegisters(f)
   285  }
   286  
   287  // After this, function is done with BUILD phase.
   288  func (f *Function) done() {
   289  	assert(f.parent == nil, "done called on an anonymous function")
   290  
   291  	var visit func(*Function)
   292  	visit = func(f *Function) {
   293  		for _, anon := range f.AnonFuncs {
   294  			visit(anon) // anon is done building before f.
   295  		}
   296  
   297  		f.built = true // function is done with BUILD phase
   298  
   299  		if f.Prog.mode&PrintFunctions != 0 {
   300  			printMu.Lock()
   301  			f.WriteTo(os.Stdout)
   302  			printMu.Unlock()
   303  		}
   304  
   305  		if f.Prog.mode&SanityCheckFunctions != 0 {
   306  			mustSanityCheck(f, nil)
   307  		}
   308  	}
   309  	visit(f)
   310  }
   311  
   312  // removeNilBlocks eliminates nils from f.Blocks and updates each
   313  // BasicBlock.Index.  Use this after any pass that may delete blocks.
   314  //
   315  func (f *Function) removeNilBlocks() {
   316  	j := 0
   317  	for _, b := range f.Blocks {
   318  		if b != nil {
   319  			b.Index = j
   320  			f.Blocks[j] = b
   321  			j++
   322  		}
   323  	}
   324  	// Nil out f.Blocks[j:] to aid GC.
   325  	for i := j; i < len(f.Blocks); i++ {
   326  		f.Blocks[i] = nil
   327  	}
   328  	f.Blocks = f.Blocks[:j]
   329  }
   330  
   331  // SetDebugMode sets the debug mode for package pkg.  If true, all its
   332  // functions will include full debug info.  This greatly increases the
   333  // size of the instruction stream, and causes Functions to depend upon
   334  // the ASTs, potentially keeping them live in memory for longer.
   335  //
   336  func (pkg *Package) SetDebugMode(debug bool) {
   337  	// TODO(adonovan): do we want ast.File granularity?
   338  	pkg.debug = debug
   339  }
   340  
   341  // debugInfo reports whether debug info is wanted for this function.
   342  func (f *Function) debugInfo() bool {
   343  	return f.Pkg != nil && f.Pkg.debug
   344  }
   345  
   346  // addNamedLocal creates a local variable, adds it to function f and
   347  // returns it.  Its name and type are taken from obj.  Subsequent
   348  // calls to f.lookup(obj) will return the same local.
   349  //
   350  func (f *Function) addNamedLocal(obj types.Object) *Alloc {
   351  	l := f.addLocal(obj.Type(), obj.Pos())
   352  	l.Comment = obj.Name()
   353  	f.objects[obj] = l
   354  	return l
   355  }
   356  
   357  func (f *Function) addLocalForIdent(id *ast.Ident) *Alloc {
   358  	return f.addNamedLocal(f.info.Defs[id])
   359  }
   360  
   361  // addLocal creates an anonymous local variable of type typ, adds it
   362  // to function f and returns it.  pos is the optional source location.
   363  //
   364  func (f *Function) addLocal(typ types.Type, pos token.Pos) *Alloc {
   365  	v := &Alloc{}
   366  	v.setType(types.NewPointer(typ))
   367  	v.setPos(pos)
   368  	f.Locals = append(f.Locals, v)
   369  	f.emit(v)
   370  	return v
   371  }
   372  
   373  // lookup returns the address of the named variable identified by obj
   374  // that is local to function f or one of its enclosing functions.
   375  // If escaping, the reference comes from a potentially escaping pointer
   376  // expression and the referent must be heap-allocated.
   377  //
   378  func (f *Function) lookup(obj types.Object, escaping bool) Value {
   379  	if v, ok := f.objects[obj]; ok {
   380  		if alloc, ok := v.(*Alloc); ok && escaping {
   381  			alloc.Heap = true
   382  		}
   383  		return v // function-local var (address)
   384  	}
   385  
   386  	// Definition must be in an enclosing function;
   387  	// plumb it through intervening closures.
   388  	if f.parent == nil {
   389  		panic("no ssa.Value for " + obj.String())
   390  	}
   391  	outer := f.parent.lookup(obj, true) // escaping
   392  	v := &FreeVar{
   393  		name:   obj.Name(),
   394  		typ:    outer.Type(),
   395  		pos:    outer.Pos(),
   396  		outer:  outer,
   397  		parent: f,
   398  	}
   399  	f.objects[obj] = v
   400  	f.FreeVars = append(f.FreeVars, v)
   401  	return v
   402  }
   403  
   404  // emit emits the specified instruction to function f.
   405  func (f *Function) emit(instr Instruction) Value {
   406  	return f.currentBlock.emit(instr)
   407  }
   408  
   409  // RelString returns the full name of this function, qualified by
   410  // package name, receiver type, etc.
   411  //
   412  // The specific formatting rules are not guaranteed and may change.
   413  //
   414  // Examples:
   415  //      "math.IsNaN"                  // a package-level function
   416  //      "(*bytes.Buffer).Bytes"       // a declared method or a wrapper
   417  //      "(*bytes.Buffer).Bytes$thunk" // thunk (func wrapping method; receiver is param 0)
   418  //      "(*bytes.Buffer).Bytes$bound" // bound (func wrapping method; receiver supplied by closure)
   419  //      "main.main$1"                 // an anonymous function in main
   420  //      "main.init#1"                 // a declared init function
   421  //      "main.init"                   // the synthesized package initializer
   422  //
   423  // When these functions are referred to from within the same package
   424  // (i.e. from == f.Pkg.Object), they are rendered without the package path.
   425  // For example: "IsNaN", "(*Buffer).Bytes", etc.
   426  //
   427  // All non-synthetic functions have distinct package-qualified names.
   428  // (But two methods may have the same name "(T).f" if one is a synthetic
   429  // wrapper promoting a non-exported method "f" from another package; in
   430  // that case, the strings are equal but the identifiers "f" are distinct.)
   431  //
   432  func (f *Function) RelString(from *types.Package) string {
   433  	// Anonymous?
   434  	if f.parent != nil {
   435  		// An anonymous function's Name() looks like "parentName$1",
   436  		// but its String() should include the type/package/etc.
   437  		parent := f.parent.RelString(from)
   438  		for i, anon := range f.parent.AnonFuncs {
   439  			if anon == f {
   440  				return fmt.Sprintf("%s$%d", parent, 1+i)
   441  			}
   442  		}
   443  
   444  		return f.name // should never happen
   445  	}
   446  
   447  	// Method (declared or wrapper)?
   448  	if recv := f.Signature.Recv(); recv != nil {
   449  		return f.relMethod(from, recv.Type())
   450  	}
   451  
   452  	// Thunk?
   453  	if f.method != nil {
   454  		return f.relMethod(from, f.method.Recv())
   455  	}
   456  
   457  	// Bound?
   458  	if len(f.FreeVars) == 1 && strings.HasSuffix(f.name, "$bound") {
   459  		return f.relMethod(from, f.FreeVars[0].Type())
   460  	}
   461  
   462  	// Package-level function?
   463  	// Prefix with package name for cross-package references only.
   464  	if p := f.relPkg(); p != nil && p != from {
   465  		return fmt.Sprintf("%s.%s", p.Path(), f.name)
   466  	}
   467  
   468  	// Unknown.
   469  	return f.name
   470  }
   471  
   472  func (f *Function) relMethod(from *types.Package, recv types.Type) string {
   473  	return fmt.Sprintf("(%s).%s", relType(recv, from), f.name)
   474  }
   475  
   476  // writeSignature writes to buf the signature sig in declaration syntax.
   477  func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *types.Signature, params []*Parameter) {
   478  	buf.WriteString("func ")
   479  	if recv := sig.Recv(); recv != nil {
   480  		buf.WriteString("(")
   481  		if n := params[0].Name(); n != "" {
   482  			buf.WriteString(n)
   483  			buf.WriteString(" ")
   484  		}
   485  		types.WriteType(buf, params[0].Type(), types.RelativeTo(from))
   486  		buf.WriteString(") ")
   487  	}
   488  	buf.WriteString(name)
   489  	types.WriteSignature(buf, sig, types.RelativeTo(from))
   490  }
   491  
   492  // declaredPackage returns the package fn is declared in or nil if the
   493  // function is not declared in a package.
   494  func (fn *Function) declaredPackage() *Package {
   495  	switch {
   496  	case fn.Pkg != nil:
   497  		return fn.Pkg // non-generic function
   498  		// generics:
   499  	// case fn.Origin != nil:
   500  	// 	return fn.Origin.pkg // instance of a named generic function
   501  	case fn.parent != nil:
   502  		return fn.parent.declaredPackage() // instance of an anonymous [generic] function
   503  	default:
   504  		return nil // function is not declared in a package, e.g. a wrapper.
   505  	}
   506  }
   507  
   508  // relPkg returns types.Package fn is printed in relationship to.
   509  func (fn *Function) relPkg() *types.Package {
   510  	if p := fn.declaredPackage(); p != nil {
   511  		return p.Pkg
   512  	}
   513  	return nil
   514  }
   515  
   516  var _ io.WriterTo = (*Function)(nil) // *Function implements io.Writer
   517  
   518  func (f *Function) WriteTo(w io.Writer) (int64, error) {
   519  	var buf bytes.Buffer
   520  	WriteFunction(&buf, f)
   521  	n, err := w.Write(buf.Bytes())
   522  	return int64(n), err
   523  }
   524  
   525  // WriteFunction writes to buf a human-readable "disassembly" of f.
   526  func WriteFunction(buf *bytes.Buffer, f *Function) {
   527  	fmt.Fprintf(buf, "# Name: %s\n", f.String())
   528  	if f.Pkg != nil {
   529  		fmt.Fprintf(buf, "# Package: %s\n", f.Pkg.Pkg.Path())
   530  	}
   531  	if syn := f.Synthetic; syn != "" {
   532  		fmt.Fprintln(buf, "# Synthetic:", syn)
   533  	}
   534  	if pos := f.Pos(); pos.IsValid() {
   535  		fmt.Fprintf(buf, "# Location: %s\n", f.Prog.Fset.Position(pos))
   536  	}
   537  
   538  	if f.parent != nil {
   539  		fmt.Fprintf(buf, "# Parent: %s\n", f.parent.Name())
   540  	}
   541  
   542  	if f.Recover != nil {
   543  		fmt.Fprintf(buf, "# Recover: %s\n", f.Recover)
   544  	}
   545  
   546  	from := f.relPkg()
   547  
   548  	if f.FreeVars != nil {
   549  		buf.WriteString("# Free variables:\n")
   550  		for i, fv := range f.FreeVars {
   551  			fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, fv.Name(), relType(fv.Type(), from))
   552  		}
   553  	}
   554  
   555  	if len(f.Locals) > 0 {
   556  		buf.WriteString("# Locals:\n")
   557  		for i, l := range f.Locals {
   558  			fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, l.Name(), relType(deref(l.Type()), from))
   559  		}
   560  	}
   561  	writeSignature(buf, from, f.Name(), f.Signature, f.Params)
   562  	buf.WriteString(":\n")
   563  
   564  	if f.Blocks == nil {
   565  		buf.WriteString("\t(external)\n")
   566  	}
   567  
   568  	// NB. column calculations are confused by non-ASCII
   569  	// characters and assume 8-space tabs.
   570  	const punchcard = 80 // for old time's sake.
   571  	const tabwidth = 8
   572  	for _, b := range f.Blocks {
   573  		if b == nil {
   574  			// Corrupt CFG.
   575  			fmt.Fprintf(buf, ".nil:\n")
   576  			continue
   577  		}
   578  		n, _ := fmt.Fprintf(buf, "%d:", b.Index)
   579  		bmsg := fmt.Sprintf("%s P:%d S:%d", b.Comment, len(b.Preds), len(b.Succs))
   580  		fmt.Fprintf(buf, "%*s%s\n", punchcard-1-n-len(bmsg), "", bmsg)
   581  
   582  		if false { // CFG debugging
   583  			fmt.Fprintf(buf, "\t# CFG: %s --> %s --> %s\n", b.Preds, b, b.Succs)
   584  		}
   585  		for _, instr := range b.Instrs {
   586  			buf.WriteString("\t")
   587  			switch v := instr.(type) {
   588  			case Value:
   589  				l := punchcard - tabwidth
   590  				// Left-align the instruction.
   591  				if name := v.Name(); name != "" {
   592  					n, _ := fmt.Fprintf(buf, "%s = ", name)
   593  					l -= n
   594  				}
   595  				n, _ := buf.WriteString(instr.String())
   596  				l -= n
   597  				// Right-align the type if there's space.
   598  				if t := v.Type(); t != nil {
   599  					buf.WriteByte(' ')
   600  					ts := relType(t, from)
   601  					l -= len(ts) + len("  ") // (spaces before and after type)
   602  					if l > 0 {
   603  						fmt.Fprintf(buf, "%*s", l, "")
   604  					}
   605  					buf.WriteString(ts)
   606  				}
   607  			case nil:
   608  				// Be robust against bad transforms.
   609  				buf.WriteString("<deleted>")
   610  			default:
   611  				buf.WriteString(instr.String())
   612  			}
   613  			buf.WriteString("\n")
   614  		}
   615  	}
   616  	fmt.Fprintf(buf, "\n")
   617  }
   618  
   619  // newBasicBlock adds to f a new basic block and returns it.  It does
   620  // not automatically become the current block for subsequent calls to emit.
   621  // comment is an optional string for more readable debugging output.
   622  //
   623  func (f *Function) newBasicBlock(comment string) *BasicBlock {
   624  	b := &BasicBlock{
   625  		Index:   len(f.Blocks),
   626  		Comment: comment,
   627  		parent:  f,
   628  	}
   629  	b.Succs = b.succs2[:0]
   630  	f.Blocks = append(f.Blocks, b)
   631  	return b
   632  }
   633  
   634  // NewFunction returns a new synthetic Function instance belonging to
   635  // prog, with its name and signature fields set as specified.
   636  //
   637  // The caller is responsible for initializing the remaining fields of
   638  // the function object, e.g. Pkg, Params, Blocks.
   639  //
   640  // It is practically impossible for clients to construct well-formed
   641  // SSA functions/packages/programs directly, so we assume this is the
   642  // job of the Builder alone.  NewFunction exists to provide clients a
   643  // little flexibility.  For example, analysis tools may wish to
   644  // construct fake Functions for the root of the callgraph, a fake
   645  // "reflect" package, etc.
   646  //
   647  // TODO(adonovan): think harder about the API here.
   648  //
   649  func (prog *Program) NewFunction(name string, sig *types.Signature, provenance string) *Function {
   650  	return &Function{Prog: prog, name: name, Signature: sig, Synthetic: provenance}
   651  }
   652  
   653  type extentNode [2]token.Pos
   654  
   655  func (n extentNode) Pos() token.Pos { return n[0] }
   656  func (n extentNode) End() token.Pos { return n[1] }
   657  
   658  // Syntax returns an ast.Node whose Pos/End methods provide the
   659  // lexical extent of the function if it was defined by Go source code
   660  // (f.Synthetic==""), or nil otherwise.
   661  //
   662  // If f was built with debug information (see Package.SetDebugRef),
   663  // the result is the *ast.FuncDecl or *ast.FuncLit that declared the
   664  // function.  Otherwise, it is an opaque Node providing only position
   665  // information; this avoids pinning the AST in memory.
   666  //
   667  func (f *Function) Syntax() ast.Node { return f.syntax }