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) 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 func (n *Name) Pragma() PragmaFlag { return n.pragma }
172
173
174 func (n *Name) SetPragma(flag PragmaFlag) { n.pragma = flag }
175
176
177 func (n *Name) Alias() bool { return n.flags&nameAlias != 0 }
178
179
180 func (n *Name) SetAlias(alias bool) { n.flags.set(nameAlias, alias) }
181
182 const (
183 nameReadonly = 1 << iota
184 nameByval
185 nameNeedzero
186 nameAutoTemp
187 nameUsed
188 nameIsClosureVar
189 nameIsOutputParamHeapAddr
190 nameIsOutputParamInRegisters
191 nameAddrtaken
192 nameInlFormal
193 nameInlLocal
194 nameOpenDeferSlot
195 nameLibfuzzer8BitCounter
196 nameCoverageAuxVar
197 nameAlias
198 nameNonMergeable
199 )
200
201 func (n *Name) Readonly() bool { return n.flags&nameReadonly != 0 }
202 func (n *Name) Needzero() bool { return n.flags&nameNeedzero != 0 }
203 func (n *Name) AutoTemp() bool { return n.flags&nameAutoTemp != 0 }
204 func (n *Name) Used() bool { return n.flags&nameUsed != 0 }
205 func (n *Name) IsClosureVar() bool { return n.flags&nameIsClosureVar != 0 }
206 func (n *Name) IsOutputParamHeapAddr() bool { return n.flags&nameIsOutputParamHeapAddr != 0 }
207 func (n *Name) IsOutputParamInRegisters() bool { return n.flags&nameIsOutputParamInRegisters != 0 }
208 func (n *Name) Addrtaken() bool { return n.flags&nameAddrtaken != 0 }
209 func (n *Name) InlFormal() bool { return n.flags&nameInlFormal != 0 }
210 func (n *Name) InlLocal() bool { return n.flags&nameInlLocal != 0 }
211 func (n *Name) OpenDeferSlot() bool { return n.flags&nameOpenDeferSlot != 0 }
212 func (n *Name) Libfuzzer8BitCounter() bool { return n.flags&nameLibfuzzer8BitCounter != 0 }
213 func (n *Name) CoverageAuxVar() bool { return n.flags&nameCoverageAuxVar != 0 }
214 func (n *Name) NonMergeable() bool { return n.flags&nameNonMergeable != 0 }
215
216 func (n *Name) setReadonly(b bool) { n.flags.set(nameReadonly, b) }
217 func (n *Name) SetNeedzero(b bool) { n.flags.set(nameNeedzero, b) }
218 func (n *Name) SetAutoTemp(b bool) { n.flags.set(nameAutoTemp, b) }
219 func (n *Name) SetUsed(b bool) { n.flags.set(nameUsed, b) }
220 func (n *Name) SetIsClosureVar(b bool) { n.flags.set(nameIsClosureVar, b) }
221 func (n *Name) SetIsOutputParamHeapAddr(b bool) { n.flags.set(nameIsOutputParamHeapAddr, b) }
222 func (n *Name) SetIsOutputParamInRegisters(b bool) { n.flags.set(nameIsOutputParamInRegisters, b) }
223 func (n *Name) SetAddrtaken(b bool) { n.flags.set(nameAddrtaken, b) }
224 func (n *Name) SetInlFormal(b bool) { n.flags.set(nameInlFormal, b) }
225 func (n *Name) SetInlLocal(b bool) { n.flags.set(nameInlLocal, b) }
226 func (n *Name) SetOpenDeferSlot(b bool) { n.flags.set(nameOpenDeferSlot, b) }
227 func (n *Name) SetLibfuzzer8BitCounter(b bool) { n.flags.set(nameLibfuzzer8BitCounter, b) }
228 func (n *Name) SetCoverageAuxVar(b bool) { n.flags.set(nameCoverageAuxVar, b) }
229 func (n *Name) SetNonMergeable(b bool) { n.flags.set(nameNonMergeable, b) }
230
231
232 func (n *Name) OnStack() bool {
233 if n.Op() == ONAME {
234 switch n.Class {
235 case PPARAM, PPARAMOUT, PAUTO:
236 return n.Esc() != EscHeap
237 case PEXTERN, PAUTOHEAP:
238 return false
239 }
240 }
241
242
243 panic(fmt.Sprintf("%v: not a variable: %v", base.FmtPos(n.Pos()), n))
244 }
245
246
247 func (n *Name) MarkReadonly() {
248 if n.Op() != ONAME {
249 base.Fatalf("Node.MarkReadonly %v", n.Op())
250 }
251 n.setReadonly(true)
252
253
254
255 n.Linksym().Type = objabi.SRODATA
256 }
257
258
259 func (n *Name) Val() constant.Value {
260 if n.val == nil {
261 return constant.MakeUnknown()
262 }
263 return n.val
264 }
265
266
267 func (n *Name) SetVal(v constant.Value) {
268 if n.op != OLITERAL {
269 panic(n.no("SetVal"))
270 }
271 AssertValidTypeForConst(n.Type(), v)
272 n.val = v
273 }
274
275
276
277
278
279 func (n *Name) Canonical() *Name {
280 if n.IsClosureVar() && n.Defn != nil {
281 n = n.Defn.(*Name)
282 }
283 return n
284 }
285
286 func (n *Name) SetByval(b bool) {
287 if n.Canonical() != n {
288 base.Fatalf("SetByval called on non-canonical variable: %v", n)
289 }
290 n.flags.set(nameByval, b)
291 }
292
293 func (n *Name) Byval() bool {
294
295
296 return n.Canonical().flags&nameByval != 0
297 }
298
299
300
301 func NewClosureVar(pos src.XPos, fn *Func, n *Name) *Name {
302 switch n.Class {
303 case PAUTO, PPARAM, PPARAMOUT, PAUTOHEAP:
304
305 default:
306
307 base.Fatalf("NewClosureVar: %+v", n)
308 }
309
310 c := NewNameAt(pos, n.Sym(), n.Type())
311 c.Curfn = fn
312 c.Class = PAUTOHEAP
313 c.SetIsClosureVar(true)
314 c.Defn = n.Canonical()
315 c.Outer = n
316
317 fn.ClosureVars = append(fn.ClosureVars, c)
318
319 return c
320 }
321
322
323
324 func NewHiddenParam(pos src.XPos, fn *Func, sym *types.Sym, typ *types.Type) *Name {
325 if fn.OClosure != nil {
326 base.FatalfAt(fn.Pos(), "cannot add hidden parameters to closures")
327 }
328
329 fn.SetNeedctxt(true)
330
331
332
333 fake := NewNameAt(pos, sym, typ)
334 fake.Class = PPARAM
335 fake.SetByval(true)
336
337 return NewClosureVar(pos, fn, fake)
338 }
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355 func SameSource(n1, n2 Node) bool {
356 return n1 == n2
357 }
358
359
360
361 func Uses(x Node, v *Name) bool {
362 if v == nil || v.Op() != ONAME {
363 base.Fatalf("RefersTo bad Name: %v", v)
364 }
365 return x.Op() == ONAME && x.Name() == v
366 }
367
368
369
370 func DeclaredBy(x, stmt Node) bool {
371 if stmt == nil {
372 base.Fatalf("DeclaredBy nil")
373 }
374 return x.Op() == ONAME && SameSource(x.Name().Defn, stmt)
375 }
376
377
378
379
380 type Class uint8
381
382
383 const (
384 Pxxx Class = iota
385 PEXTERN
386 PAUTO
387 PAUTOHEAP
388 PPARAM
389 PPARAMOUT
390 PTYPEPARAM
391 PFUNC
392
393
394 _ = uint((1 << 3) - iota)
395 )
396
397 type Embed struct {
398 Pos src.XPos
399 Patterns []string
400 }
401
View as plain text