+++ /dev/null
-// 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.
-
-// irdump: a tool for displaying the IR form of Go programs.
-package main
-
-import (
- "flag"
- "fmt"
- "go/build"
- "os"
- "runtime/pprof"
-
- "golang.org/x/tools/go/buildutil"
- "golang.org/x/tools/go/packages"
- "honnef.co/go/tools/ir"
- "honnef.co/go/tools/ir/irutil"
-)
-
-// flags
-var (
- mode = ir.BuilderMode(ir.PrintPackages | ir.PrintFunctions)
- testFlag = flag.Bool("test", false, "include implicit test packages and executables")
- cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
- dot bool
- html string
-)
-
-func init() {
- flag.Var(&mode, "build", ir.BuilderModeDoc)
- flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
- flag.BoolVar(&dot, "dot", false, "Print Graphviz dot of CFG")
- flag.StringVar(&html, "html", "", "Print HTML for 'function'")
-}
-
-const usage = `IR builder.
-Usage: irdump [-build=[DBCSNFL]] [-test] [-arg=...] package...
-Use -help flag to display options.
-
-Examples:
-% irdump -build=F hello.go # dump IR form of a single package
-% irdump -build=F -test fmt # dump IR form of a package and its tests
-`
-
-func main() {
- if err := doMain(); err != nil {
- fmt.Fprintf(os.Stderr, "irdump: %s\n", err)
- os.Exit(1)
- }
-}
-
-func doMain() error {
- flag.Parse()
- if len(flag.Args()) == 0 {
- fmt.Fprint(os.Stderr, usage)
- os.Exit(1)
- }
-
- cfg := &packages.Config{
- Mode: packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedImports | packages.NeedDeps | packages.NeedTypes | packages.NeedTypesSizes | packages.NeedSyntax | packages.NeedTypesInfo,
- Tests: *testFlag,
- }
-
- // Profiling support.
- if *cpuprofile != "" {
- f, err := os.Create(*cpuprofile)
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- pprof.StartCPUProfile(f)
- defer pprof.StopCPUProfile()
- }
-
- // Load, parse and type-check the initial packages.
- initial, err := packages.Load(cfg, flag.Args()...)
- if err != nil {
- return err
- }
- if len(initial) == 0 {
- return fmt.Errorf("no packages")
- }
- if packages.PrintErrors(initial) > 0 {
- return fmt.Errorf("packages contain errors")
- }
-
- // Create IR-form program representation.
- _, pkgs := irutil.Packages(initial, mode, &irutil.Options{PrintFunc: html})
-
- for i, p := range pkgs {
- if p == nil {
- return fmt.Errorf("cannot build IR for package %s", initial[i])
- }
- }
-
- // Build and display only the initial packages
- // (and synthetic wrappers).
- for _, p := range pkgs {
- p.Build()
- }
-
- if dot {
- for _, p := range pkgs {
- for _, m := range p.Members {
- if fn, ok := m.(*ir.Function); ok {
- fmt.Println("digraph{")
- fmt.Printf("label = %q;\n", fn.Name())
- for _, b := range fn.Blocks {
- fmt.Printf("n%d [label=\"%d: %s\"]\n", b.Index, b.Index, b.Comment)
- for _, succ := range b.Succs {
- fmt.Printf("n%d -> n%d\n", b.Index, succ.Index)
- }
- }
- fmt.Println("}")
- }
- }
- }
- }
- return nil
-}