1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package ir
6
7import (
8	"go/constant"
9
10	"cmd/compile/internal/base"
11	"cmd/compile/internal/types"
12)
13
14func ConstType(n Node) constant.Kind {
15	if n == nil || n.Op() != OLITERAL {
16		return constant.Unknown
17	}
18	return n.Val().Kind()
19}
20
21// IntVal returns v converted to int64.
22// Note: if t is uint64, very large values will be converted to negative int64.
23func IntVal(t *types.Type, v constant.Value) int64 {
24	if t.IsUnsigned() {
25		if x, ok := constant.Uint64Val(v); ok {
26			return int64(x)
27		}
28	} else {
29		if x, ok := constant.Int64Val(v); ok {
30			return x
31		}
32	}
33	base.Fatalf("%v out of range for %v", v, t)
34	panic("unreachable")
35}
36
37func AssertValidTypeForConst(t *types.Type, v constant.Value) {
38	if !ValidTypeForConst(t, v) {
39		base.Fatalf("%v (%v) does not represent %v (%v)", t, t.Kind(), v, v.Kind())
40	}
41}
42
43func ValidTypeForConst(t *types.Type, v constant.Value) bool {
44	switch v.Kind() {
45	case constant.Unknown:
46		return OKForConst[t.Kind()]
47	case constant.Bool:
48		return t.IsBoolean()
49	case constant.String:
50		return t.IsString()
51	case constant.Int:
52		return t.IsInteger()
53	case constant.Float:
54		return t.IsFloat()
55	case constant.Complex:
56		return t.IsComplex()
57	}
58
59	base.Fatalf("unexpected constant kind: %v", v)
60	panic("unreachable")
61}
62
63var OKForConst [types.NTYPE]bool
64
65// Int64Val returns n as an int64.
66// n must be an integer or rune constant.
67func Int64Val(n Node) int64 {
68	if !IsConst(n, constant.Int) {
69		base.Fatalf("Int64Val(%v)", n)
70	}
71	x, ok := constant.Int64Val(n.Val())
72	if !ok {
73		base.Fatalf("Int64Val(%v)", n)
74	}
75	return x
76}
77
78// Uint64Val returns n as a uint64.
79// n must be an integer or rune constant.
80func Uint64Val(n Node) uint64 {
81	if !IsConst(n, constant.Int) {
82		base.Fatalf("Uint64Val(%v)", n)
83	}
84	x, ok := constant.Uint64Val(n.Val())
85	if !ok {
86		base.Fatalf("Uint64Val(%v)", n)
87	}
88	return x
89}
90
91// BoolVal returns n as a bool.
92// n must be a boolean constant.
93func BoolVal(n Node) bool {
94	if !IsConst(n, constant.Bool) {
95		base.Fatalf("BoolVal(%v)", n)
96	}
97	return constant.BoolVal(n.Val())
98}
99
100// StringVal returns the value of a literal string Node as a string.
101// n must be a string constant.
102func StringVal(n Node) string {
103	if !IsConst(n, constant.String) {
104		base.Fatalf("StringVal(%v)", n)
105	}
106	return constant.StringVal(n.Val())
107}
108