aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/expr.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-05-27 02:50:17 -0700
committerMatthew Dempsky <mdempsky@google.com>2021-05-27 22:13:46 +0000
commitea522bc546bb9f66285ea00744de8b258368b3ed (patch)
treef7ad88506a7f8a9e9220bf830061a1f7b295430e /src/cmd/compile/internal/noder/expr.go
parentde5d1aca5e61e49e0704213961c68bcf14e288b8 (diff)
downloadgo-ea522bc546bb9f66285ea00744de8b258368b3ed.tar.xz
[dev.typeparams] cmd/compile: add and use ir.RawOrigExpr
This CL adds ir.RawOrigExpr, which can be used to represent arbitrary constant expressions without needing to build and carry around an entire IR representation of the original expression. It also allows distinguishing how the constant was originally written by the user (e.g., "0xff" vs "255"). This CL then also updates irgen to make use of this functionality for expressions that were constant folded by types2. Change-Id: I41e04e228e715ae2735c357b75633a2d08ee7021 Reviewed-on: https://go-review.googlesource.com/c/go/+/323210 Trust: Matthew Dempsky <mdempsky@google.com> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/expr.go')
-rw-r--r--src/cmd/compile/internal/noder/expr.go51
1 files changed, 45 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go
index f96144f8d7..c901dc5534 100644
--- a/src/cmd/compile/internal/noder/expr.go
+++ b/src/cmd/compile/internal/noder/expr.go
@@ -5,6 +5,8 @@
package noder
import (
+ "fmt"
+
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
"cmd/compile/internal/syntax"
@@ -15,6 +17,8 @@ import (
)
func (g *irgen) expr(expr syntax.Expr) ir.Node {
+ expr = unparen(expr) // skip parens; unneeded after parse+typecheck
+
if expr == nil {
return nil
}
@@ -67,7 +71,9 @@ func (g *irgen) expr(expr syntax.Expr) ir.Node {
// Constant expression.
if tv.Value != nil {
- return Const(g.pos(expr), g.typ(typ), tv.Value)
+ typ := g.typ(typ)
+ value := FixValue(typ, tv.Value)
+ return OrigConst(g.pos(expr), typ, value, constExprOp(expr), syntax.String(expr))
}
n := g.expr0(typ, expr)
@@ -161,9 +167,6 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
typed(g.typ(typ), n)
return n
- case *syntax.ParenExpr:
- return g.expr(expr.X) // skip parens; unneeded after parse+typecheck
-
case *syntax.SelectorExpr:
// Qualified identifier.
if name, ok := expr.X.(*syntax.Name); ok {
@@ -317,13 +320,17 @@ func getTargs(selinfo *types2.Selection) []types2.Type {
}
func (g *irgen) exprList(expr syntax.Expr) []ir.Node {
+ return g.exprs(unpackListExpr(expr))
+}
+
+func unpackListExpr(expr syntax.Expr) []syntax.Expr {
switch expr := expr.(type) {
case nil:
return nil
case *syntax.ListExpr:
- return g.exprs(expr.ElemList)
+ return expr.ElemList
default:
- return []ir.Node{g.expr(expr)}
+ return []syntax.Expr{expr}
}
}
@@ -402,3 +409,35 @@ func (g *irgen) typeExpr(typ syntax.Expr) *types.Type {
}
return n.Type()
}
+
+// constExprOp returns an ir.Op that represents the outermost
+// operation of the given constant expression. It's intended for use
+// with ir.RawOrigExpr.
+func constExprOp(expr syntax.Expr) ir.Op {
+ switch expr := expr.(type) {
+ default:
+ panic(fmt.Sprintf("%s: unexpected expression: %T", expr.Pos(), expr))
+
+ case *syntax.BasicLit:
+ return ir.OLITERAL
+ case *syntax.Name, *syntax.SelectorExpr:
+ return ir.ONAME
+ case *syntax.CallExpr:
+ return ir.OCALL
+ case *syntax.Operation:
+ if expr.Y == nil {
+ return unOps[expr.Op]
+ }
+ return binOps[expr.Op]
+ }
+}
+
+func unparen(expr syntax.Expr) syntax.Expr {
+ for {
+ paren, ok := expr.(*syntax.ParenExpr)
+ if !ok {
+ return expr
+ }
+ expr = paren.X
+ }
+}