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