// ssaValueForIdent returns the ssa.Value for the ast.Ident whose path // to the root of the AST is path. isAddr reports whether the // ssa.Value is the address denoted by the ast.Ident, not its value. // func ssaValueForIdent(prog *ssa.Program, qinfo *importer.PackageInfo, obj types.Object, path []ast.Node) (value ssa.Value, isAddr bool, err error) { switch obj := obj.(type) { case *types.Var: pkg := prog.Package(qinfo.Pkg) pkg.Build() if v, addr := prog.VarValue(obj, pkg, path); v != nil { return v, addr, nil } return nil, false, fmt.Errorf("can't locate SSA Value for var %s", obj.Name()) case *types.Func: return prog.FuncValue(obj), false, nil } panic(obj) }
// ssaValueForExpr returns the ssa.Value of the non-ast.Ident // expression whose path to the root of the AST is path. It may // return a nil Value without an error to indicate the pointer // analysis is not appropriate. // func ssaValueForExpr(prog *ssa.Program, qinfo *importer.PackageInfo, path []ast.Node) (ssa.Value, error) { pkg := prog.Package(qinfo.Pkg) pkg.SetDebugMode(true) pkg.Build() fn := ssa.EnclosingFunction(pkg, path) if fn == nil { return nil, fmt.Errorf("no SSA function built for this location (dead code?)") } if v := fn.ValueForExpr(path[0].(ast.Expr)); v != nil { return v, nil } return nil, fmt.Errorf("can't locate SSA Value for expression in %s", fn) }
// ssaValueForIdent returns the ssa.Value for the ast.Ident whose path // to the root of the AST is path. It may return a nil Value without // an error to indicate the pointer analysis is not appropriate. // func ssaValueForIdent(prog *ssa.Program, qinfo *importer.PackageInfo, obj types.Object, path []ast.Node) (ssa.Value, error) { if obj, ok := obj.(*types.Var); ok { pkg := prog.Package(qinfo.Pkg) pkg.Build() if v := prog.VarValue(obj, pkg, path); v != nil { // Don't run pointer analysis on a ref to a const expression. if _, ok := v.(*ssa.Const); ok { v = nil } return v, nil } return nil, fmt.Errorf("can't locate SSA Value for var %s", obj.Name()) } // Don't run pointer analysis on const/func objects. return nil, nil }