1
0
mirror of https://github.com/golang/go synced 2024-11-18 21:34:46 -07:00
go/ssa/example_test.go
Alan Donovan 3d82e7e94a go.tools/ssa: fix crash in SSA builder when using GCImporter to satisfy imports (ssadump -build=G).
Packages were not being created for all types.Packages,
specifically, indirectly imported packages were missing.
(*Program).CreatePackages now iterates over the type-checker's
package map too.

Also: removed all concurrency from importer.  I think it was
incorrect (and hard to fix).

Also: change LoadInitialPackages so that all named packages
are loaded from source.  This happens regardless of whether
GCImporter is used to satisfy imports.

Details:
- importer.Config.SourceImports flag determines whether to
  load all packages from *.go source.
  (Before, this was indicated by Config.Build != nil.)
- importer.Config.Build field effectively defaults to
  &go/build.Default.  A zero importer.Config is now usable.
- importer.Importer.Config field is now exported.
- LoadPackage renamed to ImportPackage since the resulting
  packages may come from GCImporter (and be incomplete).
- doImport and ImportPackage fused.

Fixes golang/go#7028

R=gri, axwalk
CC=golang-codereviews
https://golang.org/cl/48770043
2014-01-09 14:11:54 -05:00

111 lines
3.2 KiB
Go

// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ssa_test
import (
"fmt"
"go/parser"
"os"
"code.google.com/p/go.tools/importer"
"code.google.com/p/go.tools/ssa"
)
// 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 if you want a standalone tool
// with similar functionality. It is located at
// code.google.com/p/go.tools/cmd/ssadump.
//
func Example() {
const hello = `
package main
import "fmt"
const message = "Hello, World!"
func main() {
fmt.Println(message)
}
`
// Construct an importer.
imp := importer.New(&importer.Config{})
// Parse the input file.
file, err := parser.ParseFile(imp.Fset, "hello.go", hello, 0)
if err != nil {
fmt.Print(err) // parse error
return
}
// Create single-file main package and import its dependencies.
mainInfo := imp.CreatePackage("main", file)
// Create SSA-form program representation.
var mode ssa.BuilderMode
prog := ssa.NewProgram(imp.Fset, mode)
if err := prog.CreatePackages(imp); err != nil {
fmt.Print(err) // type error in some package
return
}
mainPkg := prog.Package(mainInfo.Pkg)
// Print out the package.
mainPkg.DumpTo(os.Stdout)
// 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
// # Package: main
// # 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
// return
//
// # Name: main.main
// # Package: main
// # Location: hello.go:8:6
// func main():
// .0.entry: P:0 S:0
// t0 = new [1]interface{} (varargs) *[1]interface{}
// t1 = &t0[0:int] *interface{}
// t2 = make interface{} <- string ("Hello, World!":string) interface{}
// *t1 = t2
// t3 = slice t0[:] []interface{}
// t4 = fmt.Println(t3...) (n int, err error)
// return
}