// EnclosingFunction returns the function that contains the syntax // node denoted by path. // // Syntax associated with package-level variable specifications is // 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). func EnclosingFunction(pkg *Package, path []ast.Node) *Function { … } // HasEnclosingFunction returns true if the AST node denoted by path // is contained within the declaration of some function or // package-level variable. // // Unlike EnclosingFunction, the behaviour of this function does not // 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 { … } // findEnclosingPackageLevelFunction returns the Function // corresponding to the package-level function enclosing path. 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 { … } // ValueForExpr returns the SSA Value that corresponds to non-constant // 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. // // If e is an addressable expression used in an lvalue context, // value is the address denoted by e, and isAddr is true. // // The types of e (or &e, if isAddr) and the result are equal // (modulo "untyped" bools resulting from comparisons). // // (Tip: to find the ssa.Value given a source position, use // 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) { … } // Package returns the SSA Package corresponding to the specified // type-checker package. It returns nil if no such Package was // created by a prior call to prog.CreatePackage. func (prog *Program) Package(pkg *types.Package) *Package { … } // packageLevelMember returns the package-level member corresponding // to the specified symbol, which may be a package-level const // (*NamedConst), var (*Global) or func/method (*Function) of some // package in prog. // // It returns nil if the object belongs to a package that has not been // created by prog.CreatePackage. func (prog *Program) packageLevelMember(obj types.Object) Member { … } // FuncValue returns the SSA function or (non-interface) method // denoted by the specified func symbol. It returns nil id the symbol // denotes an interface method, or belongs to a package that was not // created by prog.CreatePackage. func (prog *Program) FuncValue(obj *types.Func) *Function { … } // ConstValue returns the SSA constant denoted by the specified const symbol. func (prog *Program) ConstValue(obj *types.Const) *Const { … } // VarValue returns the SSA Value that corresponds to a specific // identifier denoting the specified var symbol. // // VarValue returns nil if a local variable was not found, perhaps // because its package was not built, the debug information was not // requested during SSA construction, or the value was optimized away. // // ref is the path to an ast.Ident (e.g. from PathEnclosingInterval), // and that ident must resolve to obj. // // pkg is the package enclosing the reference. (A reference to a var // always occurs within a function, so we need to know where to find it.) // // 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 // // All other identifiers denote addressable locations (variables). // For them, VarValue may return either the variable's address or its // value, even when the expression is evaluated only for its value; the // situation is reported by isAddr, the second component of the result. // // 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 // // 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) { … }