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