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