Commit 62a296cd authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile: use printer in sconv, symfmt

Change-Id: Iec33775ff5a786f6c52024d592f634231acf91c0
Reviewed-on: https://go-review.googlesource.com/27918Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 73be5d82
...@@ -463,47 +463,47 @@ func (et EType) String() string { ...@@ -463,47 +463,47 @@ func (et EType) String() string {
} }
// Fmt "%S": syms // Fmt "%S": syms
func symfmt(s *Sym, flag FmtFlag) string { func (p *printer) symfmt(s *Sym, flag FmtFlag) *printer {
if s.Pkg != nil && flag&FmtShort == 0 { if s.Pkg != nil && flag&FmtShort == 0 {
switch fmtmode { switch fmtmode {
case FErr: // This is for the user case FErr: // This is for the user
if s.Pkg == builtinpkg || s.Pkg == localpkg { if s.Pkg == builtinpkg || s.Pkg == localpkg {
return s.Name return p.s(s.Name)
} }
// If the name was used by multiple packages, display the full path, // If the name was used by multiple packages, display the full path,
if s.Pkg.Name != "" && numImport[s.Pkg.Name] > 1 { if s.Pkg.Name != "" && numImport[s.Pkg.Name] > 1 {
return fmt.Sprintf("%q.%s", s.Pkg.Path, s.Name) return p.f("%q.%s", s.Pkg.Path, s.Name)
} }
return s.Pkg.Name + "." + s.Name return p.s(s.Pkg.Name + "." + s.Name)
case FDbg: case FDbg:
return s.Pkg.Name + "." + s.Name return p.s(s.Pkg.Name + "." + s.Name)
case FTypeId: case FTypeId:
if flag&FmtUnsigned != 0 { if flag&FmtUnsigned != 0 {
return s.Pkg.Name + "." + s.Name // dcommontype, typehash return p.s(s.Pkg.Name + "." + s.Name) // dcommontype, typehash
} }
return s.Pkg.Prefix + "." + s.Name // (methodsym), typesym, weaksym return p.s(s.Pkg.Prefix + "." + s.Name) // (methodsym), typesym, weaksym
} }
} }
if flag&FmtByte != 0 { if flag&FmtByte != 0 {
// FmtByte (hh) implies FmtShort (h) // FmtByte (hh) implies FmtShort (h)
// skip leading "type." in method name // skip leading "type." in method name
p := s.Name name := s.Name
if i := strings.LastIndex(s.Name, "."); i >= 0 { if i := strings.LastIndex(name, "."); i >= 0 {
p = s.Name[i+1:] name = name[i+1:]
} }
if fmtmode == FDbg { if fmtmode == FDbg {
return fmt.Sprintf("@%q.%s", s.Pkg.Path, p) return p.f("@%q.%s", s.Pkg.Path, name)
} }
return p return p.s(name)
} }
return s.Name return p.s(s.Name)
} }
var basicnames = []string{ var basicnames = []string{
...@@ -1390,7 +1390,7 @@ func exprfmt(n *Node, prec int) string { ...@@ -1390,7 +1390,7 @@ func exprfmt(n *Node, prec int) string {
return fmt.Sprintf("<node %v>", n.Op) return fmt.Sprintf("<node %v>", n.Op)
} }
func nodefmt(n *Node, flag FmtFlag) string { func (p *printer) nodefmt(n *Node, flag FmtFlag) *printer {
t := n.Type t := n.Type
// we almost always want the original, except in export mode for literals // we almost always want the original, except in export mode for literals
...@@ -1402,115 +1402,104 @@ func nodefmt(n *Node, flag FmtFlag) string { ...@@ -1402,115 +1402,104 @@ func nodefmt(n *Node, flag FmtFlag) string {
if flag&FmtLong != 0 && t != nil { if flag&FmtLong != 0 && t != nil {
if t.Etype == TNIL { if t.Etype == TNIL {
return "nil" return p.s("nil")
} else { } else {
return fmt.Sprintf("%v (type %v)", n, t) return p.f("%v (type %v)", n, t)
} }
} }
// TODO inlining produces expressions with ninits. we can't print these yet. // TODO inlining produces expressions with ninits. we can't print these yet.
if opprec[n.Op] < 0 { if opprec[n.Op] < 0 {
return stmtfmt(n) return p.s(stmtfmt(n))
} }
return exprfmt(n, 0) return p.s(exprfmt(n, 0))
}
var dumpdepth int
func indent(buf *bytes.Buffer) {
buf.WriteString("\n")
for i := 0; i < dumpdepth; i++ {
buf.WriteString(". ")
}
} }
func nodedump(n *Node, flag FmtFlag) string { func (p *printer) nodedump(n *Node, flag FmtFlag) *printer {
if n == nil { if n == nil {
return "" return p
} }
recur := flag&FmtShort == 0 recur := flag&FmtShort == 0
var buf bytes.Buffer
if recur { if recur {
indent(&buf) p.indent()
if dumpdepth > 10 { if p.dumpdepth > 10 {
buf.WriteString("...") return p.s("...")
return buf.String()
} }
if n.Ninit.Len() != 0 { if n.Ninit.Len() != 0 {
fmt.Fprintf(&buf, "%v-init%v", n.Op, n.Ninit) p.f("%v-init%v", n.Op, n.Ninit)
indent(&buf) p.indent()
} }
} }
switch n.Op { switch n.Op {
default: default:
fmt.Fprintf(&buf, "%v%v", n.Op, jconv(n, 0)) p.f("%v%v", n.Op, jconv(n, 0))
case OREGISTER, OINDREG: case OREGISTER, OINDREG:
fmt.Fprintf(&buf, "%v-%v%v", n.Op, obj.Rconv(int(n.Reg)), jconv(n, 0)) p.f("%v-%v%v", n.Op, obj.Rconv(int(n.Reg)), jconv(n, 0))
case OLITERAL: case OLITERAL:
fmt.Fprintf(&buf, "%v-%v%v", n.Op, vconv(n.Val(), 0), jconv(n, 0)) p.f("%v-%v%v", n.Op, vconv(n.Val(), 0), jconv(n, 0))
case ONAME, ONONAME: case ONAME, ONONAME:
if n.Sym != nil { if n.Sym != nil {
fmt.Fprintf(&buf, "%v-%v%v", n.Op, n.Sym, jconv(n, 0)) p.f("%v-%v%v", n.Op, n.Sym, jconv(n, 0))
} else { } else {
fmt.Fprintf(&buf, "%v%v", n.Op, jconv(n, 0)) p.f("%v%v", n.Op, jconv(n, 0))
} }
if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil { if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil {
indent(&buf) p.indent()
fmt.Fprintf(&buf, "%v-ntype%v", n.Op, n.Name.Param.Ntype) p.f("%v-ntype%v", n.Op, n.Name.Param.Ntype)
} }
case OASOP: case OASOP:
fmt.Fprintf(&buf, "%v-%v%v", n.Op, Op(n.Etype), jconv(n, 0)) p.f("%v-%v%v", n.Op, Op(n.Etype), jconv(n, 0))
case OTYPE: case OTYPE:
fmt.Fprintf(&buf, "%v %v%v type=%v", n.Op, n.Sym, jconv(n, 0), n.Type) p.f("%v %v%v type=%v", n.Op, n.Sym, jconv(n, 0), n.Type)
if recur && n.Type == nil && n.Name.Param.Ntype != nil { if recur && n.Type == nil && n.Name.Param.Ntype != nil {
indent(&buf) p.indent()
fmt.Fprintf(&buf, "%v-ntype%v", n.Op, n.Name.Param.Ntype) p.f("%v-ntype%v", n.Op, n.Name.Param.Ntype)
} }
} }
if n.Sym != nil && n.Op != ONAME { if n.Sym != nil && n.Op != ONAME {
fmt.Fprintf(&buf, " %v", n.Sym) p.f(" %v", n.Sym)
} }
if n.Type != nil { if n.Type != nil {
fmt.Fprintf(&buf, " %v", n.Type) p.f(" %v", n.Type)
} }
if recur { if recur {
if n.Left != nil { if n.Left != nil {
buf.WriteString(Nconv(n.Left, 0)) p.s(Nconv(n.Left, 0))
} }
if n.Right != nil { if n.Right != nil {
buf.WriteString(Nconv(n.Right, 0)) p.s(Nconv(n.Right, 0))
} }
if n.List.Len() != 0 { if n.List.Len() != 0 {
indent(&buf) p.indent()
fmt.Fprintf(&buf, "%v-list%v", n.Op, n.List) p.f("%v-list%v", n.Op, n.List)
} }
if n.Rlist.Len() != 0 { if n.Rlist.Len() != 0 {
indent(&buf) p.indent()
fmt.Fprintf(&buf, "%v-rlist%v", n.Op, n.Rlist) p.f("%v-rlist%v", n.Op, n.Rlist)
} }
if n.Nbody.Len() != 0 { if n.Nbody.Len() != 0 {
indent(&buf) p.indent()
fmt.Fprintf(&buf, "%v-body%v", n.Op, n.Nbody) p.f("%v-body%v", n.Op, n.Nbody)
} }
} }
return buf.String() return p
} }
func (s *Sym) String() string { func (s *Sym) String() string {
...@@ -1520,6 +1509,8 @@ func (s *Sym) String() string { ...@@ -1520,6 +1509,8 @@ func (s *Sym) String() string {
// Fmt "%S": syms // Fmt "%S": syms
// Flags: "%hS" suppresses qualifying with package // Flags: "%hS" suppresses qualifying with package
func sconv(s *Sym, flag FmtFlag) string { func sconv(s *Sym, flag FmtFlag) string {
var p printer
if flag&FmtLong != 0 { if flag&FmtLong != 0 {
panic("linksymfmt") panic("linksymfmt")
} }
...@@ -1534,11 +1525,12 @@ func sconv(s *Sym, flag FmtFlag) string { ...@@ -1534,11 +1525,12 @@ func sconv(s *Sym, flag FmtFlag) string {
sf := flag sf := flag
sm, sb := setfmode(&flag) sm, sb := setfmode(&flag)
str := symfmt(s, flag) p.symfmt(s, flag)
flag = sf flag = sf
fmtmode = sm fmtmode = sm
fmtbody = sb fmtbody = sb
return str
return p.String()
} }
func (t *Type) String() string { func (t *Type) String() string {
...@@ -1671,21 +1663,22 @@ func (n *Node) String() string { ...@@ -1671,21 +1663,22 @@ func (n *Node) String() string {
// Flags: 'l' suffix with "(type %T)" where possible // Flags: 'l' suffix with "(type %T)" where possible
// '+h' in debug mode, don't recurse, no multiline output // '+h' in debug mode, don't recurse, no multiline output
func Nconv(n *Node, flag FmtFlag) string { func Nconv(n *Node, flag FmtFlag) string {
var p printer
if n == nil { if n == nil {
return "<N>" return "<N>"
} }
sf := flag sf := flag
sm, sb := setfmode(&flag) sm, sb := setfmode(&flag)
var str string
switch fmtmode { switch fmtmode {
case FErr: case FErr:
str = nodefmt(n, flag) p.nodefmt(n, flag)
case FDbg: case FDbg:
dumpdepth++ p.dumpdepth++
str = nodedump(n, flag) p.nodedump(n, flag)
dumpdepth-- p.dumpdepth--
default: default:
Fatalf("unhandled %%N mode") Fatalf("unhandled %%N mode")
...@@ -1694,7 +1687,8 @@ func Nconv(n *Node, flag FmtFlag) string { ...@@ -1694,7 +1687,8 @@ func Nconv(n *Node, flag FmtFlag) string {
flag = sf flag = sf
fmtbody = sb fmtbody = sb
fmtmode = sm fmtmode = sm
return str
return p.String()
} }
func (n Nodes) String() string { func (n Nodes) String() string {
...@@ -1741,7 +1735,8 @@ func Dump(s string, n *Node) { ...@@ -1741,7 +1735,8 @@ func Dump(s string, n *Node) {
// printer is a buffer for creating longer formatted strings. // printer is a buffer for creating longer formatted strings.
type printer struct { type printer struct {
buf []byte buf []byte
dumpdepth int
} }
// printer implements io.Writer. // printer implements io.Writer.
...@@ -1766,3 +1761,11 @@ func (p *printer) f(format string, args ...interface{}) *printer { ...@@ -1766,3 +1761,11 @@ func (p *printer) f(format string, args ...interface{}) *printer {
fmt.Fprintf(p, format, args...) fmt.Fprintf(p, format, args...)
return p return p
} }
// indent prints indentation to p.
func (p *printer) indent() {
p.s("\n")
for i := 0; i < p.dumpdepth; i++ {
p.s(". ")
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment