aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Donovan <adonovan@google.com>2015-02-18 12:53:21 -0500
committerAlan Donovan <adonovan@google.com>2015-02-18 18:34:24 +0000
commit9bdc5913730054d40cef92bf4b486e92e65d1d6d (patch)
tree48e458a4138900c2bc7d0da4e5a360768cdde48a
parent10d7cacb911f0ca07f31beebe5e019da2c2b393f (diff)
downloadtools-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.go55
-rw-r--r--go/ssa/create.go16
-rw-r--r--go/ssa/mode.go107
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()
+}