]>
Commit | Line | Data |
---|---|---|
b4c522fa IB |
1 | |
2 | /* Compiler implementation of the D programming language | |
f3ed896c | 3 | * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved |
b4c522fa IB |
4 | * written by Walter Bright |
5 | * http://www.digitalmars.com | |
6 | * Distributed under the Boost Software License, Version 1.0. | |
7 | * http://www.boost.org/LICENSE_1_0.txt | |
8 | * https://github.com/dlang/dmd/blob/master/src/dmd/statement.h | |
9 | */ | |
10 | ||
11 | #pragma once | |
12 | ||
13 | #include "root/root.h" | |
14 | ||
15 | #include "arraytypes.h" | |
16 | #include "dsymbol.h" | |
17 | #include "visitor.h" | |
18 | #include "tokens.h" | |
19 | ||
20 | struct OutBuffer; | |
21 | struct Scope; | |
22 | class Expression; | |
23 | class LabelDsymbol; | |
24 | class Identifier; | |
25 | class IfStatement; | |
26 | class ExpStatement; | |
27 | class DefaultStatement; | |
28 | class VarDeclaration; | |
29 | class Condition; | |
30 | class Module; | |
31 | struct Token; | |
32 | class ErrorStatement; | |
33 | class ReturnStatement; | |
34 | class CompoundStatement; | |
35 | class Parameter; | |
36 | class StaticAssert; | |
37 | class AsmStatement; | |
38 | class GotoStatement; | |
39 | class ScopeStatement; | |
40 | class TryCatchStatement; | |
41 | class TryFinallyStatement; | |
42 | class CaseStatement; | |
43 | class DefaultStatement; | |
44 | class LabelStatement; | |
45 | class StaticForeach; | |
46 | ||
47 | // Back end | |
48 | struct code; | |
49 | ||
50 | bool inferAggregate(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply); | |
51 | bool inferApplyArgTypes(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply); | |
52 | ||
53 | /* How a statement exits; this is returned by blockExit() | |
54 | */ | |
55 | enum BE | |
56 | { | |
57 | BEnone = 0, | |
58 | BEfallthru = 1, | |
59 | BEthrow = 2, | |
60 | BEreturn = 4, | |
61 | BEgoto = 8, | |
62 | BEhalt = 0x10, | |
63 | BEbreak = 0x20, | |
64 | BEcontinue = 0x40, | |
65 | BEerrthrow = 0x80, | |
66 | BEany = (BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt) | |
67 | }; | |
68 | ||
69 | class Statement : public RootObject | |
70 | { | |
71 | public: | |
72 | Loc loc; | |
73 | ||
74 | Statement(Loc loc); | |
75 | virtual Statement *syntaxCopy(); | |
76 | ||
77 | void print(); | |
78 | const char *toChars(); | |
79 | ||
80 | void error(const char *format, ...); | |
81 | void warning(const char *format, ...); | |
82 | void deprecation(const char *format, ...); | |
83 | virtual Statement *getRelatedLabeled() { return this; } | |
84 | virtual bool hasBreak(); | |
85 | virtual bool hasContinue(); | |
86 | bool usesEH(); | |
87 | bool comeFrom(); | |
88 | bool hasCode(); | |
89 | virtual Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); | |
90 | virtual Statements *flatten(Scope *sc); | |
91 | virtual Statement *last(); | |
92 | ||
93 | // Avoid dynamic_cast | |
94 | virtual ErrorStatement *isErrorStatement() { return NULL; } | |
95 | virtual ScopeStatement *isScopeStatement() { return NULL; } | |
96 | virtual ExpStatement *isExpStatement() { return NULL; } | |
97 | virtual CompoundStatement *isCompoundStatement() { return NULL; } | |
98 | virtual ReturnStatement *isReturnStatement() { return NULL; } | |
99 | virtual IfStatement *isIfStatement() { return NULL; } | |
100 | virtual CaseStatement *isCaseStatement() { return NULL; } | |
101 | virtual DefaultStatement *isDefaultStatement() { return NULL; } | |
102 | virtual LabelStatement *isLabelStatement() { return NULL; } | |
103 | virtual GotoDefaultStatement *isGotoDefaultStatement() { return NULL; } | |
104 | virtual GotoCaseStatement *isGotoCaseStatement() { return NULL; } | |
105 | virtual BreakStatement *isBreakStatement() { return NULL; } | |
106 | virtual DtorExpStatement *isDtorExpStatement() { return NULL; } | |
107 | virtual ForwardingStatement *isForwardingStatement() { return NULL; } | |
108 | virtual void accept(Visitor *v) { v->visit(this); } | |
109 | }; | |
110 | ||
111 | /** Any Statement that fails semantic() or has a component that is an ErrorExp or | |
112 | * a TypeError should return an ErrorStatement from semantic(). | |
113 | */ | |
114 | class ErrorStatement : public Statement | |
115 | { | |
116 | public: | |
117 | ErrorStatement(); | |
118 | Statement *syntaxCopy(); | |
119 | ||
120 | ErrorStatement *isErrorStatement() { return this; } | |
121 | void accept(Visitor *v) { v->visit(this); } | |
122 | }; | |
123 | ||
124 | class PeelStatement : public Statement | |
125 | { | |
126 | public: | |
127 | Statement *s; | |
128 | ||
129 | PeelStatement(Statement *s); | |
130 | void accept(Visitor *v) { v->visit(this); } | |
131 | }; | |
132 | ||
133 | class ExpStatement : public Statement | |
134 | { | |
135 | public: | |
136 | Expression *exp; | |
137 | ||
138 | ExpStatement(Loc loc, Expression *exp); | |
139 | ExpStatement(Loc loc, Dsymbol *s); | |
140 | static ExpStatement *create(Loc loc, Expression *exp); | |
141 | Statement *syntaxCopy(); | |
142 | Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); | |
143 | Statements *flatten(Scope *sc); | |
144 | ||
145 | ExpStatement *isExpStatement() { return this; } | |
146 | void accept(Visitor *v) { v->visit(this); } | |
147 | }; | |
148 | ||
149 | class DtorExpStatement : public ExpStatement | |
150 | { | |
151 | public: | |
152 | /* Wraps an expression that is the destruction of 'var' | |
153 | */ | |
154 | ||
155 | VarDeclaration *var; | |
156 | ||
157 | DtorExpStatement(Loc loc, Expression *exp, VarDeclaration *v); | |
158 | Statement *syntaxCopy(); | |
159 | void accept(Visitor *v) { v->visit(this); } | |
160 | ||
161 | DtorExpStatement *isDtorExpStatement() { return this; } | |
162 | }; | |
163 | ||
164 | class CompileStatement : public Statement | |
165 | { | |
166 | public: | |
167 | Expression *exp; | |
168 | ||
169 | CompileStatement(Loc loc, Expression *exp); | |
170 | Statement *syntaxCopy(); | |
171 | Statements *flatten(Scope *sc); | |
172 | void accept(Visitor *v) { v->visit(this); } | |
173 | }; | |
174 | ||
175 | class CompoundStatement : public Statement | |
176 | { | |
177 | public: | |
178 | Statements *statements; | |
179 | ||
180 | CompoundStatement(Loc loc, Statements *s); | |
181 | CompoundStatement(Loc loc, Statement *s1); | |
182 | CompoundStatement(Loc loc, Statement *s1, Statement *s2); | |
183 | static CompoundStatement *create(Loc loc, Statement *s1, Statement *s2); | |
184 | Statement *syntaxCopy(); | |
185 | Statements *flatten(Scope *sc); | |
186 | ReturnStatement *isReturnStatement(); | |
187 | Statement *last(); | |
188 | ||
189 | CompoundStatement *isCompoundStatement() { return this; } | |
190 | void accept(Visitor *v) { v->visit(this); } | |
191 | }; | |
192 | ||
193 | class CompoundDeclarationStatement : public CompoundStatement | |
194 | { | |
195 | public: | |
196 | CompoundDeclarationStatement(Loc loc, Statements *s); | |
197 | Statement *syntaxCopy(); | |
198 | void accept(Visitor *v) { v->visit(this); } | |
199 | }; | |
200 | ||
201 | /* The purpose of this is so that continue will go to the next | |
202 | * of the statements, and break will go to the end of the statements. | |
203 | */ | |
204 | class UnrolledLoopStatement : public Statement | |
205 | { | |
206 | public: | |
207 | Statements *statements; | |
208 | ||
209 | UnrolledLoopStatement(Loc loc, Statements *statements); | |
210 | Statement *syntaxCopy(); | |
211 | bool hasBreak(); | |
212 | bool hasContinue(); | |
213 | ||
214 | void accept(Visitor *v) { v->visit(this); } | |
215 | }; | |
216 | ||
217 | class ScopeStatement : public Statement | |
218 | { | |
219 | public: | |
220 | Statement *statement; | |
221 | Loc endloc; // location of closing curly bracket | |
222 | ||
223 | ScopeStatement(Loc loc, Statement *s, Loc endloc); | |
224 | Statement *syntaxCopy(); | |
225 | ScopeStatement *isScopeStatement() { return this; } | |
226 | ReturnStatement *isReturnStatement(); | |
227 | bool hasBreak(); | |
228 | bool hasContinue(); | |
229 | ||
230 | void accept(Visitor *v) { v->visit(this); } | |
231 | }; | |
232 | ||
233 | class ForwardingStatement : public Statement | |
234 | { | |
235 | ForwardingScopeDsymbol *sym; | |
236 | Statement *statement; | |
237 | ||
238 | Statement *syntaxCopy(); | |
239 | Statement *getRelatedLabeled(); | |
240 | bool hasBreak(); | |
241 | bool hasContinue(); | |
242 | Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally); | |
243 | Statement *last(); | |
244 | Statements *flatten(Scope *sc); | |
245 | ForwardingStatement *isForwardingStatement() { return this; } | |
246 | void accept(Visitor *v) { v->visit(this); } | |
247 | }; | |
248 | ||
249 | class WhileStatement : public Statement | |
250 | { | |
251 | public: | |
252 | Expression *condition; | |
253 | Statement *_body; | |
254 | Loc endloc; // location of closing curly bracket | |
255 | ||
256 | WhileStatement(Loc loc, Expression *c, Statement *b, Loc endloc); | |
257 | Statement *syntaxCopy(); | |
258 | bool hasBreak(); | |
259 | bool hasContinue(); | |
260 | ||
261 | void accept(Visitor *v) { v->visit(this); } | |
262 | }; | |
263 | ||
264 | class DoStatement : public Statement | |
265 | { | |
266 | public: | |
267 | Statement *_body; | |
268 | Expression *condition; | |
269 | Loc endloc; // location of ';' after while | |
270 | ||
271 | DoStatement(Loc loc, Statement *b, Expression *c, Loc endloc); | |
272 | Statement *syntaxCopy(); | |
273 | bool hasBreak(); | |
274 | bool hasContinue(); | |
275 | ||
276 | void accept(Visitor *v) { v->visit(this); } | |
277 | }; | |
278 | ||
279 | class ForStatement : public Statement | |
280 | { | |
281 | public: | |
282 | Statement *_init; | |
283 | Expression *condition; | |
284 | Expression *increment; | |
285 | Statement *_body; | |
286 | Loc endloc; // location of closing curly bracket | |
287 | ||
288 | // When wrapped in try/finally clauses, this points to the outermost one, | |
289 | // which may have an associated label. Internal break/continue statements | |
290 | // treat that label as referring to this loop. | |
291 | Statement *relatedLabeled; | |
292 | ||
293 | ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body, Loc endloc); | |
294 | Statement *syntaxCopy(); | |
295 | Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); | |
296 | Statement *getRelatedLabeled() { return relatedLabeled ? relatedLabeled : this; } | |
297 | bool hasBreak(); | |
298 | bool hasContinue(); | |
299 | ||
300 | void accept(Visitor *v) { v->visit(this); } | |
301 | }; | |
302 | ||
303 | class ForeachStatement : public Statement | |
304 | { | |
305 | public: | |
306 | TOK op; // TOKforeach or TOKforeach_reverse | |
307 | Parameters *parameters; // array of Parameter*'s | |
308 | Expression *aggr; | |
309 | Statement *_body; | |
310 | Loc endloc; // location of closing curly bracket | |
311 | ||
312 | VarDeclaration *key; | |
313 | VarDeclaration *value; | |
314 | ||
315 | FuncDeclaration *func; // function we're lexically in | |
316 | ||
317 | Statements *cases; // put breaks, continues, gotos and returns here | |
318 | ScopeStatements *gotos; // forward referenced goto's go here | |
319 | ||
320 | ForeachStatement(Loc loc, TOK op, Parameters *parameters, Expression *aggr, Statement *body, Loc endloc); | |
321 | Statement *syntaxCopy(); | |
322 | bool checkForArgTypes(); | |
323 | bool hasBreak(); | |
324 | bool hasContinue(); | |
325 | ||
326 | void accept(Visitor *v) { v->visit(this); } | |
327 | }; | |
328 | ||
329 | class ForeachRangeStatement : public Statement | |
330 | { | |
331 | public: | |
332 | TOK op; // TOKforeach or TOKforeach_reverse | |
333 | Parameter *prm; // loop index variable | |
334 | Expression *lwr; | |
335 | Expression *upr; | |
336 | Statement *_body; | |
337 | Loc endloc; // location of closing curly bracket | |
338 | ||
339 | VarDeclaration *key; | |
340 | ||
341 | ForeachRangeStatement(Loc loc, TOK op, Parameter *prm, | |
342 | Expression *lwr, Expression *upr, Statement *body, Loc endloc); | |
343 | Statement *syntaxCopy(); | |
344 | bool hasBreak(); | |
345 | bool hasContinue(); | |
346 | ||
347 | void accept(Visitor *v) { v->visit(this); } | |
348 | }; | |
349 | ||
350 | class IfStatement : public Statement | |
351 | { | |
352 | public: | |
353 | Parameter *prm; | |
354 | Expression *condition; | |
355 | Statement *ifbody; | |
356 | Statement *elsebody; | |
357 | Loc endloc; // location of closing curly bracket | |
358 | ||
359 | VarDeclaration *match; // for MatchExpression results | |
360 | ||
361 | IfStatement(Loc loc, Parameter *prm, Expression *condition, Statement *ifbody, Statement *elsebody, Loc endloc); | |
362 | Statement *syntaxCopy(); | |
363 | IfStatement *isIfStatement() { return this; } | |
364 | ||
365 | void accept(Visitor *v) { v->visit(this); } | |
366 | }; | |
367 | ||
368 | class ConditionalStatement : public Statement | |
369 | { | |
370 | public: | |
371 | Condition *condition; | |
372 | Statement *ifbody; | |
373 | Statement *elsebody; | |
374 | ||
375 | ConditionalStatement(Loc loc, Condition *condition, Statement *ifbody, Statement *elsebody); | |
376 | Statement *syntaxCopy(); | |
377 | Statements *flatten(Scope *sc); | |
378 | ||
379 | void accept(Visitor *v) { v->visit(this); } | |
380 | }; | |
381 | ||
382 | class StaticForeachStatement : public Statement | |
383 | { | |
384 | public: | |
385 | StaticForeach *sfe; | |
386 | ||
387 | Statement *syntaxCopy(); | |
388 | Statements *flatten(Scope *sc); | |
389 | ||
390 | void accept(Visitor *v) { v->visit(this); } | |
391 | }; | |
392 | ||
393 | class PragmaStatement : public Statement | |
394 | { | |
395 | public: | |
396 | Identifier *ident; | |
397 | Expressions *args; // array of Expression's | |
398 | Statement *_body; | |
399 | ||
400 | PragmaStatement(Loc loc, Identifier *ident, Expressions *args, Statement *body); | |
401 | Statement *syntaxCopy(); | |
402 | ||
403 | void accept(Visitor *v) { v->visit(this); } | |
404 | }; | |
405 | ||
406 | class StaticAssertStatement : public Statement | |
407 | { | |
408 | public: | |
409 | StaticAssert *sa; | |
410 | ||
411 | StaticAssertStatement(StaticAssert *sa); | |
412 | Statement *syntaxCopy(); | |
413 | ||
414 | void accept(Visitor *v) { v->visit(this); } | |
415 | }; | |
416 | ||
417 | class SwitchStatement : public Statement | |
418 | { | |
419 | public: | |
420 | Expression *condition; | |
421 | Statement *_body; | |
422 | bool isFinal; | |
423 | ||
424 | DefaultStatement *sdefault; | |
425 | TryFinallyStatement *tf; | |
426 | GotoCaseStatements gotoCases; // array of unresolved GotoCaseStatement's | |
427 | CaseStatements *cases; // array of CaseStatement's | |
428 | int hasNoDefault; // !=0 if no default statement | |
429 | int hasVars; // !=0 if has variable case values | |
430 | VarDeclaration *lastVar; | |
431 | ||
432 | SwitchStatement(Loc loc, Expression *c, Statement *b, bool isFinal); | |
433 | Statement *syntaxCopy(); | |
434 | bool hasBreak(); | |
435 | bool checkLabel(); | |
436 | ||
437 | void accept(Visitor *v) { v->visit(this); } | |
438 | }; | |
439 | ||
440 | class CaseStatement : public Statement | |
441 | { | |
442 | public: | |
443 | Expression *exp; | |
444 | Statement *statement; | |
445 | ||
446 | int index; // which case it is (since we sort this) | |
447 | VarDeclaration *lastVar; | |
448 | ||
449 | CaseStatement(Loc loc, Expression *exp, Statement *s); | |
450 | Statement *syntaxCopy(); | |
451 | int compare(RootObject *obj); | |
452 | CaseStatement *isCaseStatement() { return this; } | |
453 | ||
454 | void accept(Visitor *v) { v->visit(this); } | |
455 | }; | |
456 | ||
457 | ||
458 | class CaseRangeStatement : public Statement | |
459 | { | |
460 | public: | |
461 | Expression *first; | |
462 | Expression *last; | |
463 | Statement *statement; | |
464 | ||
465 | CaseRangeStatement(Loc loc, Expression *first, Expression *last, Statement *s); | |
466 | Statement *syntaxCopy(); | |
467 | void accept(Visitor *v) { v->visit(this); } | |
468 | }; | |
469 | ||
470 | ||
471 | class DefaultStatement : public Statement | |
472 | { | |
473 | public: | |
474 | Statement *statement; | |
475 | VarDeclaration *lastVar; | |
476 | ||
477 | DefaultStatement(Loc loc, Statement *s); | |
478 | Statement *syntaxCopy(); | |
479 | DefaultStatement *isDefaultStatement() { return this; } | |
480 | ||
481 | void accept(Visitor *v) { v->visit(this); } | |
482 | }; | |
483 | ||
484 | class GotoDefaultStatement : public Statement | |
485 | { | |
486 | public: | |
487 | SwitchStatement *sw; | |
488 | ||
489 | GotoDefaultStatement(Loc loc); | |
490 | Statement *syntaxCopy(); | |
491 | GotoDefaultStatement *isGotoDefaultStatement() { return this; } | |
492 | ||
493 | void accept(Visitor *v) { v->visit(this); } | |
494 | }; | |
495 | ||
496 | class GotoCaseStatement : public Statement | |
497 | { | |
498 | public: | |
499 | Expression *exp; // NULL, or which case to goto | |
500 | CaseStatement *cs; // case statement it resolves to | |
501 | ||
502 | GotoCaseStatement(Loc loc, Expression *exp); | |
503 | Statement *syntaxCopy(); | |
504 | GotoCaseStatement *isGotoCaseStatement() { return this; } | |
505 | ||
506 | void accept(Visitor *v) { v->visit(this); } | |
507 | }; | |
508 | ||
509 | class SwitchErrorStatement : public Statement | |
510 | { | |
511 | public: | |
512 | SwitchErrorStatement(Loc loc); | |
513 | ||
514 | void accept(Visitor *v) { v->visit(this); } | |
515 | }; | |
516 | ||
517 | class ReturnStatement : public Statement | |
518 | { | |
519 | public: | |
520 | Expression *exp; | |
521 | size_t caseDim; | |
522 | ||
523 | ReturnStatement(Loc loc, Expression *exp); | |
524 | Statement *syntaxCopy(); | |
525 | ||
526 | ReturnStatement *isReturnStatement() { return this; } | |
527 | void accept(Visitor *v) { v->visit(this); } | |
528 | }; | |
529 | ||
530 | class BreakStatement : public Statement | |
531 | { | |
532 | public: | |
533 | Identifier *ident; | |
534 | ||
535 | BreakStatement(Loc loc, Identifier *ident); | |
536 | Statement *syntaxCopy(); | |
537 | ||
538 | BreakStatement *isBreakStatement() { return this; } | |
539 | void accept(Visitor *v) { v->visit(this); } | |
540 | }; | |
541 | ||
542 | class ContinueStatement : public Statement | |
543 | { | |
544 | public: | |
545 | Identifier *ident; | |
546 | ||
547 | ContinueStatement(Loc loc, Identifier *ident); | |
548 | Statement *syntaxCopy(); | |
549 | ||
550 | void accept(Visitor *v) { v->visit(this); } | |
551 | }; | |
552 | ||
553 | class SynchronizedStatement : public Statement | |
554 | { | |
555 | public: | |
556 | Expression *exp; | |
557 | Statement *_body; | |
558 | ||
559 | SynchronizedStatement(Loc loc, Expression *exp, Statement *body); | |
560 | Statement *syntaxCopy(); | |
561 | bool hasBreak(); | |
562 | bool hasContinue(); | |
563 | ||
564 | void accept(Visitor *v) { v->visit(this); } | |
565 | }; | |
566 | ||
567 | class WithStatement : public Statement | |
568 | { | |
569 | public: | |
570 | Expression *exp; | |
571 | Statement *_body; | |
572 | VarDeclaration *wthis; | |
573 | Loc endloc; | |
574 | ||
575 | WithStatement(Loc loc, Expression *exp, Statement *body, Loc endloc); | |
576 | Statement *syntaxCopy(); | |
577 | ||
578 | void accept(Visitor *v) { v->visit(this); } | |
579 | }; | |
580 | ||
581 | class TryCatchStatement : public Statement | |
582 | { | |
583 | public: | |
584 | Statement *_body; | |
585 | Catches *catches; | |
586 | ||
587 | TryCatchStatement(Loc loc, Statement *body, Catches *catches); | |
588 | Statement *syntaxCopy(); | |
589 | bool hasBreak(); | |
590 | ||
591 | void accept(Visitor *v) { v->visit(this); } | |
592 | }; | |
593 | ||
594 | class Catch : public RootObject | |
595 | { | |
596 | public: | |
597 | Loc loc; | |
598 | Type *type; | |
599 | Identifier *ident; | |
600 | VarDeclaration *var; | |
601 | Statement *handler; | |
602 | ||
603 | // set if semantic processing errors | |
604 | bool errors; | |
605 | ||
606 | // was generated by the compiler, | |
607 | // wasn't present in source code | |
608 | bool internalCatch; | |
609 | ||
610 | Catch(Loc loc, Type *t, Identifier *id, Statement *handler); | |
611 | Catch *syntaxCopy(); | |
612 | }; | |
613 | ||
614 | class TryFinallyStatement : public Statement | |
615 | { | |
616 | public: | |
617 | Statement *_body; | |
618 | Statement *finalbody; | |
619 | ||
620 | TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody); | |
621 | static TryFinallyStatement *create(Loc loc, Statement *body, Statement *finalbody); | |
622 | Statement *syntaxCopy(); | |
623 | bool hasBreak(); | |
624 | bool hasContinue(); | |
625 | ||
626 | void accept(Visitor *v) { v->visit(this); } | |
627 | }; | |
628 | ||
629 | class OnScopeStatement : public Statement | |
630 | { | |
631 | public: | |
632 | TOK tok; | |
633 | Statement *statement; | |
634 | ||
635 | OnScopeStatement(Loc loc, TOK tok, Statement *statement); | |
636 | Statement *syntaxCopy(); | |
637 | Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); | |
638 | ||
639 | void accept(Visitor *v) { v->visit(this); } | |
640 | }; | |
641 | ||
642 | class ThrowStatement : public Statement | |
643 | { | |
644 | public: | |
645 | Expression *exp; | |
646 | // was generated by the compiler, | |
647 | // wasn't present in source code | |
648 | bool internalThrow; | |
649 | ||
650 | ThrowStatement(Loc loc, Expression *exp); | |
651 | Statement *syntaxCopy(); | |
652 | ||
653 | void accept(Visitor *v) { v->visit(this); } | |
654 | }; | |
655 | ||
656 | class DebugStatement : public Statement | |
657 | { | |
658 | public: | |
659 | Statement *statement; | |
660 | ||
661 | DebugStatement(Loc loc, Statement *statement); | |
662 | Statement *syntaxCopy(); | |
663 | Statements *flatten(Scope *sc); | |
664 | void accept(Visitor *v) { v->visit(this); } | |
665 | }; | |
666 | ||
667 | class GotoStatement : public Statement | |
668 | { | |
669 | public: | |
670 | Identifier *ident; | |
671 | LabelDsymbol *label; | |
672 | TryFinallyStatement *tf; | |
673 | OnScopeStatement *os; | |
674 | VarDeclaration *lastVar; | |
675 | ||
676 | GotoStatement(Loc loc, Identifier *ident); | |
677 | Statement *syntaxCopy(); | |
678 | bool checkLabel(); | |
679 | ||
680 | void accept(Visitor *v) { v->visit(this); } | |
681 | }; | |
682 | ||
683 | class LabelStatement : public Statement | |
684 | { | |
685 | public: | |
686 | Identifier *ident; | |
687 | Statement *statement; | |
688 | TryFinallyStatement *tf; | |
689 | OnScopeStatement *os; | |
690 | VarDeclaration *lastVar; | |
691 | Statement *gotoTarget; // interpret | |
692 | ||
693 | bool breaks; // someone did a 'break ident' | |
694 | ||
695 | LabelStatement(Loc loc, Identifier *ident, Statement *statement); | |
696 | Statement *syntaxCopy(); | |
697 | Statements *flatten(Scope *sc); | |
698 | Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); | |
699 | ||
700 | LabelStatement *isLabelStatement() { return this; } | |
701 | ||
702 | void accept(Visitor *v) { v->visit(this); } | |
703 | }; | |
704 | ||
705 | class LabelDsymbol : public Dsymbol | |
706 | { | |
707 | public: | |
708 | LabelStatement *statement; | |
709 | ||
710 | LabelDsymbol(Identifier *ident); | |
711 | static LabelDsymbol *create(Identifier *ident); | |
712 | LabelDsymbol *isLabel(); | |
713 | void accept(Visitor *v) { v->visit(this); } | |
714 | }; | |
715 | ||
716 | Statement* asmSemantic(AsmStatement *s, Scope *sc); | |
717 | ||
718 | class AsmStatement : public Statement | |
719 | { | |
720 | public: | |
721 | Token *tokens; | |
722 | ||
723 | AsmStatement(Loc loc, Token *tokens); | |
724 | Statement *syntaxCopy(); | |
725 | void accept(Visitor *v) { v->visit(this); } | |
726 | }; | |
727 | ||
728 | class InlineAsmStatement : public AsmStatement | |
729 | { | |
730 | public: | |
731 | code *asmcode; | |
732 | unsigned asmalign; // alignment of this statement | |
733 | unsigned regs; // mask of registers modified (must match regm_t in back end) | |
734 | bool refparam; // true if function parameter is referenced | |
735 | bool naked; // true if function is to be naked | |
736 | ||
737 | InlineAsmStatement(Loc loc, Token *tokens); | |
738 | Statement *syntaxCopy(); | |
739 | void accept(Visitor *v) { v->visit(this); } | |
740 | }; | |
741 | ||
742 | // A GCC asm statement - assembler instructions with D expression operands | |
743 | class GccAsmStatement : public AsmStatement | |
744 | { | |
745 | public: | |
746 | StorageClass stc; // attributes of the asm {} block | |
747 | Expression *insn; // string expression that is the template for assembler code | |
748 | Expressions *args; // input and output operands of the statement | |
749 | unsigned outputargs; // of the operands in 'args', the number of output operands | |
750 | Identifiers *names; // list of symbolic names for the operands | |
751 | Expressions *constraints; // list of string constants specifying constraints on operands | |
752 | Expressions *clobbers; // list of string constants specifying clobbers and scratch registers | |
753 | Identifiers *labels; // list of goto labels | |
754 | GotoStatements *gotos; // of the goto labels, the equivalent statements they represent | |
755 | ||
756 | GccAsmStatement(Loc loc, Token *tokens); | |
757 | Statement *syntaxCopy(); | |
758 | void accept(Visitor *v) { v->visit(this); } | |
759 | }; | |
760 | ||
761 | // a complete asm {} block | |
762 | class CompoundAsmStatement : public CompoundStatement | |
763 | { | |
764 | public: | |
765 | StorageClass stc; // postfix attributes like nothrow/pure/@trusted | |
766 | ||
767 | CompoundAsmStatement(Loc loc, Statements *s, StorageClass stc); | |
768 | CompoundAsmStatement *syntaxCopy(); | |
769 | Statements *flatten(Scope *sc); | |
770 | ||
771 | void accept(Visitor *v) { v->visit(this); } | |
772 | }; | |
773 | ||
774 | class ImportStatement : public Statement | |
775 | { | |
776 | public: | |
777 | Dsymbols *imports; // Array of Import's | |
778 | ||
779 | ImportStatement(Loc loc, Dsymbols *imports); | |
780 | Statement *syntaxCopy(); | |
781 | ||
782 | void accept(Visitor *v) { v->visit(this); } | |
783 | }; |