1
2
3
4
5 package ir
6
7 import (
8 "go/constant"
9 "math"
10
11 "cmd/compile/internal/base"
12 "cmd/compile/internal/types"
13 )
14
15 func ConstType(n Node) constant.Kind {
16 if n == nil || n.Op() != OLITERAL {
17 return constant.Unknown
18 }
19 return n.Val().Kind()
20 }
21
22
23
24
25 func ConstValue(n Node) interface{} {
26 switch v := n.Val(); v.Kind() {
27 default:
28 base.Fatalf("unexpected constant: %v", v)
29 panic("unreachable")
30 case constant.Bool:
31 return constant.BoolVal(v)
32 case constant.String:
33 return constant.StringVal(v)
34 case constant.Int:
35 return IntVal(n.Type(), v)
36 case constant.Float:
37 return Float64Val(v)
38 case constant.Complex:
39 return complex(Float64Val(constant.Real(v)), Float64Val(constant.Imag(v)))
40 }
41 }
42
43
44
45 func IntVal(t *types.Type, v constant.Value) int64 {
46 if t.IsUnsigned() {
47 if x, ok := constant.Uint64Val(v); ok {
48 return int64(x)
49 }
50 } else {
51 if x, ok := constant.Int64Val(v); ok {
52 return x
53 }
54 }
55 base.Fatalf("%v out of range for %v", v, t)
56 panic("unreachable")
57 }
58
59 func Float64Val(v constant.Value) float64 {
60 if x, _ := constant.Float64Val(v); !math.IsInf(x, 0) {
61 return x + 0
62 }
63 base.Fatalf("bad float64 value: %v", v)
64 panic("unreachable")
65 }
66
67 func AssertValidTypeForConst(t *types.Type, v constant.Value) {
68 if !ValidTypeForConst(t, v) {
69 base.Fatalf("%v (%v) does not represent %v (%v)", t, t.Kind(), v, v.Kind())
70 }
71 }
72
73 func ValidTypeForConst(t *types.Type, v constant.Value) bool {
74 switch v.Kind() {
75 case constant.Unknown:
76 return OKForConst[t.Kind()]
77 case constant.Bool:
78 return t.IsBoolean()
79 case constant.String:
80 return t.IsString()
81 case constant.Int:
82 return t.IsInteger()
83 case constant.Float:
84 return t.IsFloat()
85 case constant.Complex:
86 return t.IsComplex()
87 }
88
89 base.Fatalf("unexpected constant kind: %v", v)
90 panic("unreachable")
91 }
92
93
94 func NewLiteral(v constant.Value) Node {
95 return NewBasicLit(base.Pos, v)
96 }
97
98 func idealType(ct constant.Kind) *types.Type {
99 switch ct {
100 case constant.String:
101 return types.UntypedString
102 case constant.Bool:
103 return types.UntypedBool
104 case constant.Int:
105 return types.UntypedInt
106 case constant.Float:
107 return types.UntypedFloat
108 case constant.Complex:
109 return types.UntypedComplex
110 }
111 base.Fatalf("unexpected Ctype: %v", ct)
112 return nil
113 }
114
115 var OKForConst [types.NTYPE]bool
116
117
118 func CanInt64(n Node) bool {
119 if !IsConst(n, constant.Int) {
120 return false
121 }
122
123
124
125 _, ok := constant.Int64Val(n.Val())
126 return ok
127 }
128
129
130
131 func Int64Val(n Node) int64 {
132 if !IsConst(n, constant.Int) {
133 base.Fatalf("Int64Val(%v)", n)
134 }
135 x, ok := constant.Int64Val(n.Val())
136 if !ok {
137 base.Fatalf("Int64Val(%v)", n)
138 }
139 return x
140 }
141
142
143
144 func Uint64Val(n Node) uint64 {
145 if !IsConst(n, constant.Int) {
146 base.Fatalf("Uint64Val(%v)", n)
147 }
148 x, ok := constant.Uint64Val(n.Val())
149 if !ok {
150 base.Fatalf("Uint64Val(%v)", n)
151 }
152 return x
153 }
154
155
156
157 func BoolVal(n Node) bool {
158 if !IsConst(n, constant.Bool) {
159 base.Fatalf("BoolVal(%v)", n)
160 }
161 return constant.BoolVal(n.Val())
162 }
163
164
165
166 func StringVal(n Node) string {
167 if !IsConst(n, constant.String) {
168 base.Fatalf("StringVal(%v)", n)
169 }
170 return constant.StringVal(n.Val())
171 }
172
View as plain text