GoPLS Viewer

Home|gopls/go/analysis/passes/buildssa/buildssa.go
1// Copyright 2018 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// Package buildssa defines an Analyzer that constructs the SSA
6// representation of an error-free package and returns the set of all
7// functions within it. It does not report any diagnostics itself but
8// may be used as an input to other analyzers.
9//
10// THIS INTERFACE IS EXPERIMENTAL AND MAY BE SUBJECT TO INCOMPATIBLE CHANGE.
11package buildssa
12
13import (
14    "go/ast"
15    "go/types"
16    "reflect"
17
18    "golang.org/x/tools/go/analysis"
19    "golang.org/x/tools/go/ssa"
20)
21
22var Analyzer = &analysis.Analyzer{
23    Name:       "buildssa",
24    Doc:        "build SSA-form IR for later passes",
25    Run:        run,
26    ResultTypereflect.TypeOf(new(SSA)),
27}
28
29// SSA provides SSA-form intermediate representation for all the
30// non-blank source functions in the current package.
31type SSA struct {
32    Pkg      *ssa.Package
33    SrcFuncs []*ssa.Function
34}
35
36func run(pass *analysis.Pass) (interface{}, error) {
37    // Plundered from ssautil.BuildPackage.
38
39    // We must create a new Program for each Package because the
40    // analysis API provides no place to hang a Program shared by
41    // all Packages. Consequently, SSA Packages and Functions do not
42    // have a canonical representation across an analysis session of
43    // multiple packages. This is unlikely to be a problem in
44    // practice because the analysis API essentially forces all
45    // packages to be analysed independently, so any given call to
46    // Analysis.Run on a package will see only SSA objects belonging
47    // to a single Program.
48
49    // Some Analyzers may need GlobalDebug, in which case we'll have
50    // to set it globally, but let's wait till we need it.
51    mode := ssa.BuilderMode(0)
52
53    prog := ssa.NewProgram(pass.Fsetmode)
54
55    // Create SSA packages for all imports.
56    // Order is not significant.
57    created := make(map[*types.Package]bool)
58    var createAll func(pkgs []*types.Package)
59    createAll = func(pkgs []*types.Package) {
60        for _p := range pkgs {
61            if !created[p] {
62                created[p] = true
63                prog.CreatePackage(pnilniltrue)
64                createAll(p.Imports())
65            }
66        }
67    }
68    createAll(pass.Pkg.Imports())
69
70    // Create and build the primary package.
71    ssapkg := prog.CreatePackage(pass.Pkgpass.Filespass.TypesInfofalse)
72    ssapkg.Build()
73
74    // Compute list of source functions, including literals,
75    // in source order.
76    var funcs []*ssa.Function
77    for _f := range pass.Files {
78        for _decl := range f.Decls {
79            if fdeclok := decl.(*ast.FuncDecl); ok {
80
81                // SSA will not build a Function
82                // for a FuncDecl named blank.
83                // That's arguably too strict but
84                // relaxing it would break uniqueness of
85                // names of package members.
86                if fdecl.Name.Name == "_" {
87                    continue
88                }
89
90                // (init functions have distinct Func
91                // objects named "init" and distinct
92                // ssa.Functions named "init#1", ...)
93
94                fn := pass.TypesInfo.Defs[fdecl.Name].(*types.Func)
95                if fn == nil {
96                    panic(fn)
97                }
98
99                f := ssapkg.Prog.FuncValue(fn)
100                if f == nil {
101                    panic(fn)
102                }
103
104                var addAnons func(f *ssa.Function)
105                addAnons = func(f *ssa.Function) {
106                    funcs = append(funcsf)
107                    for _anon := range f.AnonFuncs {
108                        addAnons(anon)
109                    }
110                }
111                addAnons(f)
112            }
113        }
114    }
115
116    return &SSA{PkgssapkgSrcFuncsfuncs}, nil
117}
118
MembersX
ssa
run.pass
run.prog
run.ssapkg
run.funcs
run.RangeStmt_2422.f
types
analysis
run.RangeStmt_2422.BlockStmt.RangeStmt_2455.decl
run.RangeStmt_2422.BlockStmt.RangeStmt_2455.BlockStmt.BlockStmt.BlockStmt.RangeStmt_3185.anon
run
run.created
SSA
SSA.Pkg
run.mode
reflect
SSA.SrcFuncs
run.RangeStmt_2422.BlockStmt.RangeStmt_2455.BlockStmt.BlockStmt.f
ast
run.BlockStmt.RangeStmt_2001.p
Members
X