mirror of
https://github.com/golang/go
synced 2024-11-18 10:54:40 -07:00
go/ssa: make *BuilderMode satisfy flag.Value
The BuilderModeFlag function does not work with flag packages (such as Google's) that define their own FlagSet. This change exposes a type that satisifies flag.Value insted of a function. That type is *BuilderMode; there's no need for a separate wrapper type. Change-Id: I8095b80de499e3c52a29a5c1996d1b1fe3799358 Reviewed-on: https://go-review.googlesource.com/20330 Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
parent
53f5cdeed1
commit
3d26f6847a
@ -23,8 +23,9 @@ import (
|
||||
"golang.org/x/tools/go/ssa/ssautil"
|
||||
)
|
||||
|
||||
// flags
|
||||
var (
|
||||
modeFlag = ssa.BuilderModeFlag(flag.CommandLine, "build", 0)
|
||||
mode = ssa.BuilderMode(0)
|
||||
|
||||
testFlag = flag.Bool("test", false, "Loads test code (*_test.go) for imported packages.")
|
||||
|
||||
@ -35,8 +36,15 @@ 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!
|
||||
`)
|
||||
|
||||
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.Var(&mode, "build", ssa.BuilderModeDoc)
|
||||
flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||
}
|
||||
|
||||
const usage = `SSA builder and interpreter.
|
||||
Usage: ssadump [<flag> ...] <args> ...
|
||||
Use -help flag to display options.
|
||||
@ -53,22 +61,6 @@ if clear, it runs the first package named main.
|
||||
if set, it runs the tests of each package.
|
||||
`
|
||||
|
||||
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
|
||||
|
||||
func init() {
|
||||
flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||
|
||||
// If $GOMAXPROCS isn't set, use the full capacity of the machine.
|
||||
// For small machines, use at least 4 threads.
|
||||
if os.Getenv("GOMAXPROCS") == "" {
|
||||
n := runtime.NumCPU()
|
||||
if n < 4 {
|
||||
n = 4
|
||||
}
|
||||
runtime.GOMAXPROCS(n)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
if err := doMain(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "ssadump: %s\n", err)
|
||||
@ -139,7 +131,7 @@ func doMain() error {
|
||||
}
|
||||
|
||||
// Create and build SSA-form program representation.
|
||||
prog := ssautil.CreateProgram(iprog, *modeFlag)
|
||||
prog := ssautil.CreateProgram(iprog, mode)
|
||||
|
||||
// Build and display only the initial packages
|
||||
// (and synthetic wrappers), unless -run is specified.
|
||||
|
@ -8,11 +8,16 @@ package ssa
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// BuilderMode is a bitmask of options for diagnostics and checking.
|
||||
//
|
||||
// *BuilderMode satisfies the flag.Value interface. Example:
|
||||
//
|
||||
// var mode = ssa.BuilderMode(0)
|
||||
// func init() { flag.Var(&mode, "build", ssa.BuilderModeDoc) }
|
||||
//
|
||||
type BuilderMode uint
|
||||
|
||||
const (
|
||||
@ -26,7 +31,7 @@ const (
|
||||
BareInits // Build init functions without guards or calls to dependent inits
|
||||
)
|
||||
|
||||
const modeFlagUsage = `Options controlling the SSA builder.
|
||||
const BuilderModeDoc = `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.
|
||||
@ -38,20 +43,34 @@ 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
|
||||
func (m BuilderMode) String() string {
|
||||
var buf bytes.Buffer
|
||||
if m&GlobalDebug != 0 {
|
||||
buf.WriteByte('D')
|
||||
}
|
||||
if m&PrintPackages != 0 {
|
||||
buf.WriteByte('P')
|
||||
}
|
||||
if m&PrintFunctions != 0 {
|
||||
buf.WriteByte('F')
|
||||
}
|
||||
if m&LogSource != 0 {
|
||||
buf.WriteByte('S')
|
||||
}
|
||||
if m&SanityCheckFunctions != 0 {
|
||||
buf.WriteByte('C')
|
||||
}
|
||||
if m&NaiveForm != 0 {
|
||||
buf.WriteByte('N')
|
||||
}
|
||||
if m&BuildSerially != 0 {
|
||||
buf.WriteByte('L')
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type builderModeValue BuilderMode // satisfies flag.Value and flag.Getter.
|
||||
|
||||
func (v *builderModeValue) Set(s string) error {
|
||||
// Set parses the flag characters in s and updates *m.
|
||||
func (m *BuilderMode) Set(s string) error {
|
||||
var mode BuilderMode
|
||||
for _, c := range s {
|
||||
switch c {
|
||||
@ -73,35 +92,9 @@ func (v *builderModeValue) Set(s string) error {
|
||||
return fmt.Errorf("unknown BuilderMode option: %q", c)
|
||||
}
|
||||
}
|
||||
*v = builderModeValue(mode)
|
||||
*m = 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()
|
||||
}
|
||||
// Get returns m.
|
||||
func (m BuilderMode) Get() interface{} { return m }
|
||||
|
Loading…
Reference in New Issue
Block a user