1
0
mirror of https://github.com/golang/go synced 2024-10-01 13:18:33 -06:00
go/ssa/example_test.go
Alan Donovan 8cdf1f1cb1 go.tools/ssa: add support for bound-method closures.
Extracted Builder.findMethod function to handle
methodset/receiver logic common to
function calls (Builder.setCall) and
bound method closure creation (Builder.selector).

Capture: added explicit Name, Type fields to Capture instead
of relying on Outer field, which is now un-exported since its
only purpose is to let Builder.expr(case *ast.FuncLit) know
which values to put in the closure; it is nilled immediately
after.

Simplified Function.lookup() logic: there's no need to walk
the Outer chain each time to set Alloc.Heap=true, as it's
already set during creation of the outermost
Capture{outer:*Alloc}.

Added interp/testdata/boundmeth.go test.

Cosmetic changes:
- add support for bound method thunks to Function.FullName().
- Simplified {Literal,Global,Builtin,Function}.String()
- doc: Captures are no longer necessarily addresses.
- added yet another missing pair of "()" (go/types accessors).
- print "Synthetic" not "Declared at -" for synthetic functions.
- use '$' not center-dot in synthetic identifiers (easier to type).

R=gri
CC=golang-dev
https://golang.org/cl/9654043
2013-05-22 17:56:18 -04:00

103 lines
2.9 KiB
Go

package ssa_test
import (
"code.google.com/p/go.tools/ssa"
"fmt"
"go/ast"
"go/parser"
"os"
)
// This program demonstrates how to run the SSA builder on a "Hello,
// World!" program and shows the printed representation of packages,
// functions and instructions.
//
// Within the function listing, the name of each BasicBlock such as
// ".0.entry" is printed left-aligned, followed by the block's
// Instructions.
//
// For each instruction that defines an SSA virtual register
// (i.e. implements Value), the type of that value is shown in the
// right column.
//
// Build and run the ssadump.go program in this package if you want a
// standalone tool with similar functionality.
//
func Example() {
const hello = `
package main
import "fmt"
const message = "Hello, World!"
func main() {
fmt.Println(message)
}
`
// Construct a builder. Imports will be loaded as if by 'go build'.
builder := ssa.NewBuilder(&ssa.Context{Loader: ssa.MakeGoBuildLoader(nil)})
// Parse the input file.
file, err := parser.ParseFile(builder.Prog.Files, "hello.go", hello, parser.DeclarationErrors)
if err != nil {
fmt.Printf(err.Error()) // parse error
return
}
// Create a "main" package containing one file.
mainPkg, err := builder.CreatePackage("main", []*ast.File{file})
if err != nil {
fmt.Printf(err.Error()) // type error
return
}
// Print out the package.
mainPkg.DumpTo(os.Stdout)
fmt.Println()
// Build SSA code for bodies of functions in mainPkg.
builder.BuildPackage(mainPkg)
// Print out the package-level functions.
mainPkg.Init.DumpTo(os.Stdout)
for _, mem := range mainPkg.Members {
if fn, ok := mem.(*ssa.Function); ok {
fn.DumpTo(os.Stdout)
}
}
// Output:
//
// Package main:
// var init$guard *bool
// func main func()
// const message message = "Hello, World!":untyped string
//
// # Name: main.init
// # Synthetic
// func init():
// .0.entry: P:0 S:2
// t0 = *init$guard bool
// if t0 goto 2.init.done else 1.init.start
// .1.init.start: P:1 S:1
// *init$guard = true:bool
// t1 = fmt.init() ()
// jump 2.init.done
// .2.init.done: P:2 S:0
// ret
//
// # Name: main.main
// # Declared at hello.go:8:6
// func main():
// .0.entry: P:0 S:0
// a0 = new [1]interface{} *[1]interface{}
// t0 = &a0[0:untyped integer] *interface{}
// t1 = make interface interface{} <- string ("Hello, World!":string) interface{}
// *t0 = t1
// t2 = slice a0[:] []interface{}
// t3 = fmt.Println(t2) (n int, err error)
// ret
}