1
2
3
4
5 package ir
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/types"
10 "cmd/internal/obj"
11 "cmd/internal/objabi"
12 "cmd/internal/src"
13 "fmt"
14
15 "go/constant"
16 )
17
18
19 type Ident struct {
20 miniExpr
21 sym *types.Sym
22 }
23
24 func NewIdent(pos src.XPos, sym *types.Sym) *Ident {
25 n := new(Ident)
26 n.op = ONONAME
27 n.pos = pos
28 n.sym = sym
29 return n
30 }
31
32 func (n *Ident) Sym() *types.Sym { return n.sym }
33
34
35 type Name struct {
36 miniExpr
37 BuiltinOp Op
38 Class Class
39 pragma PragmaFlag
40 flags bitset16
41 DictIndex uint16
42 sym *types.Sym
43 Func *Func
44 Offset_ int64
45 val constant.Value
46 Opt interface{}
47 Embed *[]Embed
48
49
50
51
52
53
54
55 Defn Node
56
57
58 Curfn *Func
59
60 Heapaddr *Name
61
62
63
64 Outer *Name
65 }
66
67 func (n *Name) isExpr() {}
68
69 func (n *Name) copy() Node { panic(n.no("copy")) }
70 func (n *Name) doChildren(do func(Node) bool) bool { return false }
71 func (n *Name) editChildren(edit func(Node) Node) {}
72 func (n *Name) editChildrenWithHidden(edit func(Node) Node) {}
73
74
75
76 func (n *Name) RecordFrameOffset(offset int64) {
77 n.SetFrameOffset(offset)
78 }
79
80
81
82 func NewNameAt(pos src.XPos, sym *types.Sym, typ *types.Type) *Name {
83 if sym == nil {
84 base.Fatalf("NewNameAt nil")
85 }
86 n := newNameAt(pos, ONAME, sym)
87 if typ != nil {
88 n.SetType(typ)
89 n.SetTypecheck(1)
90 }
91 return n
92 }
93
94
95
96 func NewBuiltin(sym *types.Sym, op Op) *Name {
97 n := newNameAt(src.NoXPos, ONAME, sym)
98 n.BuiltinOp = op
99 n.SetTypecheck(1)
100 sym.Def = n
101 return n
102 }
103
104
105 func (fn *Func) NewLocal(pos src.XPos, sym *types.Sym, typ *types.Type) *Name {
106 if fn.Dcl == nil {
107 base.FatalfAt(pos, "must call DeclParams on %v first", fn)
108 }
109
110 n := NewNameAt(pos, sym, typ)
111 n.Class = PAUTO
112 n.Curfn = fn
113 fn.Dcl = append(fn.Dcl, n)
114 return n
115 }
116
117
118
119 func NewDeclNameAt(pos src.XPos, op Op, sym *types.Sym) *Name {
120 if sym == nil {
121 base.Fatalf("NewDeclNameAt nil")
122 }
123 switch op {
124 case ONAME, OTYPE, OLITERAL:
125
126 default:
127 base.Fatalf("NewDeclNameAt op %v", op)
128 }
129 return newNameAt(pos, op, sym)
130 }
131
132
133 func NewConstAt(pos src.XPos, sym *types.Sym, typ *types.Type, val constant.Value) *Name {
134 if sym == nil {
135 base.Fatalf("NewConstAt nil")
136 }
137 n := newNameAt(pos, OLITERAL, sym)
138 n.SetType(typ)
139 n.SetTypecheck(1)
140 n.SetVal(val)
141 return n
142 }
143
144
145 func newNameAt(pos src.XPos, op Op, sym *types.Sym) *Name {
146 n := new(Name)
147 n.op = op
148 n.pos = pos
149 n.sym = sym
150 return n
151 }
152
153 func (n *Name) Name() *Name { return n }
154 func (n *Name) Sym() *types.Sym { return n.sym }
155 func (n *Name) SetSym(x *types.Sym) { n.sym = x }
156 func (n *Name) SubOp() Op { return n.BuiltinOp }
157 func (n *Name) SetSubOp(x Op) { n.BuiltinOp = x }
158 func (n *Name) SetFunc(x *Func) { n.Func = x }
159 func (n *Name) FrameOffset() int64 { return n.Offset_ }
160 func (n *Name) SetFrameOffset(x int64) { n.Offset_ = x }
161
162 func (n *Name) Linksym() *obj.LSym { return n.sym.Linksym() }
163 func (n *Name) LinksymABI(abi obj.ABI) *obj.LSym { return n.sym.LinksymABI(abi) }
164
165 func (*Name) CanBeNtype() {}
166 func (*Name) CanBeAnSSASym() {}
167 func (*Name) CanBeAnSSAAux() {}
168
169
170 func (n *Name) Pragma() PragmaFlag { return n.pragma }
171
172
173 func (n *Name) SetPragma(flag PragmaFlag) { n.pragma = flag }
174
175
176 func (n *Name) Alias() bool { return n.flags&nameAlias != 0 }
177
178
179 func (n *Name) SetAlias(alias bool) { n.flags.set(nameAlias, alias) }
180
181 const (
182 nameReadonly = 1 << iota
183 nameByval
184 nameNeedzero
185 nameAutoTemp
186 nameUsed
187 nameIsClosureVar
188 nameIsOutputParamHeapAddr
189 nameIsOutputParamInRegisters
190 nameAddrtaken
191 nameInlFormal
192 nameInlLocal
193 nameOpenDeferSlot
194 nameLibfuzzer8BitCounter
195 nameCoverageAuxVar
196 nameAlias
197 nameNonMergeable
198 )
199
200 func (n *Name) Readonly() bool { return n.flags&nameReadonly != 0 }
201 func (n *Name) Needzero() bool { return n.flags&nameNeedzero != 0 }
202 func (n *Name) AutoTemp() bool { return n.flags&nameAutoTemp != 0 }
203 func (n *Name) Used() bool { return n.flags&nameUsed != 0 }
204 func (n *Name) IsClosureVar() bool { return n.flags&nameIsClosureVar != 0 }
205 func (n *Name) IsOutputParamHeapAddr() bool { return n.flags&nameIsOutputParamHeapAddr != 0 }
206 func (n *Name) IsOutputParamInRegisters() bool { return n.flags&nameIsOutputParamInRegisters != 0 }
207 func (n *Name) Addrtaken() bool { return n.flags&nameAddrtaken != 0 }
208 func (n *Name) InlFormal() bool { return n.flags&nameInlFormal != 0 }
209 func (n *Name) InlLocal() bool { return n.flags&nameInlLocal != 0 }
210 func (n *Name) OpenDeferSlot() bool { return n.flags&nameOpenDeferSlot != 0 }
211 func (n *Name) Libfuzzer8BitCounter() bool { return n.flags&nameLibfuzzer8BitCounter != 0 }
212 func (n *Name) CoverageAuxVar() bool { return n.flags&nameCoverageAuxVar != 0 }
213 func (n *Name) NonMergeable() bool { return n.flags&nameNonMergeable != 0 }
214
215 func (n *Name) setReadonly(b bool) { n.flags.set(nameReadonly, b) }
216 func (n *Name) SetNeedzero(b bool) { n.flags.set(nameNeedzero, b) }
217 func (n *Name) SetAutoTemp(b bool) { n.flags.set(nameAutoTemp, b) }
218 func (n *Name) SetUsed(b bool) { n.flags.set(nameUsed, b) }
219 func (n *Name) SetIsClosureVar(b bool) { n.flags.set(nameIsClosureVar, b) }
220 func (n *Name) SetIsOutputParamHeapAddr(b bool) { n.flags.set(nameIsOutputParamHeapAddr, b) }
221 func (n *Name) SetIsOutputParamInRegisters(b bool) { n.flags.set(nameIsOutputParamInRegisters, b) }
222 func (n *Name) SetAddrtaken(b bool) { n.flags.set(nameAddrtaken, b) }
223 func (n *Name) SetInlFormal(b bool) { n.flags.set(nameInlFormal, b) }
224 func (n *Name) SetInlLocal(b bool) { n.flags.set(nameInlLocal, b) }
225 func (n *Name) SetOpenDeferSlot(b bool) { n.flags.set(nameOpenDeferSlot, b) }
226 func (n *Name) SetLibfuzzer8BitCounter(b bool) { n.flags.set(nameLibfuzzer8BitCounter, b) }
227 func (n *Name) SetCoverageAuxVar(b bool) { n.flags.set(nameCoverageAuxVar, b) }
228 func (n *Name) SetNonMergeable(b bool) { n.flags.set(nameNonMergeable, b) }
229
230
231 func (n *Name) OnStack() bool {
232 if n.Op() == ONAME {
233 switch n.Class {
234 case PPARAM, PPARAMOUT, PAUTO:
235 return n.Esc() != EscHeap
236 case PEXTERN, PAUTOHEAP:
237 return false
238 }
239 }
240
241
242 panic(fmt.Sprintf("%v: not a variable: %v", base.FmtPos(n.Pos()), n))
243 }
244
245
246 func (n *Name) MarkReadonly() {
247 if n.Op() != ONAME {
248 base.Fatalf("Node.MarkReadonly %v", n.Op())
249 }
250 n.setReadonly(true)
251
252
253
254 n.Linksym().Type = objabi.SRODATA
255 }
256
257
258 func (n *Name) Val() constant.Value {
259 if n.val == nil {
260 return constant.MakeUnknown()
261 }
262 return n.val
263 }
264
265
266 func (n *Name) SetVal(v constant.Value) {
267 if n.op != OLITERAL {
268 panic(n.no("SetVal"))
269 }
270 AssertValidTypeForConst(n.Type(), v)
271 n.val = v
272 }
273
274
275
276
277
278 func (n *Name) Canonical() *Name {
279 if n.IsClosureVar() && n.Defn != nil {
280 n = n.Defn.(*Name)
281 }
282 return n
283 }
284
285 func (n *Name) SetByval(b bool) {
286 if n.Canonical() != n {
287 base.Fatalf("SetByval called on non-canonical variable: %v", n)
288 }
289 n.flags.set(nameByval, b)
290 }
291
292 func (n *Name) Byval() bool {
293
294
295 return n.Canonical().flags&nameByval != 0
296 }
297
298
299
300 func NewClosureVar(pos src.XPos, fn *Func, n *Name) *Name {
301 switch n.Class {
302 case PAUTO, PPARAM, PPARAMOUT, PAUTOHEAP:
303
304 default:
305
306 base.Fatalf("NewClosureVar: %+v", n)
307 }
308
309 c := NewNameAt(pos, n.Sym(), n.Type())
310 c.Curfn = fn
311 c.Class = PAUTOHEAP
312 c.SetIsClosureVar(true)
313 c.Defn = n.Canonical()
314 c.Outer = n
315
316 fn.ClosureVars = append(fn.ClosureVars, c)
317
318 return c
319 }
320
321
322
323 func NewHiddenParam(pos src.XPos, fn *Func, sym *types.Sym, typ *types.Type) *Name {
324 if fn.OClosure != nil {
325 base.FatalfAt(fn.Pos(), "cannot add hidden parameters to closures")
326 }
327
328 fn.SetNeedctxt(true)
329
330
331
332 fake := NewNameAt(pos, sym, typ)
333 fake.Class = PPARAM
334 fake.SetByval(true)
335
336 return NewClosureVar(pos, fn, fake)
337 }
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354 func SameSource(n1, n2 Node) bool {
355 return n1 == n2
356 }
357
358
359
360 func Uses(x Node, v *Name) bool {
361 if v == nil || v.Op() != ONAME {
362 base.Fatalf("RefersTo bad Name: %v", v)
363 }
364 return x.Op() == ONAME && x.Name() == v
365 }
366
367
368
369 func DeclaredBy(x, stmt Node) bool {
370 if stmt == nil {
371 base.Fatalf("DeclaredBy nil")
372 }
373 return x.Op() == ONAME && SameSource(x.Name().Defn, stmt)
374 }
375
376
377
378
379 type Class uint8
380
381
382 const (
383 Pxxx Class = iota
384 PEXTERN
385 PAUTO
386 PAUTOHEAP
387 PPARAM
388 PPARAMOUT
389 PTYPEPARAM
390 PFUNC
391
392
393 _ = uint((1 << 3) - iota)
394 )
395
396 type Embed struct {
397 Pos src.XPos
398 Patterns []string
399 }
400
View as plain text