.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.1.1 / internal / cmd / irdump / main.go
1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // irdump: a tool for displaying the IR form of Go programs.
6 package main
7
8 import (
9         "flag"
10         "fmt"
11         "go/build"
12         "os"
13         "runtime/pprof"
14
15         "honnef.co/go/tools/go/ir"
16         "honnef.co/go/tools/go/ir/irutil"
17
18         "golang.org/x/tools/go/buildutil"
19         "golang.org/x/tools/go/packages"
20 )
21
22 // flags
23 var (
24         mode       = ir.BuilderMode(ir.PrintPackages | ir.PrintFunctions)
25         testFlag   = flag.Bool("test", false, "include implicit test packages and executables")
26         cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
27         dot        bool
28         html       string
29 )
30
31 func init() {
32         flag.Var(&mode, "build", ir.BuilderModeDoc)
33         flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
34         flag.BoolVar(&dot, "dot", false, "Print Graphviz dot of CFG")
35         flag.StringVar(&html, "html", "", "Print HTML for 'function'")
36 }
37
38 const usage = `IR builder.
39 Usage: irdump [-build=[DBCSNFL]] [-test] [-arg=...] package...
40 Use -help flag to display options.
41
42 Examples:
43 % irdump -build=F hello.go              # dump IR form of a single package
44 % irdump -build=F -test fmt             # dump IR form of a package and its tests
45 `
46
47 func main() {
48         if err := doMain(); err != nil {
49                 fmt.Fprintf(os.Stderr, "irdump: %s\n", err)
50                 os.Exit(1)
51         }
52 }
53
54 func doMain() error {
55         flag.Parse()
56         if len(flag.Args()) == 0 {
57                 fmt.Fprint(os.Stderr, usage)
58                 os.Exit(1)
59         }
60
61         cfg := &packages.Config{
62                 Mode:  packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedImports | packages.NeedDeps | packages.NeedTypes | packages.NeedTypesSizes | packages.NeedSyntax | packages.NeedTypesInfo,
63                 Tests: *testFlag,
64         }
65
66         // Profiling support.
67         if *cpuprofile != "" {
68                 f, err := os.Create(*cpuprofile)
69                 if err != nil {
70                         fmt.Fprintln(os.Stderr, err)
71                         os.Exit(1)
72                 }
73                 pprof.StartCPUProfile(f)
74                 defer pprof.StopCPUProfile()
75         }
76
77         // Load, parse and type-check the initial packages.
78         initial, err := packages.Load(cfg, flag.Args()...)
79         if err != nil {
80                 return err
81         }
82         if len(initial) == 0 {
83                 return fmt.Errorf("no packages")
84         }
85         if packages.PrintErrors(initial) > 0 {
86                 return fmt.Errorf("packages contain errors")
87         }
88
89         // Create IR-form program representation.
90         _, pkgs := irutil.Packages(initial, mode, &irutil.Options{PrintFunc: html})
91
92         for i, p := range pkgs {
93                 if p == nil {
94                         return fmt.Errorf("cannot build IR for package %s", initial[i])
95                 }
96         }
97
98         // Build and display only the initial packages
99         // (and synthetic wrappers).
100         for _, p := range pkgs {
101                 p.Build()
102         }
103
104         if dot {
105                 for _, p := range pkgs {
106                         for _, m := range p.Members {
107                                 if fn, ok := m.(*ir.Function); ok {
108                                         fmt.Println("digraph{")
109                                         fmt.Printf("label = %q;\n", fn.Name())
110                                         for _, b := range fn.Blocks {
111                                                 fmt.Printf("n%d [label=\"%d: %s\"]\n", b.Index, b.Index, b.Comment)
112                                                 for _, succ := range b.Succs {
113                                                         fmt.Printf("n%d -> n%d\n", b.Index, succ.Index)
114                                                 }
115                                         }
116                                         fmt.Println("}")
117                                 }
118                         }
119                 }
120         }
121         return nil
122 }