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/src"
12 "go/constant"
13 )
14
15
16 type Decl struct {
17 miniNode
18 X *Name
19 }
20
21 func NewDecl(pos src.XPos, op Op, x *Name) *Decl {
22 n := &Decl{X: x}
23 n.pos = pos
24 switch op {
25 default:
26 panic("invalid Decl op " + op.String())
27 case ODCL:
28 n.op = op
29 }
30 return n
31 }
32
33 func (*Decl) isStmt() {}
34
35
36
37
38
39
40
41
42 type Stmt interface {
43 Node
44 isStmt()
45 PtrInit() *Nodes
46 }
47
48
49 type miniStmt struct {
50 miniNode
51 init Nodes
52 }
53
54 func (*miniStmt) isStmt() {}
55
56 func (n *miniStmt) Init() Nodes { return n.init }
57 func (n *miniStmt) SetInit(x Nodes) { n.init = x }
58 func (n *miniStmt) PtrInit() *Nodes { return &n.init }
59
60
61
62
63 type AssignListStmt struct {
64 miniStmt
65 Lhs Nodes
66 Def bool
67 Rhs Nodes
68 }
69
70 func NewAssignListStmt(pos src.XPos, op Op, lhs, rhs []Node) *AssignListStmt {
71 n := &AssignListStmt{}
72 n.pos = pos
73 n.SetOp(op)
74 n.Lhs = lhs
75 n.Rhs = rhs
76 return n
77 }
78
79 func (n *AssignListStmt) SetOp(op Op) {
80 switch op {
81 default:
82 panic(n.no("SetOp " + op.String()))
83 case OAS2, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV, OSELRECV2:
84 n.op = op
85 }
86 }
87
88
89
90 type AssignStmt struct {
91 miniStmt
92 X Node
93 Def bool
94 Y Node
95 }
96
97 func NewAssignStmt(pos src.XPos, x, y Node) *AssignStmt {
98 n := &AssignStmt{X: x, Y: y}
99 n.pos = pos
100 n.op = OAS
101 return n
102 }
103
104 func (n *AssignStmt) SetOp(op Op) {
105 switch op {
106 default:
107 panic(n.no("SetOp " + op.String()))
108 case OAS:
109 n.op = op
110 }
111 }
112
113
114 type AssignOpStmt struct {
115 miniStmt
116 X Node
117 AsOp Op
118 Y Node
119 IncDec bool
120 }
121
122 func NewAssignOpStmt(pos src.XPos, asOp Op, x, y Node) *AssignOpStmt {
123 n := &AssignOpStmt{AsOp: asOp, X: x, Y: y}
124 n.pos = pos
125 n.op = OASOP
126 return n
127 }
128
129
130 type BlockStmt struct {
131 miniStmt
132 List Nodes
133 }
134
135 func NewBlockStmt(pos src.XPos, list []Node) *BlockStmt {
136 n := &BlockStmt{}
137 n.pos = pos
138 if !pos.IsKnown() {
139 n.pos = base.Pos
140 if len(list) > 0 {
141 n.pos = list[0].Pos()
142 }
143 }
144 n.op = OBLOCK
145 n.List = list
146 return n
147 }
148
149
150 type BranchStmt struct {
151 miniStmt
152 Label *types.Sym
153 }
154
155 func NewBranchStmt(pos src.XPos, op Op, label *types.Sym) *BranchStmt {
156 switch op {
157 case OBREAK, OCONTINUE, OFALL, OGOTO:
158
159 default:
160 panic("NewBranch " + op.String())
161 }
162 n := &BranchStmt{Label: label}
163 n.pos = pos
164 n.op = op
165 return n
166 }
167
168 func (n *BranchStmt) SetOp(op Op) {
169 switch op {
170 default:
171 panic(n.no("SetOp " + op.String()))
172 case OBREAK, OCONTINUE, OFALL, OGOTO:
173 n.op = op
174 }
175 }
176
177 func (n *BranchStmt) Sym() *types.Sym { return n.Label }
178
179
180 type CaseClause struct {
181 miniStmt
182 Var *Name
183 List Nodes
184
185
186
187
188
189
190
191
192
193 RTypes Nodes
194
195 Body Nodes
196 }
197
198 func NewCaseStmt(pos src.XPos, list, body []Node) *CaseClause {
199 n := &CaseClause{List: list, Body: body}
200 n.pos = pos
201 n.op = OCASE
202 return n
203 }
204
205 type CommClause struct {
206 miniStmt
207 Comm Node
208 Body Nodes
209 }
210
211 func NewCommStmt(pos src.XPos, comm Node, body []Node) *CommClause {
212 n := &CommClause{Comm: comm, Body: body}
213 n.pos = pos
214 n.op = OCASE
215 return n
216 }
217
218
219 type ForStmt struct {
220 miniStmt
221 Label *types.Sym
222 Cond Node
223 Post Node
224 Body Nodes
225 DistinctVars bool
226 }
227
228 func NewForStmt(pos src.XPos, init Node, cond, post Node, body []Node, distinctVars bool) *ForStmt {
229 n := &ForStmt{Cond: cond, Post: post}
230 n.pos = pos
231 n.op = OFOR
232 if init != nil {
233 n.init = []Node{init}
234 }
235 n.Body = body
236 n.DistinctVars = distinctVars
237 return n
238 }
239
240
241
242
243
244
245 type GoDeferStmt struct {
246 miniStmt
247 Call Node
248 DeferAt Expr
249 }
250
251 func NewGoDeferStmt(pos src.XPos, op Op, call Node) *GoDeferStmt {
252 n := &GoDeferStmt{Call: call}
253 n.pos = pos
254 switch op {
255 case ODEFER, OGO:
256 n.op = op
257 default:
258 panic("NewGoDeferStmt " + op.String())
259 }
260 return n
261 }
262
263
264 type IfStmt struct {
265 miniStmt
266 Cond Node
267 Body Nodes
268 Else Nodes
269 Likely bool
270 }
271
272 func NewIfStmt(pos src.XPos, cond Node, body, els []Node) *IfStmt {
273 n := &IfStmt{Cond: cond}
274 n.pos = pos
275 n.op = OIF
276 n.Body = body
277 n.Else = els
278 return n
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292 type JumpTableStmt struct {
293 miniStmt
294
295
296
297
298 Idx Node
299
300
301
302
303 Cases []constant.Value
304 Targets []*types.Sym
305 }
306
307 func NewJumpTableStmt(pos src.XPos, idx Node) *JumpTableStmt {
308 n := &JumpTableStmt{Idx: idx}
309 n.pos = pos
310 n.op = OJUMPTABLE
311 return n
312 }
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331 type InterfaceSwitchStmt struct {
332 miniStmt
333
334 Case Node
335 Itab Node
336 RuntimeType Node
337 Hash Node
338 Descriptor *obj.LSym
339 }
340
341 func NewInterfaceSwitchStmt(pos src.XPos, case_, itab, runtimeType, hash Node, descriptor *obj.LSym) *InterfaceSwitchStmt {
342 n := &InterfaceSwitchStmt{
343 Case: case_,
344 Itab: itab,
345 RuntimeType: runtimeType,
346 Hash: hash,
347 Descriptor: descriptor,
348 }
349 n.pos = pos
350 n.op = OINTERFACESWITCH
351 return n
352 }
353
354
355 type InlineMarkStmt struct {
356 miniStmt
357 Index int64
358 }
359
360 func NewInlineMarkStmt(pos src.XPos, index int64) *InlineMarkStmt {
361 n := &InlineMarkStmt{Index: index}
362 n.pos = pos
363 n.op = OINLMARK
364 return n
365 }
366
367 func (n *InlineMarkStmt) Offset() int64 { return n.Index }
368 func (n *InlineMarkStmt) SetOffset(x int64) { n.Index = x }
369
370
371 type LabelStmt struct {
372 miniStmt
373 Label *types.Sym
374 }
375
376 func NewLabelStmt(pos src.XPos, label *types.Sym) *LabelStmt {
377 n := &LabelStmt{Label: label}
378 n.pos = pos
379 n.op = OLABEL
380 return n
381 }
382
383 func (n *LabelStmt) Sym() *types.Sym { return n.Label }
384
385
386 type RangeStmt struct {
387 miniStmt
388 Label *types.Sym
389 Def bool
390 X Node
391 RType Node `mknode:"-"`
392 Key Node
393 Value Node
394 Body Nodes
395 DistinctVars bool
396 Prealloc *Name
397
398
399
400
401 KeyTypeWord Node `mknode:"-"`
402 KeySrcRType Node `mknode:"-"`
403 ValueTypeWord Node `mknode:"-"`
404 ValueSrcRType Node `mknode:"-"`
405 }
406
407 func NewRangeStmt(pos src.XPos, key, value, x Node, body []Node, distinctVars bool) *RangeStmt {
408 n := &RangeStmt{X: x, Key: key, Value: value}
409 n.pos = pos
410 n.op = ORANGE
411 n.Body = body
412 n.DistinctVars = distinctVars
413 return n
414 }
415
416
417 type ReturnStmt struct {
418 miniStmt
419 Results Nodes
420 }
421
422 func NewReturnStmt(pos src.XPos, results []Node) *ReturnStmt {
423 n := &ReturnStmt{}
424 n.pos = pos
425 n.op = ORETURN
426 n.Results = results
427 return n
428 }
429
430
431 type SelectStmt struct {
432 miniStmt
433 Label *types.Sym
434 Cases []*CommClause
435
436
437 Compiled Nodes
438 }
439
440 func NewSelectStmt(pos src.XPos, cases []*CommClause) *SelectStmt {
441 n := &SelectStmt{Cases: cases}
442 n.pos = pos
443 n.op = OSELECT
444 return n
445 }
446
447
448 type SendStmt struct {
449 miniStmt
450 Chan Node
451 Value Node
452 }
453
454 func NewSendStmt(pos src.XPos, ch, value Node) *SendStmt {
455 n := &SendStmt{Chan: ch, Value: value}
456 n.pos = pos
457 n.op = OSEND
458 return n
459 }
460
461
462 type SwitchStmt struct {
463 miniStmt
464 Tag Node
465 Cases []*CaseClause
466 Label *types.Sym
467
468
469 Compiled Nodes
470 }
471
472 func NewSwitchStmt(pos src.XPos, tag Node, cases []*CaseClause) *SwitchStmt {
473 n := &SwitchStmt{Tag: tag, Cases: cases}
474 n.pos = pos
475 n.op = OSWITCH
476 return n
477 }
478
479
480
481 type TailCallStmt struct {
482 miniStmt
483 Call *CallExpr
484 }
485
486 func NewTailCallStmt(pos src.XPos, call *CallExpr) *TailCallStmt {
487 n := &TailCallStmt{Call: call}
488 n.pos = pos
489 n.op = OTAILCALL
490 return n
491 }
492
493
494 type TypeSwitchGuard struct {
495 miniNode
496 Tag *Ident
497 X Node
498 Used bool
499 }
500
501 func NewTypeSwitchGuard(pos src.XPos, tag *Ident, x Node) *TypeSwitchGuard {
502 n := &TypeSwitchGuard{Tag: tag, X: x}
503 n.pos = pos
504 n.op = OTYPESW
505 return n
506 }
507
View as plain text