d: Merge upstream dmd, druntime 4ca4140e58, phobos 454dff14d.
[official-gcc.git] / gcc / d / dmd / statement.h
blob46cc4dadf6461751e36a6a42bcbd870d87f304ad
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * https://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * https://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/dlang/dmd/blob/master/src/dmd/statement.h
9 */
11 #pragma once
13 #include "arraytypes.h"
14 #include "ast_node.h"
15 #include "dsymbol.h"
16 #include "visitor.h"
17 #include "tokens.h"
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;
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;
43 // Back end
44 struct code;
46 /* How a statement exits; this is returned by blockExit()
48 enum BE : int32_t
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)
62 typedef unsigned char STMT;
63 enum
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
106 class Statement : public ASTNode
108 public:
109 Loc loc;
110 STMT stmt;
112 DYNCAST dyncast() const override final { return DYNCAST_STATEMENT; }
114 virtual Statement *syntaxCopy();
116 const char *toChars() const override final;
118 void error(const char *format, ...);
119 void warning(const char *format, ...);
120 void deprecation(const char *format, ...);
121 virtual Statement *getRelatedLabeled() { return this; }
122 virtual bool hasBreak() const;
123 virtual bool hasContinue() const;
124 bool usesEH();
125 bool comeFrom();
126 bool hasCode();
127 virtual Statement *last();
129 virtual ReturnStatement *endsWithReturnStatement() { return NULL; }
131 ErrorStatement *isErrorStatement() { return stmt == STMTerror ? (ErrorStatement*)this : NULL; }
132 ScopeStatement *isScopeStatement() { return stmt == STMTscope ? (ScopeStatement*)this : NULL; }
133 ExpStatement *isExpStatement() { return stmt == STMTexp ? (ExpStatement*)this : NULL; }
134 CompoundStatement *isCompoundStatement() { return stmt == STMTcompound ? (CompoundStatement*)this : NULL; }
135 ReturnStatement *isReturnStatement() { return stmt == STMTreturn ? (ReturnStatement*)this : NULL; }
136 IfStatement *isIfStatement() { return stmt == STMTif ? (IfStatement*)this : NULL; }
137 ConditionalStatement *isConditionalStatement() { return stmt == STMTconditional ? (ConditionalStatement*)this : NULL; }
138 StaticForeachStatement *isStaticForeachStatement() { return stmt == STMTstaticForeach ? (StaticForeachStatement*)this : NULL; }
139 CaseStatement *isCaseStatement() { return stmt == STMTcase ? (CaseStatement*)this : NULL; }
140 DefaultStatement *isDefaultStatement() { return stmt == STMTdefault ? (DefaultStatement*)this : NULL; }
141 LabelStatement *isLabelStatement() { return stmt == STMTlabel ? (LabelStatement*)this : NULL; }
142 GotoDefaultStatement *isGotoDefaultStatement() { return stmt == STMTgotoDefault ? (GotoDefaultStatement*)this : NULL; }
143 GotoCaseStatement *isGotoCaseStatement() { return stmt == STMTgotoCase ? (GotoCaseStatement*)this : NULL; }
144 BreakStatement *isBreakStatement() { return stmt == STMTbreak ? (BreakStatement*)this : NULL; }
145 DtorExpStatement *isDtorExpStatement() { return stmt == STMTdtorExp ? (DtorExpStatement*)this : NULL; }
146 CompileStatement *isCompileStatement() { return stmt == STMTcompile ? (CompileStatement*)this : NULL; }
147 ForwardingStatement *isForwardingStatement() { return stmt == STMTforwarding ? (ForwardingStatement*)this : NULL; }
148 DoStatement *isDoStatement() { return stmt == STMTdo ? (DoStatement*)this : NULL; }
149 ForStatement *isForStatement() { return stmt == STMTfor ? (ForStatement*)this : NULL; }
150 ForeachStatement *isForeachStatement() { return stmt == STMTforeach ? (ForeachStatement*)this : NULL; }
151 SwitchStatement *isSwitchStatement() { return stmt == STMTswitch ? (SwitchStatement*)this : NULL; }
152 ContinueStatement *isContinueStatement() { return stmt == STMTcontinue ? (ContinueStatement*)this : NULL; }
153 WithStatement *isWithStatement() { return stmt == STMTwith ? (WithStatement*)this : NULL; }
154 TryCatchStatement *isTryCatchStatement() { return stmt == STMTtryCatch ? (TryCatchStatement*)this : NULL; }
155 ThrowStatement *isThrowStatement() { return stmt == STMTthrow ? (ThrowStatement*)this : NULL; }
156 DebugStatement *isDebugStatement() { return stmt == STMTdebug ? (DebugStatement*)this : NULL; }
157 TryFinallyStatement *isTryFinallyStatement() { return stmt == STMTtryFinally ? (TryFinallyStatement*)this : NULL; }
158 ScopeGuardStatement *isScopeGuardStatement() { return stmt == STMTscopeGuard ? (ScopeGuardStatement*)this : NULL; }
159 SwitchErrorStatement *isSwitchErrorStatement() { return stmt == STMTswitchError ? (SwitchErrorStatement*)this : NULL; }
160 UnrolledLoopStatement *isUnrolledLoopStatement() { return stmt == STMTunrolledLoop ? (UnrolledLoopStatement*)this : NULL; }
161 ForeachRangeStatement *isForeachRangeStatement() { return stmt == STMTforeachRange ? (ForeachRangeStatement*)this : NULL; }
162 CompoundDeclarationStatement *isCompoundDeclarationStatement() { return stmt == STMTcompoundDeclaration ? (CompoundDeclarationStatement*)this : NULL; }
164 void accept(Visitor *v) override { v->visit(this); }
167 /** Any Statement that fails semantic() or has a component that is an ErrorExp or
168 * a TypeError should return an ErrorStatement from semantic().
170 class ErrorStatement final : public Statement
172 public:
173 ErrorStatement *syntaxCopy() override;
175 void accept(Visitor *v) override { v->visit(this); }
178 class PeelStatement final : public Statement
180 public:
181 Statement *s;
183 void accept(Visitor *v) override { v->visit(this); }
186 class ExpStatement : public Statement
188 public:
189 Expression *exp;
191 static ExpStatement *create(const Loc &loc, Expression *exp);
192 ExpStatement *syntaxCopy() override;
194 void accept(Visitor *v) override { v->visit(this); }
197 class DtorExpStatement final : public ExpStatement
199 public:
200 /* Wraps an expression that is the destruction of 'var'
203 VarDeclaration *var;
205 DtorExpStatement *syntaxCopy() override;
206 void accept(Visitor *v) override { v->visit(this); }
209 class CompileStatement final : public Statement
211 public:
212 Expressions *exps;
214 CompileStatement *syntaxCopy() override;
215 void accept(Visitor *v) override { v->visit(this); }
218 class CompoundStatement : public Statement
220 public:
221 Statements *statements;
223 static CompoundStatement *create(const Loc &loc, Statement *s1, Statement *s2);
224 CompoundStatement *syntaxCopy() override;
225 ReturnStatement *endsWithReturnStatement() override final;
226 Statement *last() override final;
228 void accept(Visitor *v) override { v->visit(this); }
231 class CompoundDeclarationStatement final : public CompoundStatement
233 public:
234 CompoundDeclarationStatement *syntaxCopy() override;
235 void accept(Visitor *v) override { v->visit(this); }
238 /* The purpose of this is so that continue will go to the next
239 * of the statements, and break will go to the end of the statements.
241 class UnrolledLoopStatement final : public Statement
243 public:
244 Statements *statements;
246 UnrolledLoopStatement *syntaxCopy() override;
247 bool hasBreak() const override;
248 bool hasContinue() const override;
250 void accept(Visitor *v) override { v->visit(this); }
253 class ScopeStatement final : public Statement
255 public:
256 Statement *statement;
257 Loc endloc; // location of closing curly bracket
259 ScopeStatement *syntaxCopy() override;
260 ReturnStatement *endsWithReturnStatement() override;
261 bool hasBreak() const override;
262 bool hasContinue() const override;
264 void accept(Visitor *v) override { v->visit(this); }
267 class ForwardingStatement final : public Statement
269 public:
270 ForwardingScopeDsymbol *sym;
271 Statement *statement;
273 ForwardingStatement *syntaxCopy() override;
274 void accept(Visitor *v) override { v->visit(this); }
277 class WhileStatement final : public Statement
279 public:
280 Parameter *param;
281 Expression *condition;
282 Statement *_body;
283 Loc endloc; // location of closing curly bracket
285 WhileStatement *syntaxCopy() override;
286 bool hasBreak() const override;
287 bool hasContinue() const override;
289 void accept(Visitor *v) override { v->visit(this); }
292 class DoStatement final : public Statement
294 public:
295 Statement *_body;
296 Expression *condition;
297 Loc endloc; // location of ';' after while
299 DoStatement *syntaxCopy() override;
300 bool hasBreak() const override;
301 bool hasContinue() const override;
303 void accept(Visitor *v) override { v->visit(this); }
306 class ForStatement final : public Statement
308 public:
309 Statement *_init;
310 Expression *condition;
311 Expression *increment;
312 Statement *_body;
313 Loc endloc; // location of closing curly bracket
315 // When wrapped in try/finally clauses, this points to the outermost one,
316 // which may have an associated label. Internal break/continue statements
317 // treat that label as referring to this loop.
318 Statement *relatedLabeled;
320 ForStatement *syntaxCopy() override;
321 Statement *getRelatedLabeled() override { return relatedLabeled ? relatedLabeled : this; }
322 bool hasBreak() const override;
323 bool hasContinue() const override;
325 void accept(Visitor *v) override { v->visit(this); }
328 class ForeachStatement final : public Statement
330 public:
331 TOK op; // TOKforeach or TOKforeach_reverse
332 Parameters *parameters; // array of Parameter*'s
333 Expression *aggr;
334 Statement *_body;
335 Loc endloc; // location of closing curly bracket
337 VarDeclaration *key;
338 VarDeclaration *value;
340 FuncDeclaration *func; // function we're lexically in
342 Statements *cases; // put breaks, continues, gotos and returns here
343 ScopeStatements *gotos; // forward referenced goto's go here
345 ForeachStatement *syntaxCopy() override;
346 bool hasBreak() const override;
347 bool hasContinue() const override;
349 void accept(Visitor *v) override { v->visit(this); }
352 class ForeachRangeStatement final : public Statement
354 public:
355 TOK op; // TOKforeach or TOKforeach_reverse
356 Parameter *prm; // loop index variable
357 Expression *lwr;
358 Expression *upr;
359 Statement *_body;
360 Loc endloc; // location of closing curly bracket
362 VarDeclaration *key;
364 ForeachRangeStatement *syntaxCopy() override;
365 bool hasBreak() const override;
366 bool hasContinue() const override;
368 void accept(Visitor *v) override { v->visit(this); }
371 class IfStatement final : public Statement
373 public:
374 Parameter *prm;
375 Expression *condition;
376 Statement *ifbody;
377 Statement *elsebody;
378 VarDeclaration *match; // for MatchExpression results
379 Loc endloc; // location of closing curly bracket
381 IfStatement *syntaxCopy() override;
383 void accept(Visitor *v) override { v->visit(this); }
384 bool isIfCtfeBlock();
387 class ConditionalStatement final : public Statement
389 public:
390 Condition *condition;
391 Statement *ifbody;
392 Statement *elsebody;
394 ConditionalStatement *syntaxCopy() override;
396 void accept(Visitor *v) override { v->visit(this); }
399 class StaticForeachStatement final : public Statement
401 public:
402 StaticForeach *sfe;
404 StaticForeachStatement *syntaxCopy() override;
406 void accept(Visitor *v) override { v->visit(this); }
409 class PragmaStatement final : public Statement
411 public:
412 Identifier *ident;
413 Expressions *args; // array of Expression's
414 Statement *_body;
416 PragmaStatement *syntaxCopy() override;
418 void accept(Visitor *v) override { v->visit(this); }
421 class StaticAssertStatement final : public Statement
423 public:
424 StaticAssert *sa;
426 StaticAssertStatement *syntaxCopy() override;
428 void accept(Visitor *v) override { v->visit(this); }
431 class SwitchStatement final : public Statement
433 public:
434 Expression *condition;
435 Statement *_body;
436 bool isFinal;
438 DefaultStatement *sdefault;
439 Statement *tryBody; // set to TryCatchStatement or TryFinallyStatement if in _body portion
440 TryFinallyStatement *tf;
441 GotoCaseStatements gotoCases; // array of unresolved GotoCaseStatement's
442 CaseStatements *cases; // array of CaseStatement's
443 int hasNoDefault; // !=0 if no default statement
444 int hasVars; // !=0 if has variable case values
445 VarDeclaration *lastVar;
447 SwitchStatement *syntaxCopy() override;
448 bool hasBreak() const override;
450 void accept(Visitor *v) override { v->visit(this); }
453 class CaseStatement final : public Statement
455 public:
456 Expression *exp;
457 Statement *statement;
459 int index; // which case it is (since we sort this)
460 VarDeclaration *lastVar;
461 void* extra; // for use by Statement_toIR()
463 CaseStatement *syntaxCopy() override;
465 void accept(Visitor *v) override { v->visit(this); }
469 class CaseRangeStatement final : public Statement
471 public:
472 Expression *first;
473 Expression *last;
474 Statement *statement;
476 CaseRangeStatement *syntaxCopy() override;
477 void accept(Visitor *v) override { v->visit(this); }
481 class DefaultStatement final : public Statement
483 public:
484 Statement *statement;
485 VarDeclaration *lastVar;
487 DefaultStatement *syntaxCopy() override;
489 void accept(Visitor *v) override { v->visit(this); }
492 class GotoDefaultStatement final : public Statement
494 public:
495 SwitchStatement *sw;
497 GotoDefaultStatement *syntaxCopy() override;
499 void accept(Visitor *v) override { v->visit(this); }
502 class GotoCaseStatement final : public Statement
504 public:
505 Expression *exp; // NULL, or which case to goto
506 CaseStatement *cs; // case statement it resolves to
508 GotoCaseStatement *syntaxCopy() override;
510 void accept(Visitor *v) override { v->visit(this); }
513 class SwitchErrorStatement final : public Statement
515 public:
516 Expression *exp;
518 void accept(Visitor *v) override { v->visit(this); }
521 class ReturnStatement final : public Statement
523 public:
524 Expression *exp;
525 size_t caseDim;
527 ReturnStatement *syntaxCopy() override;
529 ReturnStatement *endsWithReturnStatement() override { return this; }
530 void accept(Visitor *v) override { v->visit(this); }
533 class BreakStatement final : public Statement
535 public:
536 Identifier *ident;
538 BreakStatement *syntaxCopy() override;
540 void accept(Visitor *v) override { v->visit(this); }
543 class ContinueStatement final : public Statement
545 public:
546 Identifier *ident;
548 ContinueStatement *syntaxCopy() override;
550 void accept(Visitor *v) override { v->visit(this); }
553 class SynchronizedStatement final : public Statement
555 public:
556 Expression *exp;
557 Statement *_body;
559 SynchronizedStatement *syntaxCopy() override;
560 bool hasBreak() const override;
561 bool hasContinue() const override;
563 void accept(Visitor *v) override { v->visit(this); }
566 class WithStatement final : public Statement
568 public:
569 Expression *exp;
570 Statement *_body;
571 VarDeclaration *wthis;
572 Loc endloc;
574 WithStatement *syntaxCopy() override;
576 void accept(Visitor *v) override { v->visit(this); }
579 class TryCatchStatement final : public Statement
581 public:
582 Statement *_body;
583 Catches *catches;
585 Statement *tryBody; /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
587 TryCatchStatement *syntaxCopy() override;
588 bool hasBreak() const override;
590 void accept(Visitor *v) override { v->visit(this); }
593 class Catch final : public RootObject
595 public:
596 Loc loc;
597 Type *type;
598 Identifier *ident;
599 Statement *handler;
601 VarDeclaration *var;
602 // set if semantic processing errors
603 bool errors;
605 // was generated by the compiler,
606 // wasn't present in source code
607 bool internalCatch;
609 Catch *syntaxCopy();
612 class TryFinallyStatement final : public Statement
614 public:
615 Statement *_body;
616 Statement *finalbody;
618 Statement *tryBody; // set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
619 bool bodyFallsThru; // true if _body falls through to finally
621 static TryFinallyStatement *create(const Loc &loc, Statement *body, Statement *finalbody);
622 TryFinallyStatement *syntaxCopy() override;
623 bool hasBreak() const override;
624 bool hasContinue() const override;
626 void accept(Visitor *v) override { v->visit(this); }
629 class ScopeGuardStatement final : public Statement
631 public:
632 TOK tok;
633 Statement *statement;
635 ScopeGuardStatement *syntaxCopy() override;
637 void accept(Visitor *v) override { v->visit(this); }
640 class ThrowStatement final : public Statement
642 public:
643 Expression *exp;
644 // was generated by the compiler,
645 // wasn't present in source code
646 bool internalThrow;
648 ThrowStatement *syntaxCopy() override;
650 void accept(Visitor *v) override { v->visit(this); }
653 class DebugStatement final : public Statement
655 public:
656 Statement *statement;
658 DebugStatement *syntaxCopy() override;
659 void accept(Visitor *v) override { v->visit(this); }
662 class GotoStatement final : public Statement
664 public:
665 Identifier *ident;
666 LabelDsymbol *label;
667 Statement *tryBody; /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
668 TryFinallyStatement *tf;
669 ScopeGuardStatement *os;
670 VarDeclaration *lastVar;
671 bool inCtfeBlock;
672 GotoStatement *syntaxCopy() override;
674 void accept(Visitor *v) override { v->visit(this); }
677 class LabelStatement final : public Statement
679 public:
680 Identifier *ident;
681 Statement *statement;
682 Statement *tryBody; /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
683 TryFinallyStatement *tf;
684 ScopeGuardStatement *os;
685 VarDeclaration *lastVar;
686 Statement *gotoTarget; // interpret
687 void* extra; // used by Statement_toIR()
688 bool breaks; // someone did a 'break ident'
689 bool inCtfeBlock;
690 LabelStatement *syntaxCopy() override;
692 void accept(Visitor *v) override { v->visit(this); }
695 class LabelDsymbol final : public Dsymbol
697 public:
698 LabelStatement *statement;
700 bool deleted; // set if rewritten to return in foreach delegate
701 bool iasm; // set if used by inline assembler
703 static LabelDsymbol *create(Identifier *ident);
704 LabelDsymbol *isLabel() override;
705 void accept(Visitor *v) override { v->visit(this); }
708 Statement* asmSemantic(AsmStatement *s, Scope *sc);
710 class AsmStatement : public Statement
712 public:
713 Token *tokens;
715 AsmStatement *syntaxCopy() override;
716 void accept(Visitor *v) override { v->visit(this); }
719 class InlineAsmStatement final : public AsmStatement
721 public:
722 code *asmcode;
723 unsigned asmalign; // alignment of this statement
724 unsigned regs; // mask of registers modified (must match regm_t in back end)
725 bool refparam; // true if function parameter is referenced
726 bool naked; // true if function is to be naked
728 InlineAsmStatement *syntaxCopy() override;
729 void accept(Visitor *v) override { v->visit(this); }
732 // A GCC asm statement - assembler instructions with D expression operands
733 class GccAsmStatement final : public AsmStatement
735 public:
736 StorageClass stc; // attributes of the asm {} block
737 Expression *insn; // string expression that is the template for assembler code
738 Expressions *args; // input and output operands of the statement
739 unsigned outputargs; // of the operands in 'args', the number of output operands
740 Identifiers *names; // list of symbolic names for the operands
741 Expressions *constraints; // list of string constants specifying constraints on operands
742 Expressions *clobbers; // list of string constants specifying clobbers and scratch registers
743 Identifiers *labels; // list of goto labels
744 GotoStatements *gotos; // of the goto labels, the equivalent statements they represent
746 GccAsmStatement *syntaxCopy() override;
747 void accept(Visitor *v) override { v->visit(this); }
750 // a complete asm {} block
751 class CompoundAsmStatement final : public CompoundStatement
753 public:
754 StorageClass stc; // postfix attributes like nothrow/pure/@trusted
756 CompoundAsmStatement *syntaxCopy() override;
758 void accept(Visitor *v) override { v->visit(this); }
761 class ImportStatement final : public Statement
763 public:
764 Dsymbols *imports; // Array of Import's
766 ImportStatement *syntaxCopy() override;
768 void accept(Visitor *v) override { v->visit(this); }