diff options
author | Alan Donovan <adonovan@google.com> | 2015-02-18 12:53:21 -0500 |
---|---|---|
committer | Alan Donovan <adonovan@google.com> | 2015-02-18 18:34:24 +0000 |
commit | 9bdc5913730054d40cef92bf4b486e92e65d1d6d (patch) | |
tree | 48e458a4138900c2bc7d0da4e5a360768cdde48a | |
parent | 10d7cacb911f0ca07f31beebe5e019da2c2b393f (diff) | |
download | tools-9bdc5913730054d40cef92bf4b486e92e65d1d6d.tar.gz |
go/ssa: standardize parsing of BuilderMode flags.
ssadump's -build=G option is now spelled -import; it was never related to ssa.
Change-Id: Ic21cd8b6990c0ffd25651c17a842a63bfa5019cf
Reviewed-on: https://go-review.googlesource.com/5172
Reviewed-by: David Crawshaw <crawshaw@golang.org>
-rw-r--r-- | cmd/ssadump/main.go | 55 | ||||
-rw-r--r-- | go/ssa/create.go | 16 | ||||
-rw-r--r-- | go/ssa/mode.go | 107 |
3 files changed, 120 insertions, 58 deletions
diff --git a/cmd/ssadump/main.go b/cmd/ssadump/main.go index 1901b30..8ca6aa4 100644 --- a/cmd/ssadump/main.go +++ b/cmd/ssadump/main.go @@ -19,28 +19,23 @@ import ( "golang.org/x/tools/go/types" ) -var buildFlag = flag.String("build", "", `Options controlling the SSA builder. -The value is a sequence of zero or more of these letters: -C perform sanity [C]hecking of the SSA form. -D include [D]ebug info for every function. -P print [P]ackage inventory. -F print [F]unction SSA code. -S log [S]ource locations as SSA builder progresses. -G use binary object files from gc to provide imports (no code). -L build distinct packages seria[L]ly instead of in parallel. -N build [N]aive SSA form: don't replace local loads/stores with registers. -I build bare [I]nit functions: no init guards or calls to dependent inits. -`) +var ( + importbinFlag = flag.Bool("importbin", false, + "Import binary export data from gc's object files, not source. "+ + "Imported functions will have no bodies.") + + modeFlag = ssa.BuilderModeFlag(flag.CommandLine, "build", 0) -var testFlag = flag.Bool("test", false, "Loads test code (*_test.go) for imported packages.") + testFlag = flag.Bool("test", false, "Loads test code (*_test.go) for imported packages.") -var runFlag = flag.Bool("run", false, "Invokes the SSA interpreter on the program.") + runFlag = flag.Bool("run", false, "Invokes the SSA interpreter on the program.") -var interpFlag = flag.String("interp", "", `Options controlling the SSA test interpreter. + interpFlag = flag.String("interp", "", `Options controlling the SSA test interpreter. The value is a sequence of zero or more more of these letters: R disable [R]ecover() from panic; show interpreter crash instead. T [T]race execution of the program. Best for single-threaded programs! `) +) const usage = `SSA builder and interpreter. Usage: ssadump [<flag> ...] <args> ... @@ -85,7 +80,7 @@ func doMain() error { conf := loader.Config{ Build: &build.Default, - SourceImports: true, + SourceImports: !*importbinFlag, } // TODO(adonovan): make go/types choose its default Sizes from // build.Default or a specified *build.Context. @@ -99,32 +94,6 @@ func doMain() error { WordSize: wordSize, } - var mode ssa.BuilderMode - for _, c := range *buildFlag { - switch c { - case 'D': - mode |= ssa.GlobalDebug - case 'P': - mode |= ssa.PrintPackages - case 'F': - mode |= ssa.PrintFunctions - case 'S': - mode |= ssa.LogSource | ssa.BuildSerially - case 'C': - mode |= ssa.SanityCheckFunctions - case 'N': - mode |= ssa.NaiveForm - case 'G': - conf.SourceImports = false - case 'L': - mode |= ssa.BuildSerially - case 'I': - mode |= ssa.BareInits - default: - return fmt.Errorf("unknown -build option: '%c'", c) - } - } - var interpMode interp.Mode for _, c := range *interpFlag { switch c { @@ -171,7 +140,7 @@ func doMain() error { } // Create and build SSA-form program representation. - prog := ssa.Create(iprog, mode) + prog := ssa.Create(iprog, *modeFlag) prog.BuildAll() // Run the interpreter. diff --git a/go/ssa/create.go b/go/ssa/create.go index 9b3a91b..c2985eb 100644 --- a/go/ssa/create.go +++ b/go/ssa/create.go @@ -18,20 +18,6 @@ import ( "golang.org/x/tools/go/types/typeutil" ) -// BuilderMode is a bitmask of options for diagnostics and checking. -type BuilderMode uint - -const ( - PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout - PrintFunctions // Print function SSA code to stdout - LogSource // Log source locations as SSA builder progresses - SanityCheckFunctions // Perform sanity checking of function bodies - NaiveForm // Build naïve SSA form: don't replace local loads/stores with registers - BuildSerially // Build packages serially, not in parallel. - GlobalDebug // Enable debug info for all packages - BareInits // Build init functions without guards or calls to dependent inits -) - // Create returns a new SSA Program. An SSA Package is created for // each transitively error-free package of iprog. // @@ -257,7 +243,7 @@ func (prog *Program) CreatePackage(info *loader.PackageInfo) *Package { return p } -// printMu serializes printing of Packages/Functions to stdout +// printMu serializes printing of Packages/Functions to stdout. var printMu sync.Mutex // AllPackages returns a new slice containing all packages in the diff --git a/go/ssa/mode.go b/go/ssa/mode.go new file mode 100644 index 0000000..bbd613a --- /dev/null +++ b/go/ssa/mode.go @@ -0,0 +1,107 @@ +// Copyright 2015 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 + +// This file defines the BuilderMode type and its command-line flag. + +import ( + "bytes" + "flag" + "fmt" +) + +// BuilderMode is a bitmask of options for diagnostics and checking. +type BuilderMode uint + +const ( + PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout + PrintFunctions // Print function SSA code to stdout + LogSource // Log source locations as SSA builder progresses + SanityCheckFunctions // Perform sanity checking of function bodies + NaiveForm // Build naïve SSA form: don't replace local loads/stores with registers + BuildSerially // Build packages serially, not in parallel. + GlobalDebug // Enable debug info for all packages + BareInits // Build init functions without guards or calls to dependent inits +) + +const modeFlagUsage = `Options controlling the SSA builder. +The value is a sequence of zero or more of these letters: +C perform sanity [C]hecking of the SSA form. +D include [D]ebug info for every function. +P print [P]ackage inventory. +F print [F]unction SSA code. +S log [S]ource locations as SSA builder progresses. +L build distinct packages seria[L]ly instead of in parallel. +N build [N]aive SSA form: don't replace local loads/stores with registers. +I build bare [I]nit functions: no init guards or calls to dependent inits. +` + +// BuilderModeFlag creates a new command line flag of type BuilderMode, +// adds it to the specified flag set, and returns it. +// +// Example: +// var ssabuild = BuilderModeFlag(flag.CommandLine, "ssabuild", 0) +// +func BuilderModeFlag(set *flag.FlagSet, name string, value BuilderMode) *BuilderMode { + set.Var((*builderModeValue)(&value), name, modeFlagUsage) + return &value +} + +type builderModeValue BuilderMode // satisfies flag.Value and flag.Getter. + +func (v *builderModeValue) Set(s string) error { + var mode BuilderMode + for _, c := range s { + switch c { + case 'D': + mode |= GlobalDebug + case 'P': + mode |= PrintPackages + case 'F': + mode |= PrintFunctions + case 'S': + mode |= LogSource | BuildSerially + case 'C': + mode |= SanityCheckFunctions + case 'N': + mode |= NaiveForm + case 'L': + mode |= BuildSerially + default: + return fmt.Errorf("unknown BuilderMode option: %q", c) + } + } + *v = builderModeValue(mode) + return nil +} + +func (v *builderModeValue) Get() interface{} { return BuilderMode(*v) } + +func (v *builderModeValue) String() string { + mode := BuilderMode(*v) + var buf bytes.Buffer + if mode&GlobalDebug != 0 { + buf.WriteByte('D') + } + if mode&PrintPackages != 0 { + buf.WriteByte('P') + } + if mode&PrintFunctions != 0 { + buf.WriteByte('F') + } + if mode&LogSource != 0 { + buf.WriteByte('S') + } + if mode&SanityCheckFunctions != 0 { + buf.WriteByte('C') + } + if mode&NaiveForm != 0 { + buf.WriteByte('N') + } + if mode&BuildSerially != 0 { + buf.WriteByte('L') + } + return buf.String() +} |