1
0
mirror of https://github.com/golang/go synced 2024-10-01 13:08:32 -06:00
go/ssa/example_test.go
Alan Donovan 5cc33ea5a7 go.tools/ssa: cosmetic changes to ssa.Alloc.
Remove its 'name' field and treat it just like any other
ssa.Register: it gets a temp name like "t1".

Instead, give it a comment field holding its purpose, e.g, "x"
for a source-level vare, or "new", "slicelit", "complit" or
"varargs".

This improves usability of tools whose UI needs to refer to a
particular allocation site.

R=gri
CC=golang-dev
https://golang.org/cl/12273043
2013-08-01 14:06:10 -04:00

108 lines
3.1 KiB
Go

package ssa_test
import (
"code.google.com/p/go.tools/importer"
"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 an importer. Imports will be loaded as if by 'go build'.
imp := importer.New(&importer.Config{Loader: importer.MakeGoBuildLoader(nil)})
// Parse the input file.
file, err := parser.ParseFile(imp.Fset, "hello.go", hello, parser.DeclarationErrors)
if err != nil {
fmt.Print(err.Error()) // parse error
return
}
// Create a "main" package containing one file.
info := imp.CreateSourcePackage("main", []*ast.File{file})
if info.Err != nil {
fmt.Print(info.Err.Error()) // type error
return
}
// Create SSA-form program representation.
var mode ssa.BuilderMode
prog := ssa.NewProgram(imp.Fset, mode)
for _, info := range imp.Packages {
prog.CreatePackage(info)
}
mainPkg := prog.Package(info.Pkg)
// Print out the package.
mainPkg.DumpTo(os.Stdout)
fmt.Println()
// Build SSA code for bodies of functions in mainPkg.
mainPkg.Build()
// Print out the package-level functions.
mainPkg.Func("init").DumpTo(os.Stdout)
mainPkg.Func("main").DumpTo(os.Stdout)
// Output:
//
// package main:
// func init func()
// var init$guard *bool
// func main func()
// const message message = "Hello, World!":untyped string
//
// # Name: main.init
// # Synthetic: package initializer
// 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
// # Location: hello.go:8:6
// func main():
// .0.entry: P:0 S:0
// t0 = new [1]interface{} (varargs) *[1]interface{}
// t1 = &t0[0:untyped integer] *interface{}
// t2 = make interface{} <- string ("Hello, World!":string) interface{}
// *t1 = t2
// t3 = slice t0[:] []interface{}
// t4 = fmt.Println(t3) (n int, err error)
// ret
}