Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / go / ssa / const.go
1 // Copyright 2013 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
5 package ssa
6
7 // This file defines the Const SSA value type.
8
9 import (
10         "fmt"
11         "go/constant"
12         "go/token"
13         "go/types"
14         "strconv"
15 )
16
17 // NewConst returns a new constant of the specified value and type.
18 // val must be valid according to the specification of Const.Value.
19 //
20 func NewConst(val constant.Value, typ types.Type) *Const {
21         return &Const{typ, val}
22 }
23
24 // intConst returns an 'int' constant that evaluates to i.
25 // (i is an int64 in case the host is narrower than the target.)
26 func intConst(i int64) *Const {
27         return NewConst(constant.MakeInt64(i), tInt)
28 }
29
30 // nilConst returns a nil constant of the specified type, which may
31 // be any reference type, including interfaces.
32 //
33 func nilConst(typ types.Type) *Const {
34         return NewConst(nil, typ)
35 }
36
37 // stringConst returns a 'string' constant that evaluates to s.
38 func stringConst(s string) *Const {
39         return NewConst(constant.MakeString(s), tString)
40 }
41
42 // zeroConst returns a new "zero" constant of the specified type,
43 // which must not be an array or struct type: the zero values of
44 // aggregates are well-defined but cannot be represented by Const.
45 //
46 func zeroConst(t types.Type) *Const {
47         switch t := t.(type) {
48         case *types.Basic:
49                 switch {
50                 case t.Info()&types.IsBoolean != 0:
51                         return NewConst(constant.MakeBool(false), t)
52                 case t.Info()&types.IsNumeric != 0:
53                         return NewConst(constant.MakeInt64(0), t)
54                 case t.Info()&types.IsString != 0:
55                         return NewConst(constant.MakeString(""), t)
56                 case t.Kind() == types.UnsafePointer:
57                         fallthrough
58                 case t.Kind() == types.UntypedNil:
59                         return nilConst(t)
60                 default:
61                         panic(fmt.Sprint("zeroConst for unexpected type:", t))
62                 }
63         case *types.Pointer, *types.Slice, *types.Interface, *types.Chan, *types.Map, *types.Signature:
64                 return nilConst(t)
65         case *types.Named:
66                 return NewConst(zeroConst(t.Underlying()).Value, t)
67         case *types.Array, *types.Struct, *types.Tuple:
68                 panic(fmt.Sprint("zeroConst applied to aggregate:", t))
69         }
70         panic(fmt.Sprint("zeroConst: unexpected ", t))
71 }
72
73 func (c *Const) RelString(from *types.Package) string {
74         var s string
75         if c.Value == nil {
76                 s = "nil"
77         } else if c.Value.Kind() == constant.String {
78                 s = constant.StringVal(c.Value)
79                 const max = 20
80                 // TODO(adonovan): don't cut a rune in half.
81                 if len(s) > max {
82                         s = s[:max-3] + "..." // abbreviate
83                 }
84                 s = strconv.Quote(s)
85         } else {
86                 s = c.Value.String()
87         }
88         return s + ":" + relType(c.Type(), from)
89 }
90
91 func (c *Const) Name() string {
92         return c.RelString(nil)
93 }
94
95 func (c *Const) String() string {
96         return c.Name()
97 }
98
99 func (c *Const) Type() types.Type {
100         return c.typ
101 }
102
103 func (c *Const) Referrers() *[]Instruction {
104         return nil
105 }
106
107 func (c *Const) Parent() *Function { return nil }
108
109 func (c *Const) Pos() token.Pos {
110         return token.NoPos
111 }
112
113 // IsNil returns true if this constant represents a typed or untyped nil value.
114 func (c *Const) IsNil() bool {
115         return c.Value == nil
116 }
117
118 // TODO(adonovan): move everything below into golang.org/x/tools/go/ssa/interp.
119
120 // Int64 returns the numeric value of this constant truncated to fit
121 // a signed 64-bit integer.
122 //
123 func (c *Const) Int64() int64 {
124         switch x := constant.ToInt(c.Value); x.Kind() {
125         case constant.Int:
126                 if i, ok := constant.Int64Val(x); ok {
127                         return i
128                 }
129                 return 0
130         case constant.Float:
131                 f, _ := constant.Float64Val(x)
132                 return int64(f)
133         }
134         panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
135 }
136
137 // Uint64 returns the numeric value of this constant truncated to fit
138 // an unsigned 64-bit integer.
139 //
140 func (c *Const) Uint64() uint64 {
141         switch x := constant.ToInt(c.Value); x.Kind() {
142         case constant.Int:
143                 if u, ok := constant.Uint64Val(x); ok {
144                         return u
145                 }
146                 return 0
147         case constant.Float:
148                 f, _ := constant.Float64Val(x)
149                 return uint64(f)
150         }
151         panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
152 }
153
154 // Float64 returns the numeric value of this constant truncated to fit
155 // a float64.
156 //
157 func (c *Const) Float64() float64 {
158         f, _ := constant.Float64Val(c.Value)
159         return f
160 }
161
162 // Complex128 returns the complex value of this constant truncated to
163 // fit a complex128.
164 //
165 func (c *Const) Complex128() complex128 {
166         re, _ := constant.Float64Val(constant.Real(c.Value))
167         im, _ := constant.Float64Val(constant.Imag(c.Value))
168         return complex(re, im)
169 }