mirror of
https://github.com/golang/go
synced 2024-11-26 07:17:59 -07:00
[dev.regabi] cmd/compile: clean up and document formatting
Some cleanup left over from moving the Type and Sym formatting to types. And then document what the type formats are, now that it's clear. Passes buildall w/ toolstash -cmp. Change-Id: I35cb8978f1627db1056cb8ab343ce6ba6c99afad Reviewed-on: https://go-review.googlesource.com/c/go/+/275780 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
bb4a37bd93
commit
6ea2b8c54c
@ -212,7 +212,6 @@ func Main(archInit func(*Arch)) {
|
|||||||
// would lead to import cycles)
|
// would lead to import cycles)
|
||||||
types.Widthptr = Widthptr
|
types.Widthptr = Widthptr
|
||||||
types.Dowidth = dowidth
|
types.Dowidth = dowidth
|
||||||
types.InstallTypeFormats()
|
|
||||||
types.TypeLinkSym = func(t *types.Type) *obj.LSym {
|
types.TypeLinkSym = func(t *types.Type) *obj.LSym {
|
||||||
return typenamesym(t).Linksym()
|
return typenamesym(t).Linksym()
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,7 @@ var OpNames = []string{
|
|||||||
OXOR: "^",
|
OXOR: "^",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GoString returns the Go syntax for the Op, or else its name.
|
||||||
func (o Op) GoString() string {
|
func (o Op) GoString() string {
|
||||||
if int(o) < len(OpNames) && OpNames[o] != "" {
|
if int(o) < len(OpNames) && OpNames[o] != "" {
|
||||||
return OpNames[o]
|
return OpNames[o]
|
||||||
@ -93,6 +94,12 @@ func (o Op) GoString() string {
|
|||||||
return o.String()
|
return o.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format implements formatting for an Op.
|
||||||
|
// The valid formats are:
|
||||||
|
//
|
||||||
|
// %v Go syntax ("+", "<-", "print")
|
||||||
|
// %+v Debug syntax ("ADD", "RECV", "PRINT")
|
||||||
|
//
|
||||||
func (o Op) Format(s fmt.State, verb rune) {
|
func (o Op) Format(s fmt.State, verb rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
default:
|
default:
|
||||||
@ -109,6 +116,14 @@ func (o Op) Format(s fmt.State, verb rune) {
|
|||||||
|
|
||||||
// Node
|
// Node
|
||||||
|
|
||||||
|
// FmtNode implements formatting for a Node n.
|
||||||
|
// Every Node implementation must define a Format method that calls FmtNode.
|
||||||
|
// The valid formats are:
|
||||||
|
//
|
||||||
|
// %v Go syntax
|
||||||
|
// %L Go syntax followed by " (type T)" if type is known.
|
||||||
|
// %+v Debug syntax, as in Dump.
|
||||||
|
//
|
||||||
func FmtNode(n Node, s fmt.State, verb rune) {
|
func FmtNode(n Node, s fmt.State, verb rune) {
|
||||||
// TODO(rsc): Remove uses of %#v, which behaves just like %v.
|
// TODO(rsc): Remove uses of %#v, which behaves just like %v.
|
||||||
// TODO(rsc): Remove uses of %S, which behaves just like %v.
|
// TODO(rsc): Remove uses of %S, which behaves just like %v.
|
||||||
@ -276,7 +291,7 @@ var OpPrec = []int{
|
|||||||
OEND: 0,
|
OEND: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statements which may be rendered with a simplestmt as init.
|
// StmtWithInit reports whether op is a statement with an explicit init list.
|
||||||
func StmtWithInit(op Op) bool {
|
func StmtWithInit(op Op) bool {
|
||||||
switch op {
|
switch op {
|
||||||
case OIF, OFOR, OFORUNTIL, OSWITCH:
|
case OIF, OFOR, OFORUNTIL, OSWITCH:
|
||||||
@ -869,6 +884,13 @@ func ellipsisIf(b bool) string {
|
|||||||
|
|
||||||
// Nodes
|
// Nodes
|
||||||
|
|
||||||
|
// Format implements formatting for a Nodes.
|
||||||
|
// The valid formats are:
|
||||||
|
//
|
||||||
|
// %v Go syntax, semicolon-separated
|
||||||
|
// %.v Go syntax, comma-separated
|
||||||
|
// %+v Debug syntax, as in DumpList.
|
||||||
|
//
|
||||||
func (l Nodes) Format(s fmt.State, verb rune) {
|
func (l Nodes) Format(s fmt.State, verb rune) {
|
||||||
if s.Flag('+') && verb == 'v' {
|
if s.Flag('+') && verb == 'v' {
|
||||||
// %+v is DumpList output
|
// %+v is DumpList output
|
||||||
@ -896,19 +918,22 @@ func (l Nodes) Format(s fmt.State, verb rune) {
|
|||||||
|
|
||||||
// Dump
|
// Dump
|
||||||
|
|
||||||
|
// Dump prints the message s followed by a debug dump of n.
|
||||||
func Dump(s string, n Node) {
|
func Dump(s string, n Node) {
|
||||||
fmt.Printf("%s [%p]%+v", s, n, n)
|
fmt.Printf("%s [%p]%+v", s, n, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DumpList(s string, l Nodes) {
|
// DumpList prints the message s followed by a debug dump of each node in the list.
|
||||||
|
func DumpList(s string, list Nodes) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
FDumpList(&buf, s, l)
|
FDumpList(&buf, s, list)
|
||||||
os.Stdout.Write(buf.Bytes())
|
os.Stdout.Write(buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func FDumpList(w io.Writer, s string, l Nodes) {
|
// FDumpList prints to w the message s followed by a debug dump of each node in the list.
|
||||||
|
func FDumpList(w io.Writer, s string, list Nodes) {
|
||||||
io.WriteString(w, s)
|
io.WriteString(w, s)
|
||||||
dumpNodes(w, l, 1)
|
dumpNodes(w, list, 1)
|
||||||
io.WriteString(w, "\n")
|
io.WriteString(w, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,6 @@ func init() {
|
|||||||
// Initialize just enough of the universe and the types package to make our tests function.
|
// Initialize just enough of the universe and the types package to make our tests function.
|
||||||
// TODO(josharian): move universe initialization to the types package,
|
// TODO(josharian): move universe initialization to the types package,
|
||||||
// so this test setup can share it.
|
// so this test setup can share it.
|
||||||
types.InstallTypeFormats()
|
|
||||||
types.Dowidth = func(t *types.Type) {}
|
types.Dowidth = func(t *types.Type) {}
|
||||||
|
|
||||||
for _, typ := range [...]struct {
|
for _, typ := range [...]struct {
|
||||||
|
@ -15,14 +15,16 @@ import (
|
|||||||
"cmd/compile/internal/base"
|
"cmd/compile/internal/base"
|
||||||
)
|
)
|
||||||
|
|
||||||
// builtinpkg is a fake package that declares the universe block.
|
// BuiltinPkg is a fake package that declares the universe block.
|
||||||
var BuiltinPkg *Pkg
|
var BuiltinPkg *Pkg
|
||||||
|
|
||||||
var LocalPkg *Pkg // package being compiled
|
// LocalPkg is the package being compiled.
|
||||||
|
var LocalPkg *Pkg
|
||||||
|
|
||||||
|
// BlankSym is the blank (_) symbol.
|
||||||
var BlankSym *Sym
|
var BlankSym *Sym
|
||||||
|
|
||||||
// origSym returns the original symbol written by the user.
|
// OrigSym returns the original symbol written by the user.
|
||||||
func OrigSym(s *Sym) *Sym {
|
func OrigSym(s *Sym) *Sym {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -47,84 +49,36 @@ func OrigSym(s *Sym) *Sym {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sym
|
|
||||||
|
|
||||||
// numImport tracks how often a package with a given name is imported.
|
// numImport tracks how often a package with a given name is imported.
|
||||||
// It is used to provide a better error message (by using the package
|
// It is used to provide a better error message (by using the package
|
||||||
// path to disambiguate) if a package that appears multiple times with
|
// path to disambiguate) if a package that appears multiple times with
|
||||||
// the same name appears in an error message.
|
// the same name appears in an error message.
|
||||||
var NumImport = make(map[string]int)
|
var NumImport = make(map[string]int)
|
||||||
|
|
||||||
// Format conversions:
|
// fmtMode represents the kind of printing being done.
|
||||||
// TODO(gri) verify these; eliminate those not used anymore
|
// The default is regular Go syntax (fmtGo).
|
||||||
//
|
// fmtDebug is like fmtGo but for debugging dumps and prints the type kind too.
|
||||||
// %v Op Node opcodes
|
// fmtTypeID and fmtTypeIDName are for generating various unique representations
|
||||||
// Flags: #: print Go syntax (automatic unless mode == FDbg)
|
// of types used in hashes and the linker.
|
||||||
//
|
|
||||||
// %j *Node Node details
|
|
||||||
// Flags: 0: suppresses things not relevant until walk
|
|
||||||
//
|
|
||||||
// %v *Val Constant values
|
|
||||||
//
|
|
||||||
// %v *types.Sym Symbols
|
|
||||||
// %S unqualified identifier in any mode
|
|
||||||
// Flags: +,- #: mode (see below)
|
|
||||||
// 0: in export mode: unqualified identifier if exported, qualified if not
|
|
||||||
//
|
|
||||||
// %v *types.Type Types
|
|
||||||
// %S omit "func" and receiver in function types
|
|
||||||
// %L definition instead of name.
|
|
||||||
// Flags: +,- #: mode (see below)
|
|
||||||
// ' ' (only in -/Sym mode) print type identifiers wit package name instead of prefix.
|
|
||||||
//
|
|
||||||
// %v *Node Nodes
|
|
||||||
// %S (only in +/debug mode) suppress recursion
|
|
||||||
// %L (only in Error mode) print "foo (type Bar)"
|
|
||||||
// Flags: +,- #: mode (see below)
|
|
||||||
//
|
|
||||||
// %v Nodes Node lists
|
|
||||||
// Flags: those of *Node
|
|
||||||
// .: separate items with ',' instead of ';'
|
|
||||||
|
|
||||||
// *types.Sym, *types.Type, and *Node types use the flags below to set the format mode
|
|
||||||
|
|
||||||
// The mode flags '+', '-', and '#' are sticky; they persist through
|
|
||||||
// recursions of *Node, *types.Type, and *types.Sym values. The ' ' flag is
|
|
||||||
// sticky only on *types.Type recursions and only used in %-/*types.Sym mode.
|
|
||||||
//
|
|
||||||
// Example: given a *types.Sym: %+v %#v %-v print an identifier properly qualified for debug/export/internal mode
|
|
||||||
|
|
||||||
// Useful format combinations:
|
|
||||||
// TODO(gri): verify these
|
|
||||||
//
|
|
||||||
// *Node, Nodes:
|
|
||||||
// %+v multiline recursive debug dump of *Node/Nodes
|
|
||||||
// %+S non-recursive debug dump
|
|
||||||
//
|
|
||||||
// *Node:
|
|
||||||
// %#v Go format
|
|
||||||
// %L "foo (type Bar)" for error messages
|
|
||||||
//
|
|
||||||
// *types.Type:
|
|
||||||
// %#v Go format
|
|
||||||
// %#L type definition instead of name
|
|
||||||
// %#S omit "func" and receiver in function signature
|
|
||||||
//
|
|
||||||
// %-v type identifiers
|
|
||||||
// %-S type identifiers without "func" and arg names in type signatures (methodsym)
|
|
||||||
// %- v type identifiers with package name instead of prefix (typesym, dcommontype, typehash)
|
|
||||||
|
|
||||||
type fmtMode int
|
type fmtMode int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
fmtGo fmtMode = iota
|
fmtGo fmtMode = iota
|
||||||
fmtDebug
|
fmtDebug
|
||||||
fmtTypeID
|
fmtTypeID
|
||||||
fmtTypeIDName // same as FTypeId, but use package name instead of prefix
|
fmtTypeIDName
|
||||||
)
|
)
|
||||||
|
|
||||||
// "%S" suppresses qualifying with package
|
// Sym
|
||||||
func symFormat(s *Sym, f fmt.State, verb rune) {
|
|
||||||
|
// Format implements formatting for a Sym.
|
||||||
|
// The valid formats are:
|
||||||
|
//
|
||||||
|
// %v Go syntax: Name for symbols in the local package, PkgName.Name for imported symbols.
|
||||||
|
// %+v Debug syntax: always include PkgName. prefix even for local names.
|
||||||
|
// %S Short syntax: Name only, no matter what.
|
||||||
|
//
|
||||||
|
func (s *Sym) Format(f fmt.State, verb rune) {
|
||||||
mode := fmtGo
|
mode := fmtGo
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'v', 'S':
|
case 'v', 'S':
|
||||||
@ -138,6 +92,10 @@ func symFormat(s *Sym, f fmt.State, verb rune) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Sym) String() string {
|
||||||
|
return sconv(s, 0, fmtGo)
|
||||||
|
}
|
||||||
|
|
||||||
// See #16897 for details about performance implications
|
// See #16897 for details about performance implications
|
||||||
// before changing the implementation of sconv.
|
// before changing the implementation of sconv.
|
||||||
func sconv(s *Sym, verb rune, mode fmtMode) string {
|
func sconv(s *Sym, verb rune, mode fmtMode) string {
|
||||||
@ -261,26 +219,16 @@ var fmtBufferPool = sync.Pool{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func InstallTypeFormats() {
|
// Format implements formatting for a Type.
|
||||||
SymString = func(s *Sym) string {
|
// The valid formats are:
|
||||||
return sconv(s, 0, fmtGo)
|
//
|
||||||
}
|
// %v Go syntax
|
||||||
TypeString = func(t *Type) string {
|
// %+v Debug syntax: Go syntax with a KIND- prefix for all but builtins.
|
||||||
return tconv(t, 0, fmtGo)
|
// %L Go syntax for underlying type if t is named
|
||||||
}
|
// %S short Go syntax: drop leading "func" in function type
|
||||||
TypeShortString = func(t *Type) string {
|
// %-S special case for method receiver symbol
|
||||||
return tconv(t, 0, fmtTypeID)
|
//
|
||||||
}
|
func (t *Type) Format(s fmt.State, verb rune) {
|
||||||
TypeLongString = func(t *Type) string {
|
|
||||||
return tconv(t, 0, fmtTypeIDName)
|
|
||||||
}
|
|
||||||
FormatSym = symFormat
|
|
||||||
FormatType = typeFormat
|
|
||||||
}
|
|
||||||
|
|
||||||
// "%L" print definition, not name
|
|
||||||
// "%S" omit 'func' and receiver from function types, short type names
|
|
||||||
func typeFormat(t *Type, s fmt.State, verb rune) {
|
|
||||||
mode := fmtGo
|
mode := fmtGo
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'v', 'S', 'L':
|
case 'v', 'S', 'L':
|
||||||
@ -296,6 +244,25 @@ func typeFormat(t *Type, s fmt.State, verb rune) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String returns the Go syntax for the type t.
|
||||||
|
func (t *Type) String() string {
|
||||||
|
return tconv(t, 0, fmtGo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShortString generates a short description of t.
|
||||||
|
// It is used in autogenerated method names, reflection,
|
||||||
|
// and itab names.
|
||||||
|
func (t *Type) ShortString() string {
|
||||||
|
return tconv(t, 0, fmtTypeID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LongString generates a complete description of t.
|
||||||
|
// It is useful for reflection,
|
||||||
|
// or when a unique fingerprint or hash of a type is required.
|
||||||
|
func (t *Type) LongString() string {
|
||||||
|
return tconv(t, 0, fmtTypeIDName)
|
||||||
|
}
|
||||||
|
|
||||||
func tconv(t *Type, verb rune, mode fmtMode) string {
|
func tconv(t *Type, verb rune, mode fmtMode) string {
|
||||||
buf := fmtBufferPool.Get().(*bytes.Buffer)
|
buf := fmtBufferPool.Get().(*bytes.Buffer)
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
|
@ -6,7 +6,6 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const BADWIDTH = -1000000000
|
const BADWIDTH = -1000000000
|
||||||
@ -17,47 +16,9 @@ const BADWIDTH = -1000000000
|
|||||||
var (
|
var (
|
||||||
Widthptr int
|
Widthptr int
|
||||||
Dowidth func(*Type)
|
Dowidth func(*Type)
|
||||||
SymString func(*Sym) string
|
|
||||||
TypeString func(*Type) string
|
|
||||||
TypeShortString func(*Type) string
|
|
||||||
TypeLongString func(*Type) string
|
|
||||||
FormatSym func(*Sym, fmt.State, rune)
|
|
||||||
FormatType func(*Type, fmt.State, rune)
|
|
||||||
TypeLinkSym func(*Type) *obj.LSym
|
TypeLinkSym func(*Type) *obj.LSym
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Sym) String() string {
|
|
||||||
return SymString(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sym *Sym) Format(s fmt.State, verb rune) {
|
|
||||||
FormatSym(sym, s, verb)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Type) String() string {
|
|
||||||
// The implementation
|
|
||||||
// must handle recursive types correctly.
|
|
||||||
return TypeString(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShortString generates a short description of t.
|
|
||||||
// It is used in autogenerated method names, reflection,
|
|
||||||
// and itab names.
|
|
||||||
func (t *Type) ShortString() string {
|
|
||||||
return TypeShortString(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LongString generates a complete description of t.
|
|
||||||
// It is useful for reflection,
|
|
||||||
// or when a unique fingerprint or hash of a type is required.
|
|
||||||
func (t *Type) LongString() string {
|
|
||||||
return TypeLongString(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Type) Format(s fmt.State, verb rune) {
|
|
||||||
FormatType(t, s, verb)
|
|
||||||
}
|
|
||||||
|
|
||||||
type bitset8 uint8
|
type bitset8 uint8
|
||||||
|
|
||||||
func (f *bitset8) set(mask uint8, b bool) {
|
func (f *bitset8) set(mask uint8, b bool) {
|
||||||
|
Loading…
Reference in New Issue
Block a user