Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / ssa / emit.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 // Helpers for emitting SSA instructions.
8
9 import (
10         "fmt"
11         "go/ast"
12         "go/token"
13         "go/types"
14 )
15
16 // emitNew emits to f a new (heap Alloc) instruction allocating an
17 // object of type typ.  pos is the optional source location.
18 //
19 func emitNew(f *Function, typ types.Type, pos token.Pos) *Alloc {
20         v := &Alloc{Heap: true}
21         v.setType(types.NewPointer(typ))
22         v.setPos(pos)
23         f.emit(v)
24         return v
25 }
26
27 // emitLoad emits to f an instruction to load the address addr into a
28 // new temporary, and returns the value so defined.
29 //
30 func emitLoad(f *Function, addr Value) *UnOp {
31         v := &UnOp{Op: token.MUL, X: addr}
32         v.setType(deref(addr.Type()))
33         f.emit(v)
34         return v
35 }
36
37 // emitDebugRef emits to f a DebugRef pseudo-instruction associating
38 // expression e with value v.
39 //
40 func emitDebugRef(f *Function, e ast.Expr, v Value, isAddr bool) {
41         if !f.debugInfo() {
42                 return // debugging not enabled
43         }
44         if v == nil || e == nil {
45                 panic("nil")
46         }
47         var obj types.Object
48         e = unparen(e)
49         if id, ok := e.(*ast.Ident); ok {
50                 if isBlankIdent(id) {
51                         return
52                 }
53                 obj = f.Pkg.objectOf(id)
54                 switch obj.(type) {
55                 case *types.Nil, *types.Const, *types.Builtin:
56                         return
57                 }
58         }
59         f.emit(&DebugRef{
60                 X:      v,
61                 Expr:   e,
62                 IsAddr: isAddr,
63                 object: obj,
64         })
65 }
66
67 // emitArith emits to f code to compute the binary operation op(x, y)
68 // where op is an eager shift, logical or arithmetic operation.
69 // (Use emitCompare() for comparisons and Builder.logicalBinop() for
70 // non-eager operations.)
71 //
72 func emitArith(f *Function, op token.Token, x, y Value, t types.Type, pos token.Pos) Value {
73         switch op {
74         case token.SHL, token.SHR:
75                 x = emitConv(f, x, t)
76                 // y may be signed or an 'untyped' constant.
77                 // TODO(adonovan): whence signed values?
78                 if b, ok := y.Type().Underlying().(*types.Basic); ok && b.Info()&types.IsUnsigned == 0 {
79                         y = emitConv(f, y, types.Typ[types.Uint64])
80                 }
81
82         case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT:
83                 x = emitConv(f, x, t)
84                 y = emitConv(f, y, t)
85
86         default:
87                 panic("illegal op in emitArith: " + op.String())
88
89         }
90         v := &BinOp{
91                 Op: op,
92                 X:  x,
93                 Y:  y,
94         }
95         v.setPos(pos)
96         v.setType(t)
97         return f.emit(v)
98 }
99
100 // emitCompare emits to f code compute the boolean result of
101 // comparison comparison 'x op y'.
102 //
103 func emitCompare(f *Function, op token.Token, x, y Value, pos token.Pos) Value {
104         xt := x.Type().Underlying()
105         yt := y.Type().Underlying()
106
107         // Special case to optimise a tagless SwitchStmt so that
108         // these are equivalent
109         //   switch { case e: ...}
110         //   switch true { case e: ... }
111         //   if e==true { ... }
112         // even in the case when e's type is an interface.
113         // TODO(adonovan): opt: generalise to x==true, false!=y, etc.
114         if x == vTrue && op == token.EQL {
115                 if yt, ok := yt.(*types.Basic); ok && yt.Info()&types.IsBoolean != 0 {
116                         return y
117                 }
118         }
119
120         if types.Identical(xt, yt) {
121                 // no conversion necessary
122         } else if _, ok := xt.(*types.Interface); ok {
123                 y = emitConv(f, y, x.Type())
124         } else if _, ok := yt.(*types.Interface); ok {
125                 x = emitConv(f, x, y.Type())
126         } else if _, ok := x.(*Const); ok {
127                 x = emitConv(f, x, y.Type())
128         } else if _, ok := y.(*Const); ok {
129                 y = emitConv(f, y, x.Type())
130         } else {
131                 // other cases, e.g. channels.  No-op.
132         }
133
134         v := &BinOp{
135                 Op: op,
136                 X:  x,
137                 Y:  y,
138         }
139         v.setPos(pos)
140         v.setType(tBool)
141         return f.emit(v)
142 }
143
144 // isValuePreserving returns true if a conversion from ut_src to
145 // ut_dst is value-preserving, i.e. just a change of type.
146 // Precondition: neither argument is a named type.
147 //
148 func isValuePreserving(ut_src, ut_dst types.Type) bool {
149         // Identical underlying types?
150         if structTypesIdentical(ut_dst, ut_src) {
151                 return true
152         }
153
154         switch ut_dst.(type) {
155         case *types.Chan:
156                 // Conversion between channel types?
157                 _, ok := ut_src.(*types.Chan)
158                 return ok
159
160         case *types.Pointer:
161                 // Conversion between pointers with identical base types?
162                 _, ok := ut_src.(*types.Pointer)
163                 return ok
164         }
165         return false
166 }
167
168 // emitConv emits to f code to convert Value val to exactly type typ,
169 // and returns the converted value.  Implicit conversions are required
170 // by language assignability rules in assignments, parameter passing,
171 // etc.  Conversions cannot fail dynamically.
172 //
173 func emitConv(f *Function, val Value, typ types.Type) Value {
174         t_src := val.Type()
175
176         // Identical types?  Conversion is a no-op.
177         if types.Identical(t_src, typ) {
178                 return val
179         }
180
181         ut_dst := typ.Underlying()
182         ut_src := t_src.Underlying()
183
184         // Just a change of type, but not value or representation?
185         if isValuePreserving(ut_src, ut_dst) {
186                 c := &ChangeType{X: val}
187                 c.setType(typ)
188                 return f.emit(c)
189         }
190
191         // Conversion to, or construction of a value of, an interface type?
192         if _, ok := ut_dst.(*types.Interface); ok {
193                 // Assignment from one interface type to another?
194                 if _, ok := ut_src.(*types.Interface); ok {
195                         c := &ChangeInterface{X: val}
196                         c.setType(typ)
197                         return f.emit(c)
198                 }
199
200                 // Untyped nil constant?  Return interface-typed nil constant.
201                 if ut_src == tUntypedNil {
202                         return nilConst(typ)
203                 }
204
205                 // Convert (non-nil) "untyped" literals to their default type.
206                 if t, ok := ut_src.(*types.Basic); ok && t.Info()&types.IsUntyped != 0 {
207                         val = emitConv(f, val, types.Default(ut_src))
208                 }
209
210                 f.Pkg.Prog.needMethodsOf(val.Type())
211                 mi := &MakeInterface{X: val}
212                 mi.setType(typ)
213                 return f.emit(mi)
214         }
215
216         // Conversion of a compile-time constant value?
217         if c, ok := val.(*Const); ok {
218                 if _, ok := ut_dst.(*types.Basic); ok || c.IsNil() {
219                         // Conversion of a compile-time constant to
220                         // another constant type results in a new
221                         // constant of the destination type and
222                         // (initially) the same abstract value.
223                         // We don't truncate the value yet.
224                         return NewConst(c.Value, typ)
225                 }
226
227                 // We're converting from constant to non-constant type,
228                 // e.g. string -> []byte/[]rune.
229         }
230
231         // A representation-changing conversion?
232         // At least one of {ut_src,ut_dst} must be *Basic.
233         // (The other may be []byte or []rune.)
234         _, ok1 := ut_src.(*types.Basic)
235         _, ok2 := ut_dst.(*types.Basic)
236         if ok1 || ok2 {
237                 c := &Convert{X: val}
238                 c.setType(typ)
239                 return f.emit(c)
240         }
241
242         panic(fmt.Sprintf("in %s: cannot convert %s (%s) to %s", f, val, val.Type(), typ))
243 }
244
245 // emitStore emits to f an instruction to store value val at location
246 // addr, applying implicit conversions as required by assignability rules.
247 //
248 func emitStore(f *Function, addr, val Value, pos token.Pos) *Store {
249         s := &Store{
250                 Addr: addr,
251                 Val:  emitConv(f, val, deref(addr.Type())),
252                 pos:  pos,
253         }
254         f.emit(s)
255         return s
256 }
257
258 // emitJump emits to f a jump to target, and updates the control-flow graph.
259 // Postcondition: f.currentBlock is nil.
260 //
261 func emitJump(f *Function, target *BasicBlock) {
262         b := f.currentBlock
263         b.emit(new(Jump))
264         addEdge(b, target)
265         f.currentBlock = nil
266 }
267
268 // emitIf emits to f a conditional jump to tblock or fblock based on
269 // cond, and updates the control-flow graph.
270 // Postcondition: f.currentBlock is nil.
271 //
272 func emitIf(f *Function, cond Value, tblock, fblock *BasicBlock) {
273         b := f.currentBlock
274         b.emit(&If{Cond: cond})
275         addEdge(b, tblock)
276         addEdge(b, fblock)
277         f.currentBlock = nil
278 }
279
280 // emitExtract emits to f an instruction to extract the index'th
281 // component of tuple.  It returns the extracted value.
282 //
283 func emitExtract(f *Function, tuple Value, index int) Value {
284         e := &Extract{Tuple: tuple, Index: index}
285         e.setType(tuple.Type().(*types.Tuple).At(index).Type())
286         return f.emit(e)
287 }
288
289 // emitTypeAssert emits to f a type assertion value := x.(t) and
290 // returns the value.  x.Type() must be an interface.
291 //
292 func emitTypeAssert(f *Function, x Value, t types.Type, pos token.Pos) Value {
293         a := &TypeAssert{X: x, AssertedType: t}
294         a.setPos(pos)
295         a.setType(t)
296         return f.emit(a)
297 }
298
299 // emitTypeTest emits to f a type test value,ok := x.(t) and returns
300 // a (value, ok) tuple.  x.Type() must be an interface.
301 //
302 func emitTypeTest(f *Function, x Value, t types.Type, pos token.Pos) Value {
303         a := &TypeAssert{
304                 X:            x,
305                 AssertedType: t,
306                 CommaOk:      true,
307         }
308         a.setPos(pos)
309         a.setType(types.NewTuple(
310                 newVar("value", t),
311                 varOk,
312         ))
313         return f.emit(a)
314 }
315
316 // emitTailCall emits to f a function call in tail position.  The
317 // caller is responsible for all fields of 'call' except its type.
318 // Intended for wrapper methods.
319 // Precondition: f does/will not use deferred procedure calls.
320 // Postcondition: f.currentBlock is nil.
321 //
322 func emitTailCall(f *Function, call *Call) {
323         tresults := f.Signature.Results()
324         nr := tresults.Len()
325         if nr == 1 {
326                 call.typ = tresults.At(0).Type()
327         } else {
328                 call.typ = tresults
329         }
330         tuple := f.emit(call)
331         var ret Return
332         switch nr {
333         case 0:
334                 // no-op
335         case 1:
336                 ret.Results = []Value{tuple}
337         default:
338                 for i := 0; i < nr; i++ {
339                         v := emitExtract(f, tuple, i)
340                         // TODO(adonovan): in principle, this is required:
341                         //   v = emitConv(f, o.Type, f.Signature.Results[i].Type)
342                         // but in practice emitTailCall is only used when
343                         // the types exactly match.
344                         ret.Results = append(ret.Results, v)
345                 }
346         }
347         f.emit(&ret)
348         f.currentBlock = nil
349 }
350
351 // emitImplicitSelections emits to f code to apply the sequence of
352 // implicit field selections specified by indices to base value v, and
353 // returns the selected value.
354 //
355 // If v is the address of a struct, the result will be the address of
356 // a field; if it is the value of a struct, the result will be the
357 // value of a field.
358 //
359 func emitImplicitSelections(f *Function, v Value, indices []int) Value {
360         for _, index := range indices {
361                 fld := deref(v.Type()).Underlying().(*types.Struct).Field(index)
362
363                 if isPointer(v.Type()) {
364                         instr := &FieldAddr{
365                                 X:     v,
366                                 Field: index,
367                         }
368                         instr.setType(types.NewPointer(fld.Type()))
369                         v = f.emit(instr)
370                         // Load the field's value iff indirectly embedded.
371                         if isPointer(fld.Type()) {
372                                 v = emitLoad(f, v)
373                         }
374                 } else {
375                         instr := &Field{
376                                 X:     v,
377                                 Field: index,
378                         }
379                         instr.setType(fld.Type())
380                         v = f.emit(instr)
381                 }
382         }
383         return v
384 }
385
386 // emitFieldSelection emits to f code to select the index'th field of v.
387 //
388 // If wantAddr, the input must be a pointer-to-struct and the result
389 // will be the field's address; otherwise the result will be the
390 // field's value.
391 // Ident id is used for position and debug info.
392 //
393 func emitFieldSelection(f *Function, v Value, index int, wantAddr bool, id *ast.Ident) Value {
394         fld := deref(v.Type()).Underlying().(*types.Struct).Field(index)
395         if isPointer(v.Type()) {
396                 instr := &FieldAddr{
397                         X:     v,
398                         Field: index,
399                 }
400                 instr.setPos(id.Pos())
401                 instr.setType(types.NewPointer(fld.Type()))
402                 v = f.emit(instr)
403                 // Load the field's value iff we don't want its address.
404                 if !wantAddr {
405                         v = emitLoad(f, v)
406                 }
407         } else {
408                 instr := &Field{
409                         X:     v,
410                         Field: index,
411                 }
412                 instr.setPos(id.Pos())
413                 instr.setType(fld.Type())
414                 v = f.emit(instr)
415         }
416         emitDebugRef(f, id, v, wantAddr)
417         return v
418 }
419
420 // zeroValue emits to f code to produce a zero value of type t,
421 // and returns it.
422 //
423 func zeroValue(f *Function, t types.Type) Value {
424         switch t.Underlying().(type) {
425         case *types.Struct, *types.Array:
426                 return emitLoad(f, f.addLocal(t, token.NoPos))
427         default:
428                 return zeroConst(t)
429         }
430 }
431
432 // createRecoverBlock emits to f a block of code to return after a
433 // recovered panic, and sets f.Recover to it.
434 //
435 // If f's result parameters are named, the code loads and returns
436 // their current values, otherwise it returns the zero values of their
437 // type.
438 //
439 // Idempotent.
440 //
441 func createRecoverBlock(f *Function) {
442         if f.Recover != nil {
443                 return // already created
444         }
445         saved := f.currentBlock
446
447         f.Recover = f.newBasicBlock("recover")
448         f.currentBlock = f.Recover
449
450         var results []Value
451         if f.namedResults != nil {
452                 // Reload NRPs to form value tuple.
453                 for _, r := range f.namedResults {
454                         results = append(results, emitLoad(f, r))
455                 }
456         } else {
457                 R := f.Signature.Results()
458                 for i, n := 0, R.Len(); i < n; i++ {
459                         T := R.At(i).Type()
460
461                         // Return zero value of each result type.
462                         results = append(results, zeroValue(f, T))
463                 }
464         }
465         f.emit(&Return{Results: results})
466
467         f.currentBlock = saved
468 }