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