d: Merge upstream dmd, druntime 4c18eed967, phobos d945686a4.
[official-gcc.git] / gcc / d / dmd / statement.h
blobfe899c6a496374a4f34c31f576a2ed1c769f3ef4
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 STMTmixin,
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 void error(const char *format, ...);
117 void warning(unsigned flag, const char *format, ...);
118 void deprecation(const char *format, ...);
119 virtual Statement *getRelatedLabeled() { return this; }
120 virtual bool hasBreak() const;
121 virtual bool hasContinue() const;
122 bool usesEH();
123 bool comeFrom();
124 bool hasCode();
125 virtual Statement *last();
127 virtual ReturnStatement *endsWithReturnStatement() { return NULL; }
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 MixinStatement *isMixinStatement() { return stmt == STMTmixin ? (MixinStatement*)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; }
162 void accept(Visitor *v) override { v->visit(this); }
165 /** Any Statement that fails semantic() or has a component that is an ErrorExp or
166 * a TypeError should return an ErrorStatement from semantic().
168 class ErrorStatement final : public Statement
170 public:
171 ErrorStatement *syntaxCopy() override;
173 void accept(Visitor *v) override { v->visit(this); }
176 class PeelStatement final : public Statement
178 public:
179 Statement *s;
181 void accept(Visitor *v) override { v->visit(this); }
184 class ExpStatement : public Statement
186 public:
187 Expression *exp;
189 static ExpStatement *create(const Loc &loc, Expression *exp);
190 ExpStatement *syntaxCopy() override;
192 void accept(Visitor *v) override { v->visit(this); }
195 class DtorExpStatement final : public ExpStatement
197 public:
198 /* Wraps an expression that is the destruction of 'var'
201 VarDeclaration *var;
203 DtorExpStatement *syntaxCopy() override;
204 void accept(Visitor *v) override { v->visit(this); }
207 class MixinStatement final : public Statement
209 public:
210 Expressions *exps;
212 MixinStatement *syntaxCopy() override;
213 void accept(Visitor *v) override { v->visit(this); }
216 class CompoundStatement : public Statement
218 public:
219 Statements *statements;
221 static CompoundStatement *create(const Loc &loc, Statement *s1, Statement *s2);
222 CompoundStatement *syntaxCopy() override;
223 ReturnStatement *endsWithReturnStatement() override final;
224 Statement *last() override final;
226 void accept(Visitor *v) override { v->visit(this); }
229 class CompoundDeclarationStatement final : public CompoundStatement
231 public:
232 CompoundDeclarationStatement *syntaxCopy() override;
233 void accept(Visitor *v) override { v->visit(this); }
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.
239 class UnrolledLoopStatement final : public Statement
241 public:
242 Statements *statements;
244 UnrolledLoopStatement *syntaxCopy() override;
245 bool hasBreak() const override;
246 bool hasContinue() const override;
248 void accept(Visitor *v) override { v->visit(this); }
251 class ScopeStatement final : public Statement
253 public:
254 Statement *statement;
255 Loc endloc; // location of closing curly bracket
257 ScopeStatement *syntaxCopy() override;
258 ReturnStatement *endsWithReturnStatement() override;
259 bool hasBreak() const override;
260 bool hasContinue() const override;
262 void accept(Visitor *v) override { v->visit(this); }
265 class ForwardingStatement final : public Statement
267 public:
268 ForwardingScopeDsymbol *sym;
269 Statement *statement;
271 ForwardingStatement *syntaxCopy() override;
272 void accept(Visitor *v) override { v->visit(this); }
275 class WhileStatement final : public Statement
277 public:
278 Parameter *param;
279 Expression *condition;
280 Statement *_body;
281 Loc endloc; // location of closing curly bracket
283 WhileStatement *syntaxCopy() override;
284 bool hasBreak() const override;
285 bool hasContinue() const override;
287 void accept(Visitor *v) override { v->visit(this); }
290 class DoStatement final : public Statement
292 public:
293 Statement *_body;
294 Expression *condition;
295 Loc endloc; // location of ';' after while
297 DoStatement *syntaxCopy() override;
298 bool hasBreak() const override;
299 bool hasContinue() const override;
301 void accept(Visitor *v) override { v->visit(this); }
304 class ForStatement final : public Statement
306 public:
307 Statement *_init;
308 Expression *condition;
309 Expression *increment;
310 Statement *_body;
311 Loc endloc; // location of closing curly bracket
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;
318 ForStatement *syntaxCopy() override;
319 Statement *getRelatedLabeled() override { return relatedLabeled ? relatedLabeled : this; }
320 bool hasBreak() const override;
321 bool hasContinue() const override;
323 void accept(Visitor *v) override { v->visit(this); }
326 class ForeachStatement final : public Statement
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
335 VarDeclaration *key;
336 VarDeclaration *value;
338 FuncDeclaration *func; // function we're lexically in
340 Statements *cases; // put breaks, continues, gotos and returns here
341 ScopeStatements *gotos; // forward referenced goto's go here
343 ForeachStatement *syntaxCopy() override;
344 bool hasBreak() const override;
345 bool hasContinue() const override;
347 void accept(Visitor *v) override { v->visit(this); }
350 class ForeachRangeStatement final : public Statement
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
360 VarDeclaration *key;
362 ForeachRangeStatement *syntaxCopy() override;
363 bool hasBreak() const override;
364 bool hasContinue() const override;
366 void accept(Visitor *v) override { v->visit(this); }
369 class IfStatement final : public Statement
371 public:
372 Parameter *prm;
373 Expression *condition;
374 Statement *ifbody;
375 Statement *elsebody;
376 VarDeclaration *match; // for MatchExpression results
377 Loc endloc; // location of closing curly bracket
379 IfStatement *syntaxCopy() override;
381 void accept(Visitor *v) override { v->visit(this); }
382 bool isIfCtfeBlock();
385 class ConditionalStatement final : public Statement
387 public:
388 Condition *condition;
389 Statement *ifbody;
390 Statement *elsebody;
392 ConditionalStatement *syntaxCopy() override;
394 void accept(Visitor *v) override { v->visit(this); }
397 class StaticForeachStatement final : public Statement
399 public:
400 StaticForeach *sfe;
402 StaticForeachStatement *syntaxCopy() override;
404 void accept(Visitor *v) override { v->visit(this); }
407 class PragmaStatement final : public Statement
409 public:
410 Identifier *ident;
411 Expressions *args; // array of Expression's
412 Statement *_body;
414 PragmaStatement *syntaxCopy() override;
416 void accept(Visitor *v) override { v->visit(this); }
419 class StaticAssertStatement final : public Statement
421 public:
422 StaticAssert *sa;
424 StaticAssertStatement *syntaxCopy() override;
426 void accept(Visitor *v) override { v->visit(this); }
429 class SwitchStatement final : public Statement
431 public:
432 Parameter *param;
433 Expression *condition;
434 Statement *_body;
435 d_bool isFinal;
436 Loc endloc;
438 d_bool hasDefault; // true if default statement
439 d_bool hasVars; // true if has variable case values
440 DefaultStatement *sdefault;
441 Statement *tryBody; // set to TryCatchStatement or TryFinallyStatement if in _body portion
442 TryFinallyStatement *tf;
443 GotoCaseStatements gotoCases; // array of unresolved GotoCaseStatement's
444 CaseStatements *cases; // array of CaseStatement's
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 d_bool errors;
605 // was generated by the compiler,
606 // wasn't present in source code
607 d_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 d_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 d_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 d_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 d_bool breaks; // someone did a 'break ident'
689 d_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 d_bool deleted; // set if rewritten to return in foreach delegate
701 d_bool iasm; // set if used by inline assembler
702 d_bool duplicated; // set if multiply defined, to avoid duplicate error messages
704 static LabelDsymbol *create(Identifier *ident);
705 LabelDsymbol *isLabel() override;
706 void accept(Visitor *v) override { v->visit(this); }
709 Statement* asmSemantic(AsmStatement *s, Scope *sc);
711 class AsmStatement : public Statement
713 public:
714 Token *tokens;
715 bool caseSensitive; // for register names
717 AsmStatement *syntaxCopy() override;
718 void accept(Visitor *v) override { v->visit(this); }
721 class InlineAsmStatement final : public AsmStatement
723 public:
724 code *asmcode;
725 unsigned asmalign; // alignment of this statement
726 unsigned regs; // mask of registers modified (must match regm_t in back end)
727 d_bool refparam; // true if function parameter is referenced
728 d_bool naked; // true if function is to be naked
730 InlineAsmStatement *syntaxCopy() override;
731 void accept(Visitor *v) override { v->visit(this); }
734 // A GCC asm statement - assembler instructions with D expression operands
735 class GccAsmStatement final : public AsmStatement
737 public:
738 StorageClass stc; // attributes of the asm {} block
739 Expression *insn; // string expression that is the template for assembler code
740 Expressions *args; // input and output operands of the statement
741 unsigned outputargs; // of the operands in 'args', the number of output operands
742 Identifiers *names; // list of symbolic names for the operands
743 Expressions *constraints; // list of string constants specifying constraints on operands
744 Expressions *clobbers; // list of string constants specifying clobbers and scratch registers
745 Identifiers *labels; // list of goto labels
746 GotoStatements *gotos; // of the goto labels, the equivalent statements they represent
748 GccAsmStatement *syntaxCopy() override;
749 void accept(Visitor *v) override { v->visit(this); }
752 // a complete asm {} block
753 class CompoundAsmStatement final : public CompoundStatement
755 public:
756 StorageClass stc; // postfix attributes like nothrow/pure/@trusted
758 CompoundAsmStatement *syntaxCopy() override;
760 void accept(Visitor *v) override { v->visit(this); }
763 class ImportStatement final : public Statement
765 public:
766 Dsymbols *imports; // Array of Import's
768 ImportStatement *syntaxCopy() override;
770 void accept(Visitor *v) override { v->visit(this); }