go.tools/go/ssa: name anon funcs by their enclosing func.

Before, they were named func@line:col which made them easy to find in the source if you know the file, but hard if you don't, and it made tests fragile.

Now, they are named outer$1, outer$2, etc, which makes them
more informative in a UI since "outer" has meaning.

LGTM=crawshaw
R=crawshaw
CC=golang-codereviews
https://golang.org/cl/65630048
This commit is contained in:
Alan Donovan 2014-02-28 10:18:55 -05:00
parent c509cf123c
commit d503a640d7
11 changed files with 24 additions and 23 deletions

View File

@ -60,11 +60,11 @@ func TestEnclosingFunction(t *testing.T) {
// Function literal: // Function literal:
{`package main {`package main
func f() { println(func() { print(300) }) }`, func f() { println(func() { print(300) }) }`,
"300", "func@2.24"}, "300", "f$1"},
// Doubly nested // Doubly nested
{`package main {`package main
func f() { println(func() { print(func() { print(350) })})}`, func f() { println(func() { print(func() { print(350) })})}`,
"350", "func@2.39"}, "350", "f$1$1"},
// Implicit init for package-level var initializer. // Implicit init for package-level var initializer.
{"package main; var a = 400", "400", "main.init"}, {"package main; var a = 400", "400", "main.init"},
// No code for constants: // No code for constants:
@ -79,7 +79,7 @@ func TestEnclosingFunction(t *testing.T) {
// init() containing FuncLit. // init() containing FuncLit.
{`package main {`package main
func init() { println(func(){print(900)}) }`, func init() { println(func(){print(900)}) }`,
"900", "func@2.27"}, "900", "init$1$1"},
} }
for _, test := range tests { for _, test := range tests {
conf := loader.Config{Fset: token.NewFileSet()} conf := loader.Config{Fset: token.NewFileSet()}

View File

@ -19,7 +19,7 @@ func chan1() {
print(<-chA) // @pointsto main.incr print(<-chA) // @pointsto main.incr
print(chB) // @pointsto makechan@c1makeB:13 print(chB) // @pointsto makechan@c1makeB:13
print(<-chB) // @pointsto main.decr | func@16.9 print(<-chB) // @pointsto main.decr | chan1$1
} }
func chan2() { func chan2() {
@ -40,10 +40,10 @@ func chan2() {
print(<-chA) // @pointsto main.incr print(<-chA) // @pointsto main.incr
print(chB) // @pointsto makechan@c2makeB:13 print(chB) // @pointsto makechan@c2makeB:13
print(<-chB) // @pointsto main.decr | func@30.9 print(<-chB) // @pointsto main.decr | chan2$1
print(chAB) // @pointsto makechan@c2makeA:13 | makechan@c2makeB:13 print(chAB) // @pointsto makechan@c2makeA:13 | makechan@c2makeB:13
print(<-chAB) // @pointsto main.incr | main.decr | func@30.9 print(<-chAB) // @pointsto main.incr | main.decr | chan2$1
(<-chA)(3) (<-chA)(3)
} }
@ -59,7 +59,7 @@ func chan3() {
print(chA) // @pointsto makechan@c3makeA:13 print(chA) // @pointsto makechan@c3makeA:13
print(<-chA) // @pointsto main.incr print(<-chA) // @pointsto main.incr
print(chB) // @pointsto makechan@c3makeB:13 print(chB) // @pointsto makechan@c3makeB:13
print(<-chB) // @pointsto main.decr | func@58.9 print(<-chB) // @pointsto main.decr | chan3$1
(<-chA)(3) (<-chA)(3)
} }

View File

@ -28,9 +28,9 @@ func func1() {
print(&a) // @pointsto main.a print(&a) // @pointsto main.a
} }
// @calls main.func1 -> func@19.7 // @calls main.func1 -> func1$2
// @calls main.func1 -> func@11.7 // @calls main.func1 -> func1$1
// @calls func@19.7 -> func@11.7 // @calls func1$2 -> func1$1
func func2() { func func2() {
var x, y *int var x, y *int
@ -124,7 +124,7 @@ func func6() {
print(f()) // @pointsto main.a print(f()) // @pointsto main.a
} }
// @calls main.func6 -> func@121.7 // @calls main.func6 -> func6$1
type I interface { type I interface {
f() f()

View File

@ -468,9 +468,8 @@ func (b *builder) expr0(fn *Function, e ast.Expr) Value {
panic("non-constant BasicLit") // unreachable panic("non-constant BasicLit") // unreachable
case *ast.FuncLit: case *ast.FuncLit:
posn := fn.Prog.Fset.Position(e.Type.Func)
fn2 := &Function{ fn2 := &Function{
name: fmt.Sprintf("func@%d.%d", posn.Line, posn.Column), name: fmt.Sprintf("%s$%d", fn.Name(), 1+len(fn.AnonFuncs)),
Signature: fn.Pkg.typeOf(e.Type).Underlying().(*types.Signature), Signature: fn.Pkg.typeOf(e.Type).Underlying().(*types.Signature),
pos: e.Type.Func, pos: e.Type.Func,
Enclosing: fn, Enclosing: fn,

View File

@ -457,7 +457,9 @@ func (f *Function) emit(instr Instruction) Value {
// "(*sync.WaitGroup).Add" // a declared method // "(*sync.WaitGroup).Add" // a declared method
// "(*Return).Block" // a promotion wrapper method (intra-package ref) // "(*Return).Block" // a promotion wrapper method (intra-package ref)
// "(Instruction).Block" // an interface method wrapper (intra-package ref) // "(Instruction).Block" // an interface method wrapper (intra-package ref)
// "func@5.32" // an anonymous function // "main$1" // an anonymous function
// "init$1" // a declared init function
// "init" // the synthesized package initializer
// "bound$(*T).f" // a bound method wrapper // "bound$(*T).f" // a bound method wrapper
// //
// If from==f.Pkg, suppress package qualification. // If from==f.Pkg, suppress package qualification.

View File

@ -15,7 +15,7 @@ func f() {
for _, f := range pc { for _, f := range pc {
Func := runtime.FuncForPC(f) Func := runtime.FuncForPC(f)
name := Func.Name() name := Func.Name()
if strings.Contains(name, "func") { if strings.Contains(name, "$") || strings.Contains(name, ".func") {
name = "func" // anon funcs vary across toolchains name = "func" // anon funcs vary across toolchains
} }
file, line := Func.FileLine(0) file, line := Func.FileLine(0)

View File

@ -43,7 +43,7 @@
"pos": "testdata/src/main/callgraph-json.go:9:6" "pos": "testdata/src/main/callgraph-json.go:9:6"
}, },
{ {
"name": "func@31.8", "name": "main$1",
"pos": "testdata/src/main/callgraph-json.go:31:8" "pos": "testdata/src/main/callgraph-json.go:31:8"
} }
] ]

View File

@ -11,7 +11,7 @@ Non-numbered nodes indicate back- or cross-edges to the node whose
3 A 3 A
4 B 4 B
5 call2 5 call2
6 func@33.8 6 main$1
7 nop 7 nop
-------- @callgraph callgraph-complete -------- -------- @callgraph callgraph-complete --------
@ -30,6 +30,6 @@ Non-numbered nodes indicate back- or cross-edges to the node whose
6 main.A 6 main.A
7 main.B 7 main.B
8 main.call2 8 main.call2
9 func@33.8 9 main$1
10 main.nop 10 main.nop

View File

@ -6,7 +6,7 @@
"desc": "dynamic function call", "desc": "dynamic function call",
"callees": [ "callees": [
{ {
"name": "func@12.7", "name": "main$1",
"pos": "testdata/src/main/calls-json.go:12:7" "pos": "testdata/src/main/calls-json.go:12:7"
} }
] ]
@ -16,7 +16,7 @@
"mode": "callstack", "mode": "callstack",
"callstack": { "callstack": {
"pos": "testdata/src/main/calls-json.go:12:7", "pos": "testdata/src/main/calls-json.go:12:7",
"target": "func@12.7", "target": "main$1",
"callers": [ "callers": [
{ {
"pos": "testdata/src/main/calls-json.go:8:3", "pos": "testdata/src/main/calls-json.go:8:3",

View File

@ -35,11 +35,11 @@ main.store is called from these 2 sites:
-------- @pointsto pointsto-result-f -------- -------- @pointsto pointsto-result-f --------
this func() *int may point to these objects: this func() *int may point to these objects:
func@50.7 main$1
-------- @callees callees-main.call-f -------- -------- @callees callees-main.call-f --------
this dynamic function call dispatches to: this dynamic function call dispatches to:
func@50.7 main$1
-------- @callers callers-main.call -------- -------- @callers callers-main.call --------
main.call is called from these 2 sites: main.call is called from these 2 sites:

View File

@ -31,7 +31,7 @@ this func() may point to these objects:
-------- @pointsto ref-anon -------- -------- @pointsto ref-anon --------
this func() may point to these objects: this func() may point to these objects:
func@25.10 main$1
-------- @pointsto ref-global -------- -------- @pointsto ref-global --------
this *string may point to these objects: this *string may point to these objects: