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