1
0
mirror of https://github.com/golang/go synced 2024-09-23 15:20:13 -06: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:
Russ Cox 2020-12-06 14:15:09 -05:00
parent bb4a37bd93
commit 6ea2b8c54c
5 changed files with 87 additions and 136 deletions

View File

@ -212,7 +212,6 @@ func Main(archInit func(*Arch)) {
// would lead to import cycles)
types.Widthptr = Widthptr
types.Dowidth = dowidth
types.InstallTypeFormats()
types.TypeLinkSym = func(t *types.Type) *obj.LSym {
return typenamesym(t).Linksym()
}

View File

@ -86,6 +86,7 @@ var OpNames = []string{
OXOR: "^",
}
// GoString returns the Go syntax for the Op, or else its name.
func (o Op) GoString() string {
if int(o) < len(OpNames) && OpNames[o] != "" {
return OpNames[o]
@ -93,6 +94,12 @@ func (o Op) GoString() 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) {
switch verb {
default:
@ -109,6 +116,14 @@ func (o Op) Format(s fmt.State, verb rune) {
// 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) {
// TODO(rsc): Remove uses of %#v, 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,
}
// 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 {
switch op {
case OIF, OFOR, OFORUNTIL, OSWITCH:
@ -869,6 +884,13 @@ func ellipsisIf(b bool) string {
// 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) {
if s.Flag('+') && verb == 'v' {
// %+v is DumpList output
@ -896,19 +918,22 @@ func (l Nodes) Format(s fmt.State, verb rune) {
// Dump
// Dump prints the message s followed by a debug dump of n.
func Dump(s string, n Node) {
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
FDumpList(&buf, s, l)
FDumpList(&buf, s, list)
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)
dumpNodes(w, l, 1)
dumpNodes(w, list, 1)
io.WriteString(w, "\n")
}

View File

@ -137,7 +137,6 @@ func init() {
// Initialize just enough of the universe and the types package to make our tests function.
// TODO(josharian): move universe initialization to the types package,
// so this test setup can share it.
types.InstallTypeFormats()
types.Dowidth = func(t *types.Type) {}
for _, typ := range [...]struct {

View File

@ -15,14 +15,16 @@ import (
"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 LocalPkg *Pkg // package being compiled
// LocalPkg is the package being compiled.
var LocalPkg *Pkg
// BlankSym is the blank (_) symbol.
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 {
if s == nil {
return nil
@ -47,84 +49,36 @@ func OrigSym(s *Sym) *Sym {
return s
}
// Sym
// 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
// path to disambiguate) if a package that appears multiple times with
// the same name appears in an error message.
var NumImport = make(map[string]int)
// Format conversions:
// TODO(gri) verify these; eliminate those not used anymore
//
// %v Op Node opcodes
// Flags: #: print Go syntax (automatic unless mode == FDbg)
//
// %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)
// fmtMode represents the kind of printing being done.
// The default is regular Go syntax (fmtGo).
// fmtDebug is like fmtGo but for debugging dumps and prints the type kind too.
// fmtTypeID and fmtTypeIDName are for generating various unique representations
// of types used in hashes and the linker.
type fmtMode int
const (
fmtGo fmtMode = iota
fmtDebug
fmtTypeID
fmtTypeIDName // same as FTypeId, but use package name instead of prefix
fmtTypeIDName
)
// "%S" suppresses qualifying with package
func symFormat(s *Sym, f fmt.State, verb rune) {
// Sym
// 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
switch verb {
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
// before changing the implementation of sconv.
func sconv(s *Sym, verb rune, mode fmtMode) string {
@ -261,26 +219,16 @@ var fmtBufferPool = sync.Pool{
},
}
func InstallTypeFormats() {
SymString = func(s *Sym) string {
return sconv(s, 0, fmtGo)
}
TypeString = func(t *Type) string {
return tconv(t, 0, fmtGo)
}
TypeShortString = func(t *Type) string {
return tconv(t, 0, fmtTypeID)
}
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) {
// Format implements formatting for a Type.
// The valid formats are:
//
// %v Go syntax
// %+v Debug syntax: Go syntax with a KIND- prefix for all but builtins.
// %L Go syntax for underlying type if t is named
// %S short Go syntax: drop leading "func" in function type
// %-S special case for method receiver symbol
//
func (t *Type) Format(s fmt.State, verb rune) {
mode := fmtGo
switch verb {
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 {
buf := fmtBufferPool.Get().(*bytes.Buffer)
buf.Reset()

View File

@ -6,7 +6,6 @@ package types
import (
"cmd/internal/obj"
"fmt"
)
const BADWIDTH = -1000000000
@ -15,49 +14,11 @@ const BADWIDTH = -1000000000
// They are here to break import cycles.
// TODO(gri) eliminate these dependencies.
var (
Widthptr int
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
Widthptr int
Dowidth func(*Type)
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
func (f *bitset8) set(mask uint8, b bool) {