...
1
2
3
4
5 package ssa
6
7
8
9
10 import (
11 "go/ast"
12 "go/token"
13 "go/types"
14 )
15
16
17
18
19 type lvalue interface {
20 store(fn *Function, v Value)
21 load(fn *Function) Value
22 address(fn *Function) Value
23 typ() types.Type
24 }
25
26
27 type address struct {
28 addr Value
29 pos token.Pos
30 expr ast.Expr
31 }
32
33 func (a *address) load(fn *Function) Value {
34 load := emitLoad(fn, a.addr)
35 load.pos = a.pos
36 return load
37 }
38
39 func (a *address) store(fn *Function, v Value) {
40 store := emitStore(fn, a.addr, v, a.pos)
41 if a.expr != nil {
42
43 emitDebugRef(fn, a.expr, store.Val, false)
44 }
45 }
46
47 func (a *address) address(fn *Function) Value {
48 if a.expr != nil {
49 emitDebugRef(fn, a.expr, a.addr, true)
50 }
51 return a.addr
52 }
53
54 func (a *address) typ() types.Type {
55 return deref(a.addr.Type())
56 }
57
58
59
60
61
62 type element struct {
63 m, k Value
64 t types.Type
65 pos token.Pos
66 }
67
68 func (e *element) load(fn *Function) Value {
69 l := &Lookup{
70 X: e.m,
71 Index: e.k,
72 }
73 l.setPos(e.pos)
74 l.setType(e.t)
75 return fn.emit(l)
76 }
77
78 func (e *element) store(fn *Function, v Value) {
79 up := &MapUpdate{
80 Map: e.m,
81 Key: e.k,
82 Value: emitConv(fn, v, e.t),
83 }
84 up.pos = e.pos
85 fn.emit(up)
86 }
87
88 func (e *element) address(fn *Function) Value {
89 panic("map elements are not addressable")
90 }
91
92 func (e *element) typ() types.Type {
93 return e.t
94 }
95
96
97
98
99
100
101 type lazyAddress struct {
102 addr func(fn *Function) Value
103 t types.Type
104 pos token.Pos
105 expr ast.Expr
106 }
107
108 func (l *lazyAddress) load(fn *Function) Value {
109 load := emitLoad(fn, l.addr(fn))
110 load.pos = l.pos
111 return load
112 }
113
114 func (l *lazyAddress) store(fn *Function, v Value) {
115 store := emitStore(fn, l.addr(fn), v, l.pos)
116 if l.expr != nil {
117
118 emitDebugRef(fn, l.expr, store.Val, false)
119 }
120 }
121
122 func (l *lazyAddress) address(fn *Function) Value {
123 addr := l.addr(fn)
124 if l.expr != nil {
125 emitDebugRef(fn, l.expr, addr, true)
126 }
127 return addr
128 }
129
130 func (l *lazyAddress) typ() types.Type { return l.t }
131
132
133
134 type blank struct{}
135
136 func (bl blank) load(fn *Function) Value {
137 panic("blank.load is illegal")
138 }
139
140 func (bl blank) store(fn *Function, v Value) {
141
142 }
143
144 func (bl blank) address(fn *Function) Value {
145 panic("blank var is not addressable")
146 }
147
148 func (bl blank) typ() types.Type {
149
150
151
152 panic("blank.typ is unimplemented")
153 }
154
View as plain text