1
0
mirror of https://github.com/golang/go synced 2024-11-27 04:11:22 -07:00

cmd/compile/internal/ir: simplify printing of OLITERALs

This formatting used to be relevant to user error diagnostics and
(much earlier) even to the old textual export data format, but now
it's only relevant to backend debugging. So we can simplify a lot,
adjusting a few test expectations accordingly.

Change-Id: Ibe8e029284ce6150bfa24ef794d8d9eff66dbdea
Reviewed-on: https://go-review.googlesource.com/c/go/+/526375
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2023-09-06 14:43:22 -07:00 committed by Gopher Robot
parent 660620dd45
commit ae09ca6c0f
5 changed files with 39 additions and 85 deletions

View File

@ -133,10 +133,14 @@ type BasicLit struct {
} }
func NewBasicLit(pos src.XPos, val constant.Value) Node { func NewBasicLit(pos src.XPos, val constant.Value) Node {
if val == nil || val.Kind() == constant.Unknown {
base.FatalfAt(pos, "bad value: %v", val)
}
n := &BasicLit{val: val} n := &BasicLit{val: val}
n.op = OLITERAL n.op = OLITERAL
n.pos = pos n.pos = pos
n.SetType(idealType(val.Kind())) n.SetType(types.UntypedTypes[val.Kind()])
n.SetTypecheck(1) n.SetTypecheck(1)
return n return n
} }

View File

@ -580,46 +580,29 @@ func exprFmt(n Node, s fmt.State, prec int) {
case ONIL: case ONIL:
fmt.Fprint(s, "nil") fmt.Fprint(s, "nil")
case OLITERAL: // this is a bit of a mess case OLITERAL:
if !exportFormat && n.Sym() != nil { if n.Sym() != nil {
fmt.Fprint(s, n.Sym()) fmt.Fprint(s, n.Sym())
return return
} }
needUnparen := false typ := n.Type()
if n.Type() != nil && !n.Type().IsUntyped() { val := n.Val()
// Need parens when type begins with what might
// be misinterpreted as a unary operator: * or <-.
if n.Type().IsPtr() || (n.Type().IsChan() && n.Type().ChanDir() == types.Crecv) {
fmt.Fprintf(s, "(%v)(", n.Type())
} else {
fmt.Fprintf(s, "%v(", n.Type())
}
needUnparen = true
}
if n.Type() == types.UntypedRune { // Special case for rune constants.
switch x, ok := constant.Uint64Val(n.Val()); { if typ == types.RuneType || typ == types.UntypedRune {
case !ok: if x, ok := constant.Uint64Val(val); ok && x <= utf8.MaxRune {
fallthrough
default:
fmt.Fprintf(s, "('\\x00' + %v)", n.Val())
case x < utf8.RuneSelf:
fmt.Fprintf(s, "%q", x) fmt.Fprintf(s, "%q", x)
return
case x < 1<<16:
fmt.Fprintf(s, "'\\u%04x'", x)
case x <= utf8.MaxRune:
fmt.Fprintf(s, "'\\U%08x'", x)
} }
} else {
fmt.Fprint(s, types.FmtConst(n.Val(), s.Flag('#')))
} }
if needUnparen { // Only include typ if it's neither the default nor untyped type
fmt.Fprintf(s, ")") // for the constant value.
if k := val.Kind(); typ == types.Types[types.DefaultKinds[k]] || typ == types.UntypedTypes[k] {
fmt.Fprint(s, val)
} else {
fmt.Fprintf(s, "%v(%v)", typ, val)
} }
case ODCLFUNC: case ODCLFUNC:

View File

@ -60,23 +60,6 @@ func ValidTypeForConst(t *types.Type, v constant.Value) bool {
panic("unreachable") panic("unreachable")
} }
func idealType(ct constant.Kind) *types.Type {
switch ct {
case constant.String:
return types.UntypedString
case constant.Bool:
return types.UntypedBool
case constant.Int:
return types.UntypedInt
case constant.Float:
return types.UntypedFloat
case constant.Complex:
return types.UntypedComplex
}
base.Fatalf("unexpected Ctype: %v", ct)
return nil
}
var OKForConst [types.NTYPE]bool var OKForConst [types.NTYPE]bool
// Int64Val returns n as an int64. // Int64Val returns n as an int64.

View File

@ -8,7 +8,6 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"go/constant"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -683,41 +682,6 @@ func SplitVargenSuffix(name string) (base, suffix string) {
return name, "" return name, ""
} }
// Val
func FmtConst(v constant.Value, sharp bool) string {
if !sharp && v.Kind() == constant.Complex {
real, imag := constant.Real(v), constant.Imag(v)
var re string
sre := constant.Sign(real)
if sre != 0 {
re = real.String()
}
var im string
sim := constant.Sign(imag)
if sim != 0 {
im = imag.String()
}
switch {
case sre == 0 && sim == 0:
return "0"
case sre == 0:
return im + "i"
case sim == 0:
return re
case sim < 0:
return fmt.Sprintf("(%s%si)", re, im)
default:
return fmt.Sprintf("(%s+%si)", re, im)
}
}
return v.String()
}
// TypeHash computes a hash value for type t to use in type switch statements. // TypeHash computes a hash value for type t to use in type switch statements.
func TypeHash(t *Type) uint32 { func TypeHash(t *Type) uint32 {
p := t.LinkString() p := t.LinkString()

View File

@ -9,6 +9,7 @@ import (
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/src" "cmd/internal/src"
"fmt" "fmt"
"go/constant"
"internal/types/errors" "internal/types/errors"
"sync" "sync"
) )
@ -128,6 +129,25 @@ var (
UntypedComplex = newType(TIDEAL) UntypedComplex = newType(TIDEAL)
) )
// UntypedTypes maps from a constant.Kind to its untyped Type
// representation.
var UntypedTypes = [...]*Type{
constant.Bool: UntypedBool,
constant.String: UntypedString,
constant.Int: UntypedInt,
constant.Float: UntypedFloat,
constant.Complex: UntypedComplex,
}
// DefaultKinds maps from a constant.Kind to its default Kind.
var DefaultKinds = [...]Kind{
constant.Bool: TBOOL,
constant.String: TSTRING,
constant.Int: TINT,
constant.Float: TFLOAT64,
constant.Complex: TCOMPLEX128,
}
// A Type represents a Go type. // A Type represents a Go type.
// //
// There may be multiple unnamed types with identical structure. However, there must // There may be multiple unnamed types with identical structure. However, there must