diff options
Diffstat (limited to 'go/ssa/source.go')
-rw-r--r-- | go/ssa/source.go | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/go/ssa/source.go b/go/ssa/source.go index 7e2a369dd..b9a08363e 100644 --- a/go/ssa/source.go +++ b/go/ssa/source.go @@ -14,6 +14,8 @@ import ( "go/ast" "go/token" "go/types" + + "golang.org/x/tools/internal/typeparams" ) // EnclosingFunction returns the function that contains the syntax @@ -23,11 +25,10 @@ import ( // enclosed by the package's init() function. // // Returns nil if not found; reasons might include: -// - the node is not enclosed by any function. -// - the node is within an anonymous function (FuncLit) and -// its SSA function has not been created yet -// (pkg.Build() has not yet been called). -// +// - the node is not enclosed by any function. +// - the node is within an anonymous function (FuncLit) and +// its SSA function has not been created yet +// (pkg.Build() has not yet been called). func EnclosingFunction(pkg *Package, path []ast.Node) *Function { // Start with package-level function... fn := findEnclosingPackageLevelFunction(pkg, path) @@ -65,14 +66,12 @@ outer: // depend on whether SSA code for pkg has been built, so it can be // used to quickly reject check inputs that will cause // EnclosingFunction to fail, prior to SSA building. -// func HasEnclosingFunction(pkg *Package, path []ast.Node) bool { return findEnclosingPackageLevelFunction(pkg, path) != nil } // findEnclosingPackageLevelFunction returns the Function // corresponding to the package-level function enclosing path. -// func findEnclosingPackageLevelFunction(pkg *Package, path []ast.Node) *Function { if n := len(path); n >= 2 { // [... {Gen,Func}Decl File] switch decl := path[n-2].(type) { @@ -107,7 +106,6 @@ func findEnclosingPackageLevelFunction(pkg *Package, path []ast.Node) *Function // findNamedFunc returns the named function whose FuncDecl.Ident is at // position pos. -// func findNamedFunc(pkg *Package, pos token.Pos) *Function { // Look at all package members and method sets of named types. // Not very efficient. @@ -135,13 +133,13 @@ func findNamedFunc(pkg *Package, pos token.Pos) *Function { // expression e. // // It returns nil if no value was found, e.g. -// - the expression is not lexically contained within f; -// - f was not built with debug information; or -// - e is a constant expression. (For efficiency, no debug -// information is stored for constants. Use -// go/types.Info.Types[e].Value instead.) -// - e is a reference to nil or a built-in function. -// - the value was optimised away. +// - the expression is not lexically contained within f; +// - f was not built with debug information; or +// - e is a constant expression. (For efficiency, no debug +// information is stored for constants. Use +// go/types.Info.Types[e].Value instead.) +// - e is a reference to nil or a built-in function. +// - the value was optimised away. // // If e is an addressable expression used in an lvalue context, // value is the address denoted by e, and isAddr is true. @@ -153,7 +151,6 @@ func findNamedFunc(pkg *Package, pos token.Pos) *Function { // astutil.PathEnclosingInterval to locate the ast.Node, then // EnclosingFunction to locate the Function, then ValueForExpr to find // the ssa.Value.) -// func (f *Function) ValueForExpr(e ast.Expr) (value Value, isAddr bool) { if f.debugInfo() { // (opt) e = unparen(e) @@ -175,7 +172,6 @@ func (f *Function) ValueForExpr(e ast.Expr) (value Value, isAddr bool) { // Package returns the SSA Package corresponding to the specified // type-checker package object. // It returns nil if no such SSA package has been created. -// func (prog *Program) Package(obj *types.Package) *Package { return prog.packages[obj] } @@ -184,7 +180,6 @@ func (prog *Program) Package(obj *types.Package) *Package { // the specified named object, which may be a package-level const // (*NamedConst), var (*Global) or func (*Function) of some package in // prog. It returns nil if the object is not found. -// func (prog *Program) packageLevelMember(obj types.Object) Member { if pkg, ok := prog.packages[obj.Pkg()]; ok { return pkg.objects[obj] @@ -192,12 +187,17 @@ func (prog *Program) packageLevelMember(obj types.Object) Member { return nil } +// originFunc returns the package-level generic function that is the +// origin of obj. If returns nil if the generic function is not found. +func (prog *Program) originFunc(obj *types.Func) *Function { + return prog.declaredFunc(typeparams.OriginMethod(obj)) +} + // FuncValue returns the concrete Function denoted by the source-level // named function obj, or nil if obj denotes an interface method. // // TODO(adonovan): check the invariant that obj.Type() matches the // result's Signature, both in the params/results and in the receiver. -// func (prog *Program) FuncValue(obj *types.Func) *Function { fn, _ := prog.packageLevelMember(obj).(*Function) return fn @@ -205,7 +205,6 @@ func (prog *Program) FuncValue(obj *types.Func) *Function { // ConstValue returns the SSA Value denoted by the source-level named // constant obj. -// func (prog *Program) ConstValue(obj *types.Const) *Const { // TODO(adonovan): opt: share (don't reallocate) // Consts for const objects and constant ast.Exprs. @@ -237,8 +236,9 @@ func (prog *Program) ConstValue(obj *types.Const) *Const { // If the identifier is a field selector and its base expression is // non-addressable, then VarValue returns the value of that field. // For example: -// func f() struct {x int} -// f().x // VarValue(x) returns a *Field instruction of type int +// +// func f() struct {x int} +// f().x // VarValue(x) returns a *Field instruction of type int // // All other identifiers denote addressable locations (variables). // For them, VarValue may return either the variable's address or its @@ -247,14 +247,14 @@ func (prog *Program) ConstValue(obj *types.Const) *Const { // // If !isAddr, the returned value is the one associated with the // specific identifier. For example, -// var x int // VarValue(x) returns Const 0 here -// x = 1 // VarValue(x) returns Const 1 here +// +// var x int // VarValue(x) returns Const 0 here +// x = 1 // VarValue(x) returns Const 1 here // // It is not specified whether the value or the address is returned in // any particular case, as it may depend upon optimizations performed // during SSA code generation, such as registerization, constant // folding, avoidance of materialization of subexpressions, etc. -// func (prog *Program) VarValue(obj *types.Var, pkg *Package, ref []ast.Node) (value Value, isAddr bool) { // All references to a var are local to some function, possibly init. fn := EnclosingFunction(pkg, ref) |