...
1
2
3
4
5 package ssa
6
7
8
9
10 import (
11 "go/ast"
12 "go/token"
13 "go/types"
14
15 "golang.org/x/tools/internal/typeparams"
16 )
17
18
19
20
21 type lvalue interface {
22 store(fn *Function, v Value)
23 load(fn *Function) Value
24 address(fn *Function) Value
25 typ() types.Type
26 }
27
28
29 type address struct {
30 addr Value
31 pos token.Pos
32 expr ast.Expr
33 }
34
35 func (a *address) load(fn *Function) Value {
36 load := emitLoad(fn, a.addr)
37 load.pos = a.pos
38 return load
39 }
40
41 func (a *address) store(fn *Function, v Value) {
42 store := emitStore(fn, a.addr, v, a.pos)
43 if a.expr != nil {
44
45 emitDebugRef(fn, a.expr, store.Val, false)
46 }
47 }
48
49 func (a *address) address(fn *Function) Value {
50 if a.expr != nil {
51 emitDebugRef(fn, a.expr, a.addr, true)
52 }
53 return a.addr
54 }
55
56 func (a *address) typ() types.Type {
57 return typeparams.MustDeref(a.addr.Type())
58 }
59
60
61
62
63
64 type element struct {
65 m, k Value
66 t types.Type
67 pos token.Pos
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 elements are not addressable")
92 }
93
94 func (e *element) typ() types.Type {
95 return e.t
96 }
97
98
99
100
101
102
103 type lazyAddress struct {
104 addr func(fn *Function) Value
105 t types.Type
106 pos token.Pos
107 expr ast.Expr
108 }
109
110 func (l *lazyAddress) load(fn *Function) Value {
111 load := emitLoad(fn, l.addr(fn))
112 load.pos = l.pos
113 return load
114 }
115
116 func (l *lazyAddress) store(fn *Function, v Value) {
117 store := emitStore(fn, l.addr(fn), v, l.pos)
118 if l.expr != nil {
119
120 emitDebugRef(fn, l.expr, store.Val, false)
121 }
122 }
123
124 func (l *lazyAddress) address(fn *Function) Value {
125 addr := l.addr(fn)
126 if l.expr != nil {
127 emitDebugRef(fn, l.expr, addr, true)
128 }
129 return addr
130 }
131
132 func (l *lazyAddress) typ() types.Type { return l.t }
133
134
135
136 type blank struct{}
137
138 func (bl blank) load(fn *Function) Value {
139 panic("blank.load is illegal")
140 }
141
142 func (bl blank) store(fn *Function, v Value) {
143
144 }
145
146 func (bl blank) address(fn *Function) Value {
147 panic("blank var is not addressable")
148 }
149
150 func (bl blank) typ() types.Type {
151
152
153
154 panic("blank.typ is unimplemented")
155 }
156
View as plain text