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 / lvalue.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 // lvalues are the union of addressable expressions and map-index
8 // expressions.
9
10 import (
11         "go/ast"
12         "go/token"
13         "go/types"
14 )
15
16 // An lvalue represents an assignable location that may appear on the
17 // left-hand side of an assignment.  This is a generalization of a
18 // pointer to permit updates to elements of maps.
19 //
20 type lvalue interface {
21         store(fn *Function, v Value) // stores v into the location
22         load(fn *Function) Value     // loads the contents of the location
23         address(fn *Function) Value  // address of the location
24         typ() types.Type             // returns the type of the location
25 }
26
27 // An address is an lvalue represented by a true pointer.
28 type address struct {
29         addr Value
30         pos  token.Pos // source position
31         expr ast.Expr  // source syntax of the value (not address) [debug mode]
32 }
33
34 func (a *address) load(fn *Function) Value {
35         load := emitLoad(fn, a.addr)
36         load.pos = a.pos
37         return load
38 }
39
40 func (a *address) store(fn *Function, v Value) {
41         store := emitStore(fn, a.addr, v, a.pos)
42         if a.expr != nil {
43                 // store.Val is v, converted for assignability.
44                 emitDebugRef(fn, a.expr, store.Val, false)
45         }
46 }
47
48 func (a *address) address(fn *Function) Value {
49         if a.expr != nil {
50                 emitDebugRef(fn, a.expr, a.addr, true)
51         }
52         return a.addr
53 }
54
55 func (a *address) typ() types.Type {
56         return deref(a.addr.Type())
57 }
58
59 // An element is an lvalue represented by m[k], the location of an
60 // element of a map or string.  These locations are not addressable
61 // since pointers cannot be formed from them, but they do support
62 // load(), and in the case of maps, store().
63 //
64 type element struct {
65         m, k Value      // map or string
66         t    types.Type // map element type or string byte type
67         pos  token.Pos  // source position of colon ({k:v}) or lbrack (m[k]=v)
68 }
69
70 func (e *element) load(fn *Function) Value {
71         l := &Lookup{
72                 X:     e.m,
73                 Index: e.k,
74         }
75         l.setPos(e.pos)
76         l.setType(e.t)
77         return fn.emit(l)
78 }
79
80 func (e *element) store(fn *Function, v Value) {
81         up := &MapUpdate{
82                 Map:   e.m,
83                 Key:   e.k,
84                 Value: emitConv(fn, v, e.t),
85         }
86         up.pos = e.pos
87         fn.emit(up)
88 }
89
90 func (e *element) address(fn *Function) Value {
91         panic("map/string elements are not addressable")
92 }
93
94 func (e *element) typ() types.Type {
95         return e.t
96 }
97
98 // A blank is a dummy variable whose name is "_".
99 // It is not reified: loads are illegal and stores are ignored.
100 //
101 type blank struct{}
102
103 func (bl blank) load(fn *Function) Value {
104         panic("blank.load is illegal")
105 }
106
107 func (bl blank) store(fn *Function, v Value) {
108         // no-op
109 }
110
111 func (bl blank) address(fn *Function) Value {
112         panic("blank var is not addressable")
113 }
114
115 func (bl blank) typ() types.Type {
116         // This should be the type of the blank Ident; the typechecker
117         // doesn't provide this yet, but fortunately, we don't need it
118         // yet either.
119         panic("blank.typ is unimplemented")
120 }