go/ssa: rename some API features (incompatible change)
Rename the following exported names: (*Program).BuildAll → Build (*Program).Method → MethodValue Package.Object → Pkg Also: (*Function).pkgobj → pkg Change-Id: Iff7e6c240ebe6786ba759278ac0daa3d66698013 Reviewed-on: https://go-review.googlesource.com/14134 Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
e21b7325f7
commit
afcda55b39
|
@ -180,7 +180,7 @@ func doCallgraph(ctxt *build.Context, algo, format string, tests bool, args []st
|
||||||
|
|
||||||
// Create and build SSA-form program representation.
|
// Create and build SSA-form program representation.
|
||||||
prog := ssautil.CreateProgram(iprog, 0)
|
prog := ssautil.CreateProgram(iprog, 0)
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
// -- call graph construction ------------------------------------------
|
// -- call graph construction ------------------------------------------
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ func mainPackage(prog *ssa.Program, tests bool) (*ssa.Package, error) {
|
||||||
|
|
||||||
// Otherwise, use the first package named main.
|
// Otherwise, use the first package named main.
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
if pkg.Object.Name() == "main" {
|
if pkg.Pkg.Name() == "main" {
|
||||||
if pkg.Func("main") == nil {
|
if pkg.Func("main") == nil {
|
||||||
return nil, fmt.Errorf("no func main() in main package")
|
return nil, fmt.Errorf("no func main() in main package")
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ func doMain() error {
|
||||||
|
|
||||||
// Run the interpreter.
|
// Run the interpreter.
|
||||||
if *runFlag {
|
if *runFlag {
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
var main *ssa.Package
|
var main *ssa.Package
|
||||||
pkgs := prog.AllPackages()
|
pkgs := prog.AllPackages()
|
||||||
|
@ -162,7 +162,7 @@ func doMain() error {
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, run main.main.
|
// Otherwise, run main.main.
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
if pkg.Object.Name() == "main" {
|
if pkg.Pkg.Name() == "main" {
|
||||||
main = pkg
|
main = pkg
|
||||||
if main.Func("main") == nil {
|
if main.Func("main") == nil {
|
||||||
return fmt.Errorf("no func main() in main package")
|
return fmt.Errorf("no func main() in main package")
|
||||||
|
@ -180,7 +180,7 @@ func doMain() error {
|
||||||
build.Default.GOARCH, runtime.GOARCH)
|
build.Default.GOARCH, runtime.GOARCH)
|
||||||
}
|
}
|
||||||
|
|
||||||
interp.Interpret(main, interpMode, conf.TypeChecker.Sizes, main.Object.Path(), args)
|
interp.Interpret(main, interpMode, conf.TypeChecker.Sizes, main.Pkg.Path(), args)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,11 +78,11 @@ func TestCHA(t *testing.T) {
|
||||||
|
|
||||||
prog := ssautil.CreateProgram(iprog, 0)
|
prog := ssautil.CreateProgram(iprog, 0)
|
||||||
mainPkg := prog.Package(iprog.Created[0].Pkg)
|
mainPkg := prog.Package(iprog.Created[0].Pkg)
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
cg := cha.CallGraph(prog)
|
cg := cha.CallGraph(prog)
|
||||||
|
|
||||||
if got := printGraph(cg, mainPkg.Object); got != want {
|
if got := printGraph(cg, mainPkg.Pkg); got != want {
|
||||||
t.Errorf("%s: got:\n%s\nwant:\n%s",
|
t.Errorf("%s: got:\n%s\nwant:\n%s",
|
||||||
prog.Fset.Position(pos), got, want)
|
prog.Fset.Position(pos), got, want)
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ func (r *rta) visitDynCall(site ssa.CallInstruction) {
|
||||||
func (r *rta) addInvokeEdge(site ssa.CallInstruction, C types.Type) {
|
func (r *rta) addInvokeEdge(site ssa.CallInstruction, C types.Type) {
|
||||||
// Ascertain the concrete method of C to be called.
|
// Ascertain the concrete method of C to be called.
|
||||||
imethod := site.Common().Method
|
imethod := site.Common().Method
|
||||||
cmethod := r.prog.Method(r.prog.MethodSets.MethodSet(C).Lookup(imethod.Pkg(), imethod.Name()))
|
cmethod := r.prog.MethodValue(r.prog.MethodSets.MethodSet(C).Lookup(imethod.Pkg(), imethod.Name()))
|
||||||
r.addEdge(site, cmethod, true)
|
r.addEdge(site, cmethod, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ func (r *rta) addRuntimeType(T types.Type, skip bool) {
|
||||||
|
|
||||||
if m.Exported() {
|
if m.Exported() {
|
||||||
// Exported methods are always potentially callable via reflection.
|
// Exported methods are always potentially callable via reflection.
|
||||||
r.addReachable(r.prog.Method(sel), true)
|
r.addReachable(r.prog.MethodValue(sel), true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,14 +83,14 @@ func TestRTA(t *testing.T) {
|
||||||
|
|
||||||
prog := ssautil.CreateProgram(iprog, 0)
|
prog := ssautil.CreateProgram(iprog, 0)
|
||||||
mainPkg := prog.Package(iprog.Created[0].Pkg)
|
mainPkg := prog.Package(iprog.Created[0].Pkg)
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
res := rta.Analyze([]*ssa.Function{
|
res := rta.Analyze([]*ssa.Function{
|
||||||
mainPkg.Func("main"),
|
mainPkg.Func("main"),
|
||||||
mainPkg.Func("init"),
|
mainPkg.Func("init"),
|
||||||
}, true)
|
}, true)
|
||||||
|
|
||||||
if got := printResult(res, mainPkg.Object); got != want {
|
if got := printResult(res, mainPkg.Pkg); got != want {
|
||||||
t.Errorf("%s: got:\n%s\nwant:\n%s",
|
t.Errorf("%s: got:\n%s\nwant:\n%s",
|
||||||
prog.Fset.Position(pos), got, want)
|
prog.Fset.Position(pos), got, want)
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ func TestStatic(t *testing.T) {
|
||||||
P := iprog.Created[0].Pkg
|
P := iprog.Created[0].Pkg
|
||||||
|
|
||||||
prog := ssautil.CreateProgram(iprog, 0)
|
prog := ssautil.CreateProgram(iprog, 0)
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
cg := static.CallGraph(prog)
|
cg := static.CallGraph(prog)
|
||||||
|
|
||||||
|
|
|
@ -254,17 +254,17 @@ func Analyze(config *Config) (result *Result, err error) {
|
||||||
for _, pkg := range a.prog.AllPackages() {
|
for _, pkg := range a.prog.AllPackages() {
|
||||||
// (This only checks that the package scope is complete,
|
// (This only checks that the package scope is complete,
|
||||||
// not that func bodies exist, but it's a good signal.)
|
// not that func bodies exist, but it's a good signal.)
|
||||||
if !pkg.Object.Complete() {
|
if !pkg.Pkg.Complete() {
|
||||||
return nil, fmt.Errorf(`pointer analysis requires a complete program yet package %q was incomplete`, pkg.Object.Path())
|
return nil, fmt.Errorf(`pointer analysis requires a complete program yet package %q was incomplete`, pkg.Pkg.Path())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if reflect := a.prog.ImportedPackage("reflect"); reflect != nil {
|
if reflect := a.prog.ImportedPackage("reflect"); reflect != nil {
|
||||||
rV := reflect.Object.Scope().Lookup("Value")
|
rV := reflect.Pkg.Scope().Lookup("Value")
|
||||||
a.reflectValueObj = rV
|
a.reflectValueObj = rV
|
||||||
a.reflectValueCall = a.prog.LookupMethod(rV.Type(), nil, "Call")
|
a.reflectValueCall = a.prog.LookupMethod(rV.Type(), nil, "Call")
|
||||||
a.reflectType = reflect.Object.Scope().Lookup("Type").Type().(*types.Named)
|
a.reflectType = reflect.Pkg.Scope().Lookup("Type").Type().(*types.Named)
|
||||||
a.reflectRtypeObj = reflect.Object.Scope().Lookup("rtype")
|
a.reflectRtypeObj = reflect.Pkg.Scope().Lookup("rtype")
|
||||||
a.reflectRtypePtr = types.NewPointer(a.reflectRtypeObj.Type())
|
a.reflectRtypePtr = types.NewPointer(a.reflectRtypeObj.Type())
|
||||||
|
|
||||||
// Override flattening of reflect.Value, treating it like a basic type.
|
// Override flattening of reflect.Value, treating it like a basic type.
|
||||||
|
|
|
@ -66,7 +66,7 @@ func main() {
|
||||||
mainPkg := prog.Package(iprog.Created[0].Pkg)
|
mainPkg := prog.Package(iprog.Created[0].Pkg)
|
||||||
|
|
||||||
// Build SSA code for bodies of all functions in the whole program.
|
// Build SSA code for bodies of all functions in the whole program.
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
// Configure the pointer analysis to build a call-graph.
|
// Configure the pointer analysis to build a call-graph.
|
||||||
config := &pointer.Config{
|
config := &pointer.Config{
|
||||||
|
@ -76,7 +76,7 @@ func main() {
|
||||||
|
|
||||||
// Query points-to set of (C).f's parameter m, a map.
|
// Query points-to set of (C).f's parameter m, a map.
|
||||||
C := mainPkg.Type("C").Type()
|
C := mainPkg.Type("C").Type()
|
||||||
Cfm := prog.LookupMethod(C, mainPkg.Object, "f").Params[1]
|
Cfm := prog.LookupMethod(C, mainPkg.Pkg, "f").Params[1]
|
||||||
config.AddQuery(Cfm)
|
config.AddQuery(Cfm)
|
||||||
|
|
||||||
// Run the pointer analysis.
|
// Run the pointer analysis.
|
||||||
|
|
|
@ -1223,7 +1223,7 @@ func (a *analysis) genMethodsOf(T types.Type) {
|
||||||
// I think so, but the answer may depend on reflection.
|
// I think so, but the answer may depend on reflection.
|
||||||
mset := a.prog.MethodSets.MethodSet(T)
|
mset := a.prog.MethodSets.MethodSet(T)
|
||||||
for i, n := 0, mset.Len(); i < n; i++ {
|
for i, n := 0, mset.Len(); i < n; i++ {
|
||||||
m := a.prog.Method(mset.At(i))
|
m := a.prog.MethodValue(mset.At(i))
|
||||||
a.valueNode(m)
|
a.valueNode(m)
|
||||||
|
|
||||||
if !itf {
|
if !itf {
|
||||||
|
|
|
@ -211,7 +211,7 @@ func (a *analysis) isReflect(fn *ssa.Function) bool {
|
||||||
return false // "reflect" package not loaded
|
return false // "reflect" package not loaded
|
||||||
}
|
}
|
||||||
reflectPackage := a.reflectValueObj.Pkg()
|
reflectPackage := a.reflectValueObj.Pkg()
|
||||||
if fn.Pkg != nil && fn.Pkg.Object == reflectPackage {
|
if fn.Pkg != nil && fn.Pkg.Pkg == reflectPackage {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Synthetic wrappers have a nil Pkg, so they slip through the
|
// Synthetic wrappers have a nil Pkg, so they slip through the
|
||||||
|
|
|
@ -176,7 +176,7 @@ func doOneInput(input, filename string) bool {
|
||||||
|
|
||||||
// SSA creation + building.
|
// SSA creation + building.
|
||||||
prog := ssautil.CreateProgram(iprog, ssa.SanityCheckFunctions)
|
prog := ssautil.CreateProgram(iprog, ssa.SanityCheckFunctions)
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
mainpkg := prog.Package(mainPkgInfo)
|
mainpkg := prog.Package(mainPkgInfo)
|
||||||
ptrmain := mainpkg // main package for the pointer analysis
|
ptrmain := mainpkg // main package for the pointer analysis
|
||||||
|
@ -243,7 +243,7 @@ func doOneInput(input, filename string) bool {
|
||||||
for _, typstr := range split(rest, "|") {
|
for _, typstr := range split(rest, "|") {
|
||||||
var t types.Type = types.Typ[types.Invalid] // means "..."
|
var t types.Type = types.Typ[types.Invalid] // means "..."
|
||||||
if typstr != "..." {
|
if typstr != "..." {
|
||||||
tv, err := types.Eval(prog.Fset, mainpkg.Object, f.Pos(), typstr)
|
tv, err := types.Eval(prog.Fset, mainpkg.Pkg, f.Pos(), typstr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ok = false
|
ok = false
|
||||||
// Don't print err since its location is bad.
|
// Don't print err since its location is bad.
|
||||||
|
|
|
@ -1879,7 +1879,7 @@ func (c *rtypeMethodByNameConstraint) solve(a *analysis, delta *nodeset) {
|
||||||
if isIface {
|
if isIface {
|
||||||
sig = sel.Type().(*types.Signature)
|
sig = sel.Type().(*types.Signature)
|
||||||
} else {
|
} else {
|
||||||
fn = a.prog.Method(sel)
|
fn = a.prog.MethodValue(sel)
|
||||||
// move receiver to params[0]
|
// move receiver to params[0]
|
||||||
sig = changeRecv(fn.Signature)
|
sig = changeRecv(fn.Signature)
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ func TestStdlib(t *testing.T) {
|
||||||
|
|
||||||
// Create SSA packages.
|
// Create SSA packages.
|
||||||
prog := ssautil.CreateProgram(iprog, 0)
|
prog := ssautil.CreateProgram(iprog, 0)
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
numPkgs := len(prog.AllPackages())
|
numPkgs := len(prog.AllPackages())
|
||||||
if want := 240; numPkgs < want {
|
if want := 240; numPkgs < want {
|
||||||
|
|
|
@ -2217,9 +2217,7 @@ func (b *builder) buildFuncDecl(pkg *Package, decl *ast.FuncDecl) {
|
||||||
//
|
//
|
||||||
// BuildAll is idempotent and thread-safe.
|
// BuildAll is idempotent and thread-safe.
|
||||||
//
|
//
|
||||||
// TODO(adonovan): rename to Build.
|
func (prog *Program) Build() {
|
||||||
//
|
|
||||||
func (prog *Program) BuildAll() {
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for _, p := range prog.packages {
|
for _, p := range prog.packages {
|
||||||
if prog.mode&BuildSerially != 0 {
|
if prog.mode&BuildSerially != 0 {
|
||||||
|
@ -2281,10 +2279,10 @@ func (p *Package) Build() {
|
||||||
emitStore(init, initguard, vTrue, token.NoPos)
|
emitStore(init, initguard, vTrue, token.NoPos)
|
||||||
|
|
||||||
// Call the init() function of each package we import.
|
// Call the init() function of each package we import.
|
||||||
for _, pkg := range p.Object.Imports() {
|
for _, pkg := range p.Pkg.Imports() {
|
||||||
prereq := p.Prog.packages[pkg]
|
prereq := p.Prog.packages[pkg]
|
||||||
if prereq == nil {
|
if prereq == nil {
|
||||||
panic(fmt.Sprintf("Package(%q).Build(): unsatisfied import: Program.CreatePackage(%q) was not called", p.Object.Path(), pkg.Path()))
|
panic(fmt.Sprintf("Package(%q).Build(): unsatisfied import: Program.CreatePackage(%q) was not called", p.Pkg.Path(), pkg.Path()))
|
||||||
}
|
}
|
||||||
var v Call
|
var v Call
|
||||||
v.Call.Value = prereq.init
|
v.Call.Value = prereq.init
|
||||||
|
|
|
@ -112,7 +112,7 @@ func main() {
|
||||||
}
|
}
|
||||||
mset := prog.MethodSets.MethodSet(types.NewPointer(mem.Type()))
|
mset := prog.MethodSets.MethodSet(types.NewPointer(mem.Type()))
|
||||||
for i, n := 0, mset.Len(); i < n; i++ {
|
for i, n := 0, mset.Len(); i < n; i++ {
|
||||||
m := prog.Method(mset.At(i))
|
m := prog.MethodValue(mset.At(i))
|
||||||
// For external types, only synthetic wrappers have code.
|
// For external types, only synthetic wrappers have code.
|
||||||
expExt := !strings.Contains(m.Synthetic, "wrapper")
|
expExt := !strings.Contains(m.Synthetic, "wrapper")
|
||||||
if expExt && !isEmpty(m) {
|
if expExt && !isEmpty(m) {
|
||||||
|
@ -303,7 +303,7 @@ func init():
|
||||||
}
|
}
|
||||||
prog := ssautil.CreateProgram(lprog, test.mode)
|
prog := ssautil.CreateProgram(lprog, test.mode)
|
||||||
mainPkg := prog.Package(lprog.Created[0].Pkg)
|
mainPkg := prog.Package(lprog.Created[0].Pkg)
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
initFunc := mainPkg.Func("init")
|
initFunc := mainPkg.Func("init")
|
||||||
if initFunc == nil {
|
if initFunc == nil {
|
||||||
t.Errorf("test 'package %s': no init function", f.Name.Name)
|
t.Errorf("test 'package %s': no init function", f.Name.Name)
|
||||||
|
@ -374,7 +374,7 @@ var (
|
||||||
|
|
||||||
// Create and build SSA
|
// Create and build SSA
|
||||||
prog := ssautil.CreateProgram(lprog, 0)
|
prog := ssautil.CreateProgram(lprog, 0)
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
// Enumerate reachable synthetic functions
|
// Enumerate reachable synthetic functions
|
||||||
want := map[string]string{
|
want := map[string]string{
|
||||||
|
|
|
@ -162,7 +162,7 @@ func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *
|
||||||
Prog: prog,
|
Prog: prog,
|
||||||
Members: make(map[string]Member),
|
Members: make(map[string]Member),
|
||||||
values: make(map[types.Object]Value),
|
values: make(map[types.Object]Value),
|
||||||
Object: pkg,
|
Pkg: pkg,
|
||||||
info: info, // transient (CREATE and BUILD phases)
|
info: info, // transient (CREATE and BUILD phases)
|
||||||
files: files, // transient (CREATE and BUILD phases)
|
files: files, // transient (CREATE and BUILD phases)
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *
|
||||||
// GC-compiled binary package.
|
// GC-compiled binary package.
|
||||||
// No code.
|
// No code.
|
||||||
// No position information.
|
// No position information.
|
||||||
scope := p.Object.Scope()
|
scope := p.Pkg.Scope()
|
||||||
for _, name := range scope.Names() {
|
for _, name := range scope.Names() {
|
||||||
obj := scope.Lookup(name)
|
obj := scope.Lookup(name)
|
||||||
memberFromObject(p, obj, nil)
|
memberFromObject(p, obj, nil)
|
||||||
|
@ -224,9 +224,9 @@ func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *
|
||||||
}
|
}
|
||||||
|
|
||||||
if importable {
|
if importable {
|
||||||
prog.imported[p.Object.Path()] = p
|
prog.imported[p.Pkg.Path()] = p
|
||||||
}
|
}
|
||||||
prog.packages[p.Object] = p
|
prog.packages[p.Pkg] = p
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ func ExampleLoadProgram() {
|
||||||
prog := ssautil.CreateProgram(lprog, ssa.SanityCheckFunctions)
|
prog := ssautil.CreateProgram(lprog, ssa.SanityCheckFunctions)
|
||||||
|
|
||||||
// Build SSA code for the entire cmd/cover program.
|
// Build SSA code for the entire cmd/cover program.
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
}
|
}
|
||||||
|
|
|
@ -501,7 +501,7 @@ func (f *Function) RelString(from *types.Package) string {
|
||||||
|
|
||||||
// Package-level function?
|
// Package-level function?
|
||||||
// Prefix with package name for cross-package references only.
|
// Prefix with package name for cross-package references only.
|
||||||
if p := f.pkgobj(); p != nil && p != from {
|
if p := f.pkg(); p != nil && p != from {
|
||||||
return fmt.Sprintf("%s.%s", p.Path(), f.name)
|
return fmt.Sprintf("%s.%s", p.Path(), f.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,9 +529,9 @@ func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *ty
|
||||||
types.WriteSignature(buf, sig, types.RelativeTo(from))
|
types.WriteSignature(buf, sig, types.RelativeTo(from))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Function) pkgobj() *types.Package {
|
func (f *Function) pkg() *types.Package {
|
||||||
if f.Pkg != nil {
|
if f.Pkg != nil {
|
||||||
return f.Pkg.Object
|
return f.Pkg.Pkg
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -549,7 +549,7 @@ func (f *Function) WriteTo(w io.Writer) (int64, error) {
|
||||||
func WriteFunction(buf *bytes.Buffer, f *Function) {
|
func WriteFunction(buf *bytes.Buffer, f *Function) {
|
||||||
fmt.Fprintf(buf, "# Name: %s\n", f.String())
|
fmt.Fprintf(buf, "# Name: %s\n", f.String())
|
||||||
if f.Pkg != nil {
|
if f.Pkg != nil {
|
||||||
fmt.Fprintf(buf, "# Package: %s\n", f.Pkg.Object.Path())
|
fmt.Fprintf(buf, "# Package: %s\n", f.Pkg.Pkg.Path())
|
||||||
}
|
}
|
||||||
if syn := f.Synthetic; syn != "" {
|
if syn := f.Synthetic; syn != "" {
|
||||||
fmt.Fprintln(buf, "# Synthetic:", syn)
|
fmt.Fprintln(buf, "# Synthetic:", syn)
|
||||||
|
@ -566,7 +566,7 @@ func WriteFunction(buf *bytes.Buffer, f *Function) {
|
||||||
fmt.Fprintf(buf, "# Recover: %s\n", f.Recover)
|
fmt.Fprintf(buf, "# Recover: %s\n", f.Recover)
|
||||||
}
|
}
|
||||||
|
|
||||||
from := f.pkgobj()
|
from := f.pkg()
|
||||||
|
|
||||||
if f.FreeVars != nil {
|
if f.FreeVars != nil {
|
||||||
buf.WriteString("# Free variables:\n")
|
buf.WriteString("# Free variables:\n")
|
||||||
|
|
|
@ -619,7 +619,7 @@ func setGlobal(i *interpreter, pkg *ssa.Package, name string, v value) {
|
||||||
*g = v
|
*g = v
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
panic("no global variable: " + pkg.Object.Path() + "." + name)
|
panic("no global variable: " + pkg.Pkg.Path() + "." + name)
|
||||||
}
|
}
|
||||||
|
|
||||||
var environ []value
|
var environ []value
|
||||||
|
@ -687,7 +687,7 @@ func Interpret(mainpkg *ssa.Package, mode Mode, sizes types.Sizes, filename stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ad-hoc initialization for magic system variables.
|
// Ad-hoc initialization for magic system variables.
|
||||||
switch pkg.Object.Path() {
|
switch pkg.Pkg.Path() {
|
||||||
case "syscall":
|
case "syscall":
|
||||||
setGlobal(i, pkg, "envs", environ)
|
setGlobal(i, pkg, "envs", environ)
|
||||||
|
|
||||||
|
@ -695,7 +695,7 @@ func Interpret(mainpkg *ssa.Package, mode Mode, sizes types.Sizes, filename stri
|
||||||
deleteBodies(pkg, "DeepEqual", "deepValueEqual")
|
deleteBodies(pkg, "DeepEqual", "deepValueEqual")
|
||||||
|
|
||||||
case "runtime":
|
case "runtime":
|
||||||
sz := sizes.Sizeof(pkg.Object.Scope().Lookup("MemStats").Type())
|
sz := sizes.Sizeof(pkg.Pkg.Scope().Lookup("MemStats").Type())
|
||||||
setGlobal(i, pkg, "sizeof_C_MStats", uintptr(sz))
|
setGlobal(i, pkg, "sizeof_C_MStats", uintptr(sz))
|
||||||
deleteBodies(pkg, "GOROOT", "gogetenv")
|
deleteBodies(pkg, "GOROOT", "gogetenv")
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,7 +219,7 @@ func run(t *testing.T, dir, input string, success successPredicate) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
prog := ssautil.CreateProgram(iprog, ssa.SanityCheckFunctions)
|
prog := ssautil.CreateProgram(iprog, ssa.SanityCheckFunctions)
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
var mainPkg *ssa.Package
|
var mainPkg *ssa.Package
|
||||||
var initialPkgs []*ssa.Package
|
var initialPkgs []*ssa.Package
|
||||||
|
|
|
@ -520,7 +520,7 @@ func newMethod(pkg *ssa.Package, recvType types.Type, name string) *ssa.Function
|
||||||
func initReflect(i *interpreter) {
|
func initReflect(i *interpreter) {
|
||||||
i.reflectPackage = &ssa.Package{
|
i.reflectPackage = &ssa.Package{
|
||||||
Prog: i.prog,
|
Prog: i.prog,
|
||||||
Object: reflectTypesPackage,
|
Pkg: reflectTypesPackage,
|
||||||
Members: make(map[string]ssa.Member),
|
Members: make(map[string]ssa.Member),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,18 +539,18 @@ func initReflect(i *interpreter) {
|
||||||
// provide fake source files. This would guarantee that no bad
|
// provide fake source files. This would guarantee that no bad
|
||||||
// information leaks into other packages.
|
// information leaks into other packages.
|
||||||
if r := i.prog.ImportedPackage("reflect"); r != nil {
|
if r := i.prog.ImportedPackage("reflect"); r != nil {
|
||||||
rV := r.Object.Scope().Lookup("Value").Type().(*types.Named)
|
rV := r.Pkg.Scope().Lookup("Value").Type().(*types.Named)
|
||||||
|
|
||||||
// delete bodies of the old methods
|
// delete bodies of the old methods
|
||||||
mset := i.prog.MethodSets.MethodSet(rV)
|
mset := i.prog.MethodSets.MethodSet(rV)
|
||||||
for j := 0; j < mset.Len(); j++ {
|
for j := 0; j < mset.Len(); j++ {
|
||||||
i.prog.Method(mset.At(j)).Blocks = nil
|
i.prog.MethodValue(mset.At(j)).Blocks = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tEface := types.NewInterface(nil, nil).Complete()
|
tEface := types.NewInterface(nil, nil).Complete()
|
||||||
rV.SetUnderlying(types.NewStruct([]*types.Var{
|
rV.SetUnderlying(types.NewStruct([]*types.Var{
|
||||||
types.NewField(token.NoPos, r.Object, "t", tEface, false), // a lie
|
types.NewField(token.NoPos, r.Pkg, "t", tEface, false), // a lie
|
||||||
types.NewField(token.NoPos, r.Object, "v", tEface, false),
|
types.NewField(token.NoPos, r.Pkg, "v", tEface, false),
|
||||||
}, nil))
|
}, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,17 @@ import (
|
||||||
"golang.org/x/tools/go/types"
|
"golang.org/x/tools/go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Method returns the Function implementing method sel, building
|
// MethodValue returns the Function implementing method sel, building
|
||||||
// wrapper methods on demand. It returns nil if sel denotes an
|
// wrapper methods on demand. It returns nil if sel denotes an
|
||||||
// abstract (interface) method.
|
// abstract (interface) method.
|
||||||
//
|
//
|
||||||
// Precondition: sel.Kind() == MethodVal.
|
// Precondition: sel.Kind() == MethodVal.
|
||||||
//
|
//
|
||||||
// TODO(adonovan): rename this to MethodValue because of the
|
|
||||||
// precondition, and for consistency with functions in source.go.
|
|
||||||
//
|
|
||||||
// Thread-safe.
|
// Thread-safe.
|
||||||
//
|
//
|
||||||
// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu)
|
// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu)
|
||||||
//
|
//
|
||||||
func (prog *Program) Method(sel *types.Selection) *Function {
|
func (prog *Program) MethodValue(sel *types.Selection) *Function {
|
||||||
if sel.Kind() != types.MethodVal {
|
if sel.Kind() != types.MethodVal {
|
||||||
panic(fmt.Sprintf("Method(%s) kind != MethodVal", sel))
|
panic(fmt.Sprintf("Method(%s) kind != MethodVal", sel))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +49,7 @@ func (prog *Program) LookupMethod(T types.Type, pkg *types.Package, name string)
|
||||||
if sel == nil {
|
if sel == nil {
|
||||||
panic(fmt.Sprintf("%s has no method %s", T, types.Id(pkg, name)))
|
panic(fmt.Sprintf("%s has no method %s", T, types.Id(pkg, name)))
|
||||||
}
|
}
|
||||||
return prog.Method(sel)
|
return prog.MethodValue(sel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// methodSet contains the (concrete) methods of a non-interface type.
|
// methodSet contains the (concrete) methods of a non-interface type.
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
func relName(v Value, i Instruction) string {
|
func relName(v Value, i Instruction) string {
|
||||||
var from *types.Package
|
var from *types.Package
|
||||||
if i != nil {
|
if i != nil {
|
||||||
from = i.Parent().pkgobj()
|
from = i.Parent().pkg()
|
||||||
}
|
}
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case Member: // *Function or *Global
|
case Member: // *Function or *Global
|
||||||
|
@ -45,8 +45,8 @@ func relType(t types.Type, from *types.Package) string {
|
||||||
func relString(m Member, from *types.Package) string {
|
func relString(m Member, from *types.Package) string {
|
||||||
// NB: not all globals have an Object (e.g. init$guard),
|
// NB: not all globals have an Object (e.g. init$guard),
|
||||||
// so use Package().Object not Object.Package().
|
// so use Package().Object not Object.Package().
|
||||||
if obj := m.Package().Object; obj != nil && obj != from {
|
if pkg := m.Package().Pkg; pkg != nil && pkg != from {
|
||||||
return fmt.Sprintf("%s.%s", obj.Path(), m.Name())
|
return fmt.Sprintf("%s.%s", pkg.Path(), m.Name())
|
||||||
}
|
}
|
||||||
return m.Name()
|
return m.Name()
|
||||||
}
|
}
|
||||||
|
@ -57,12 +57,12 @@ func relString(m Member, from *types.Package) string {
|
||||||
// It never appears in disassembly, which uses Value.Name().
|
// It never appears in disassembly, which uses Value.Name().
|
||||||
|
|
||||||
func (v *Parameter) String() string {
|
func (v *Parameter) String() string {
|
||||||
from := v.Parent().pkgobj()
|
from := v.Parent().pkg()
|
||||||
return fmt.Sprintf("parameter %s : %s", v.Name(), relType(v.Type(), from))
|
return fmt.Sprintf("parameter %s : %s", v.Name(), relType(v.Type(), from))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *FreeVar) String() string {
|
func (v *FreeVar) String() string {
|
||||||
from := v.Parent().pkgobj()
|
from := v.Parent().pkg()
|
||||||
return fmt.Sprintf("freevar %s : %s", v.Name(), relType(v.Type(), from))
|
return fmt.Sprintf("freevar %s : %s", v.Name(), relType(v.Type(), from))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ func (v *Alloc) String() string {
|
||||||
if v.Heap {
|
if v.Heap {
|
||||||
op = "new"
|
op = "new"
|
||||||
}
|
}
|
||||||
from := v.Parent().pkgobj()
|
from := v.Parent().pkg()
|
||||||
return fmt.Sprintf("%s %s (%s)", op, relType(deref(v.Type()), from), v.Comment)
|
return fmt.Sprintf("%s %s (%s)", op, relType(deref(v.Type()), from), v.Comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ func (v *UnOp) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func printConv(prefix string, v, x Value) string {
|
func printConv(prefix string, v, x Value) string {
|
||||||
from := v.Parent().pkgobj()
|
from := v.Parent().pkg()
|
||||||
return fmt.Sprintf("%s %s <- %s (%s)",
|
return fmt.Sprintf("%s %s <- %s (%s)",
|
||||||
prefix,
|
prefix,
|
||||||
relType(v.Type(), from),
|
relType(v.Type(), from),
|
||||||
|
@ -177,7 +177,7 @@ func (v *MakeClosure) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MakeSlice) String() string {
|
func (v *MakeSlice) String() string {
|
||||||
from := v.Parent().pkgobj()
|
from := v.Parent().pkg()
|
||||||
return fmt.Sprintf("make %s %s %s",
|
return fmt.Sprintf("make %s %s %s",
|
||||||
relType(v.Type(), from),
|
relType(v.Type(), from),
|
||||||
relName(v.Len, v),
|
relName(v.Len, v),
|
||||||
|
@ -209,12 +209,12 @@ func (v *MakeMap) String() string {
|
||||||
if v.Reserve != nil {
|
if v.Reserve != nil {
|
||||||
res = relName(v.Reserve, v)
|
res = relName(v.Reserve, v)
|
||||||
}
|
}
|
||||||
from := v.Parent().pkgobj()
|
from := v.Parent().pkg()
|
||||||
return fmt.Sprintf("make %s %s", relType(v.Type(), from), res)
|
return fmt.Sprintf("make %s %s", relType(v.Type(), from), res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MakeChan) String() string {
|
func (v *MakeChan) String() string {
|
||||||
from := v.Parent().pkgobj()
|
from := v.Parent().pkg()
|
||||||
return fmt.Sprintf("make %s %s", relType(v.Type(), from), relName(v.Size, v))
|
return fmt.Sprintf("make %s %s", relType(v.Type(), from), relName(v.Size, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ func (v *Next) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *TypeAssert) String() string {
|
func (v *TypeAssert) String() string {
|
||||||
from := v.Parent().pkgobj()
|
from := v.Parent().pkg()
|
||||||
return fmt.Sprintf("typeassert%s %s.(%s)", commaOk(v.CommaOk), relName(v.X, v), relType(v.AssertedType, from))
|
return fmt.Sprintf("typeassert%s %s.(%s)", commaOk(v.CommaOk), relName(v.X, v), relType(v.AssertedType, from))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ func (s *DebugRef) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Package) String() string {
|
func (p *Package) String() string {
|
||||||
return "package " + p.Object.Path()
|
return "package " + p.Pkg.Path()
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ io.WriterTo = (*Package)(nil) // *Package implements io.Writer
|
var _ io.WriterTo = (*Package)(nil) // *Package implements io.Writer
|
||||||
|
@ -391,7 +391,7 @@ func WritePackage(buf *bytes.Buffer, p *Package) {
|
||||||
names = append(names, name)
|
names = append(names, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
from := p.Object
|
from := p.Pkg
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
switch mem := p.Members[name].(type) {
|
switch mem := p.Members[name].(type) {
|
||||||
|
|
|
@ -408,7 +408,7 @@ func (s *sanity) checkFunction(fn *Function) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn.String() // must not crash
|
fn.String() // must not crash
|
||||||
fn.RelString(fn.pkgobj()) // must not crash
|
fn.RelString(fn.pkg()) // must not crash
|
||||||
|
|
||||||
// All functions have a package, except delegates (which are
|
// All functions have a package, except delegates (which are
|
||||||
// shared across packages, or duplicated as weak symbols in a
|
// shared across packages, or duplicated as weak symbols in a
|
||||||
|
@ -484,7 +484,7 @@ func (s *sanity) checkFunction(fn *Function) bool {
|
||||||
// It does not require that the package is built.
|
// It does not require that the package is built.
|
||||||
// Unlike sanityCheck (for functions), it just panics at the first error.
|
// Unlike sanityCheck (for functions), it just panics at the first error.
|
||||||
func sanityCheckPackage(pkg *Package) {
|
func sanityCheckPackage(pkg *Package) {
|
||||||
if pkg.Object == nil {
|
if pkg.Pkg == nil {
|
||||||
panic(fmt.Sprintf("Package %s has no Object", pkg))
|
panic(fmt.Sprintf("Package %s has no Object", pkg))
|
||||||
}
|
}
|
||||||
pkg.String() // must not crash
|
pkg.String() // must not crash
|
||||||
|
@ -492,7 +492,7 @@ func sanityCheckPackage(pkg *Package) {
|
||||||
for name, mem := range pkg.Members {
|
for name, mem := range pkg.Members {
|
||||||
if name != mem.Name() {
|
if name != mem.Name() {
|
||||||
panic(fmt.Sprintf("%s: %T.Name() = %s, want %s",
|
panic(fmt.Sprintf("%s: %T.Name() = %s, want %s",
|
||||||
pkg.Object.Path(), mem, mem.Name(), name))
|
pkg.Pkg.Path(), mem, mem.Name(), name))
|
||||||
}
|
}
|
||||||
obj := mem.Object()
|
obj := mem.Object()
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
|
@ -510,7 +510,7 @@ func sanityCheckPackage(pkg *Package) {
|
||||||
// its types.Func ("init") and its ssa.Function ("init#%d").
|
// its types.Func ("init") and its ssa.Function ("init#%d").
|
||||||
} else {
|
} else {
|
||||||
panic(fmt.Sprintf("%s: %T.Object().Name() = %s, want %s",
|
panic(fmt.Sprintf("%s: %T.Object().Name() = %s, want %s",
|
||||||
pkg.Object.Path(), mem, obj.Name(), name))
|
pkg.Pkg.Path(), mem, obj.Name(), name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if obj.Pos() != mem.Pos() {
|
if obj.Pos() != mem.Pos() {
|
||||||
|
|
|
@ -45,7 +45,7 @@ type Program struct {
|
||||||
//
|
//
|
||||||
type Package struct {
|
type Package struct {
|
||||||
Prog *Program // the owning program
|
Prog *Program // the owning program
|
||||||
Object *types.Package // the type checker's package object for this package
|
Pkg *types.Package // the corresponding go/types.Package
|
||||||
Members map[string]Member // all package members keyed by name (incl. init and init#%d)
|
Members map[string]Member // all package members keyed by name (incl. init and init#%d)
|
||||||
values map[types.Object]Value // package members (incl. types and methods), keyed by object
|
values map[types.Object]Value // package members (incl. types and methods), keyed by object
|
||||||
init *Function // Func("init"); the package's init function
|
init *Function // Func("init"); the package's init function
|
||||||
|
|
|
@ -44,7 +44,7 @@ func (visit *visitor) program() {
|
||||||
for _, T := range visit.prog.RuntimeTypes() {
|
for _, T := range visit.prog.RuntimeTypes() {
|
||||||
mset := visit.prog.MethodSets.MethodSet(T)
|
mset := visit.prog.MethodSets.MethodSet(T)
|
||||||
for i, n := 0, mset.Len(); i < n; i++ {
|
for i, n := 0, mset.Len(); i < n; i++ {
|
||||||
visit.function(visit.prog.Method(mset.At(i)))
|
visit.function(visit.prog.MethodValue(mset.At(i)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ func TestStdlib(t *testing.T) {
|
||||||
t2 := time.Now()
|
t2 := time.Now()
|
||||||
|
|
||||||
// Build SSA.
|
// Build SSA.
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
t3 := time.Now()
|
t3 := time.Now()
|
||||||
alloc3 := bytesAllocated()
|
alloc3 := bytesAllocated()
|
||||||
|
|
|
@ -102,7 +102,7 @@ func (prog *Program) CreateTestMainPackage(pkgs ...*Package) *Package {
|
||||||
Prog: prog,
|
Prog: prog,
|
||||||
Members: make(map[string]Member),
|
Members: make(map[string]Member),
|
||||||
values: make(map[types.Object]Value),
|
values: make(map[types.Object]Value),
|
||||||
Object: types.NewPackage("test$main", "main"),
|
Pkg: types.NewPackage("test$main", "main"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build package's init function.
|
// Build package's init function.
|
||||||
|
@ -127,23 +127,23 @@ func (prog *Program) CreateTestMainPackage(pkgs ...*Package) *Package {
|
||||||
v.setType(types.NewTuple())
|
v.setType(types.NewTuple())
|
||||||
init.emit(&v)
|
init.emit(&v)
|
||||||
|
|
||||||
pkgpaths = append(pkgpaths, pkg.Object.Path())
|
pkgpaths = append(pkgpaths, pkg.Pkg.Path())
|
||||||
}
|
}
|
||||||
sort.Strings(pkgpaths)
|
sort.Strings(pkgpaths)
|
||||||
init.emit(new(Return))
|
init.emit(new(Return))
|
||||||
init.finishBody()
|
init.finishBody()
|
||||||
testmain.init = init
|
testmain.init = init
|
||||||
testmain.Object.MarkComplete()
|
testmain.Pkg.MarkComplete()
|
||||||
testmain.Members[init.name] = init
|
testmain.Members[init.name] = init
|
||||||
|
|
||||||
// For debugging convenience, define an unexported const
|
// For debugging convenience, define an unexported const
|
||||||
// that enumerates the packages.
|
// that enumerates the packages.
|
||||||
packagesConst := types.NewConst(token.NoPos, testmain.Object, "packages", tString,
|
packagesConst := types.NewConst(token.NoPos, testmain.Pkg, "packages", tString,
|
||||||
exact.MakeString(strings.Join(pkgpaths, " ")))
|
exact.MakeString(strings.Join(pkgpaths, " ")))
|
||||||
memberFromObject(testmain, packagesConst, nil)
|
memberFromObject(testmain, packagesConst, nil)
|
||||||
|
|
||||||
// Create main *types.Func and *ssa.Function
|
// Create main *types.Func and *ssa.Function
|
||||||
mainFunc := types.NewFunc(token.NoPos, testmain.Object, "main", new(types.Signature))
|
mainFunc := types.NewFunc(token.NoPos, testmain.Pkg, "main", new(types.Signature))
|
||||||
memberFromObject(testmain, mainFunc, nil)
|
memberFromObject(testmain, mainFunc, nil)
|
||||||
main := testmain.Func("main")
|
main := testmain.Func("main")
|
||||||
main.Synthetic = "test main function"
|
main.Synthetic = "test main function"
|
||||||
|
@ -222,7 +222,7 @@ func (prog *Program) CreateTestMainPackage(pkgs ...*Package) *Package {
|
||||||
sanityCheckPackage(testmain)
|
sanityCheckPackage(testmain)
|
||||||
}
|
}
|
||||||
|
|
||||||
prog.packages[testmain.Object] = testmain
|
prog.packages[testmain.Pkg] = testmain
|
||||||
|
|
||||||
return testmain
|
return testmain
|
||||||
}
|
}
|
||||||
|
|
|
@ -405,7 +405,7 @@ func Run(pta bool, result *Result) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, pkg := range allPackages {
|
for _, pkg := range allPackages {
|
||||||
if pkg.Object.Name() == "main" && pkg.Func("main") != nil {
|
if pkg.Pkg.Name() == "main" && pkg.Func("main") != nil {
|
||||||
mainPkgs = append(mainPkgs, pkg)
|
mainPkgs = append(mainPkgs, pkg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,7 +413,7 @@ func Run(pta bool, result *Result) {
|
||||||
|
|
||||||
// Build SSA code for bodies of all functions in the whole program.
|
// Build SSA code for bodies of all functions in the whole program.
|
||||||
result.setStatusf("Constructing SSA form...")
|
result.setStatusf("Constructing SSA form...")
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
log.Print("SSA construction complete")
|
log.Print("SSA construction complete")
|
||||||
|
|
||||||
a := analysis{
|
a := analysis{
|
||||||
|
|
|
@ -104,7 +104,7 @@ func (a *analysis) doCallgraph(cg *callgraph.Graph) {
|
||||||
|
|
||||||
var this *types.Package // for relativizing names
|
var this *types.Package // for relativizing names
|
||||||
if callee.Pkg != nil {
|
if callee.Pkg != nil {
|
||||||
this = callee.Pkg.Object
|
this = callee.Pkg.Pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute sites grouped by parent, with text and URLs.
|
// Compute sites grouped by parent, with text and URLs.
|
||||||
|
@ -169,14 +169,14 @@ func (a *analysis) doCallgraph(cg *callgraph.Graph) {
|
||||||
roots := &pcg.nodes[0].edges
|
roots := &pcg.nodes[0].edges
|
||||||
roots.SetBit(roots, i, 1)
|
roots.SetBit(roots, i, 1)
|
||||||
}
|
}
|
||||||
index[n.fn.RelString(pkg.Object)] = i
|
index[n.fn.RelString(pkg.Pkg)] = i
|
||||||
}
|
}
|
||||||
|
|
||||||
json := a.pcgJSON(pcg)
|
json := a.pcgJSON(pcg)
|
||||||
|
|
||||||
// TODO(adonovan): pkg.Path() is not unique!
|
// TODO(adonovan): pkg.Path() is not unique!
|
||||||
// It is possible to declare a non-test package called x_test.
|
// It is possible to declare a non-test package called x_test.
|
||||||
a.result.pkgInfo(pkg.Object.Path()).setCallGraph(json, index)
|
a.result.pkgInfo(pkg.Pkg.Path()).setCallGraph(json, index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ func (a *analysis) addCallees(site ssa.CallInstruction, fns []*ssa.Function) {
|
||||||
}
|
}
|
||||||
var this *types.Package // for relativizing names
|
var this *types.Package // for relativizing names
|
||||||
if p := site.Parent().Package(); p != nil {
|
if p := site.Parent().Package(); p != nil {
|
||||||
this = p.Object
|
this = p.Pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fn := range fns {
|
for _, fn := range fns {
|
||||||
|
@ -242,10 +242,10 @@ func prettyFunc(this *types.Package, fn *ssa.Function) string {
|
||||||
}
|
}
|
||||||
if fn.Synthetic != "" && fn.Name() == "init" {
|
if fn.Synthetic != "" && fn.Name() == "init" {
|
||||||
// (This is the actual initializer, not a declared 'func init').
|
// (This is the actual initializer, not a declared 'func init').
|
||||||
if fn.Pkg.Object == this {
|
if fn.Pkg.Pkg == this {
|
||||||
return "package initializer"
|
return "package initializer"
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%q package initializer", fn.Pkg.Object.Path())
|
return fmt.Sprintf("%q package initializer", fn.Pkg.Pkg.Path())
|
||||||
}
|
}
|
||||||
return fn.RelString(this)
|
return fn.RelString(this)
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ func (pcg *packageCallGraph) sortNodes() {
|
||||||
for fn := range pcg.nodeIndex {
|
for fn := range pcg.nodeIndex {
|
||||||
nodes = append(nodes, &pcgNode{
|
nodes = append(nodes, &pcgNode{
|
||||||
fn: fn,
|
fn: fn,
|
||||||
pretty: prettyFunc(fn.Pkg.Object, fn),
|
pretty: prettyFunc(fn.Pkg.Pkg, fn),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
sort.Sort(pcgNodesByPretty(nodes[1:]))
|
sort.Sort(pcgNodesByPretty(nodes[1:]))
|
||||||
|
|
|
@ -72,7 +72,7 @@ func (a *analysis) doChannelPeers(ptsets map[ssa.Value]pointer.Pointer) {
|
||||||
Href: a.posURL(makechan.Pos()-token.Pos(len("make")),
|
Href: a.posURL(makechan.Pos()-token.Pos(len("make")),
|
||||||
len("make")),
|
len("make")),
|
||||||
},
|
},
|
||||||
Fn: makechan.Parent().RelString(op.fn.Package().Object),
|
Fn: makechan.Parent().RelString(op.fn.Package().Pkg),
|
||||||
})
|
})
|
||||||
for _, op := range aliasedOps[makechan] {
|
for _, op := range aliasedOps[makechan] {
|
||||||
ops[op] = true
|
ops[op] = true
|
||||||
|
|
|
@ -115,7 +115,7 @@ func callees(q *Query) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defer SSA construction till after errors are reported.
|
// Defer SSA construction till after errors are reported.
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
// Ascertain calling function and call site.
|
// Ascertain calling function and call site.
|
||||||
callerFn := ssa.EnclosingFunction(pkg, qpos.path)
|
callerFn := ssa.EnclosingFunction(pkg, qpos.path)
|
||||||
|
|
|
@ -53,7 +53,7 @@ func callers(q *Query) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defer SSA construction till after errors are reported.
|
// Defer SSA construction till after errors are reported.
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
target := ssa.EnclosingFunction(pkg, qpos.path)
|
target := ssa.EnclosingFunction(pkg, qpos.path)
|
||||||
if target == nil {
|
if target == nil {
|
||||||
|
|
|
@ -61,7 +61,7 @@ func callstack(q *Query) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defer SSA construction till after errors are reported.
|
// Defer SSA construction till after errors are reported.
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
target := ssa.EnclosingFunction(pkg, qpos.path)
|
target := ssa.EnclosingFunction(pkg, qpos.path)
|
||||||
if target == nil {
|
if target == nil {
|
||||||
|
|
|
@ -55,7 +55,7 @@ func peers(q *Query) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defer SSA construction till after errors are reported.
|
// Defer SSA construction till after errors are reported.
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
var queryOp chanOp // the originating send or receive operation
|
var queryOp chanOp // the originating send or receive operation
|
||||||
var ops []chanOp // all sends/receives of opposite direction
|
var ops []chanOp // all sends/receives of opposite direction
|
||||||
|
|
|
@ -95,7 +95,7 @@ func pointsto(q *Query) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defer SSA construction till after errors are reported.
|
// Defer SSA construction till after errors are reported.
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
// Run the pointer analysis.
|
// Run the pointer analysis.
|
||||||
ptrs, err := runPTA(ptaConfig, value, isAddr)
|
ptrs, err := runPTA(ptaConfig, value, isAddr)
|
||||||
|
|
|
@ -91,7 +91,7 @@ func whicherrs(q *Query) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defer SSA construction till after errors are reported.
|
// Defer SSA construction till after errors are reported.
|
||||||
prog.BuildAll()
|
prog.Build()
|
||||||
|
|
||||||
globals := findVisibleErrs(prog, qpos)
|
globals := findVisibleErrs(prog, qpos)
|
||||||
constants := findVisibleConsts(prog, qpos)
|
constants := findVisibleConsts(prog, qpos)
|
||||||
|
|
Loading…
Reference in New Issue