d: Merge upstream dmd, druntime e48bc0987d, phobos 2458e8f82.
[official-gcc.git] / gcc / d / dmd / statement.d
blobb5906c8edc31cadcea601a5adb276c9a856ae048
1 /**
2 * Defines AST nodes for statements.
4 * Specification: $(LINK2 https://dlang.org/spec/statement.html, Statements)
6 * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
7 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
8 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
9 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statement.d, _statement.d)
10 * Documentation: https://dlang.org/phobos/dmd_statement.html
11 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/statement.d
14 module dmd.statement;
16 import core.stdc.stdarg;
17 import core.stdc.stdio;
19 import dmd.arraytypes;
20 import dmd.astenums;
21 import dmd.ast_node;
22 import dmd.errors;
23 import dmd.gluelayer;
24 import dmd.cond;
25 import dmd.declaration;
26 import dmd.dsymbol;
27 import dmd.expression;
28 import dmd.func;
29 import dmd.globals;
30 import dmd.hdrgen;
31 import dmd.id;
32 import dmd.identifier;
33 import dmd.location;
34 import dmd.mtype;
35 import dmd.common.outbuffer;
36 import dmd.rootobject;
37 import dmd.sapply;
38 import dmd.staticassert;
39 import dmd.tokens;
40 import dmd.visitor;
42 /***********************************************************
43 * Specification: https://dlang.org/spec/statement.html
45 extern (C++) abstract class Statement : ASTNode
47 const Loc loc;
48 const STMT stmt;
50 override final DYNCAST dyncast() const
52 return DYNCAST.statement;
55 final extern (D) this(const ref Loc loc, STMT stmt) @safe
57 this.loc = loc;
58 this.stmt = stmt;
59 // If this is an in{} contract scope statement (skip for determining
60 // inlineStatus of a function body for header content)
63 Statement syntaxCopy()
65 assert(0);
68 /*************************************
69 * Do syntax copy of an array of Statement's.
71 static Statements* arraySyntaxCopy(Statements* a)
73 Statements* b = null;
74 if (a)
76 b = a.copy();
77 foreach (i, s; *a)
79 (*b)[i] = s ? s.syntaxCopy() : null;
82 return b;
85 Statement getRelatedLabeled()
87 return this;
90 /****************************
91 * Determine if an enclosed `break` would apply to this
92 * statement, such as if it is a loop or switch statement.
93 * Returns:
94 * `true` if it does
96 bool hasBreak() const pure nothrow
98 //printf("Statement::hasBreak()\n");
99 return false;
102 /****************************
103 * Determine if an enclosed `continue` would apply to this
104 * statement, such as if it is a loop statement.
105 * Returns:
106 * `true` if it does
108 bool hasContinue() const pure nothrow
110 return false;
113 /**********************************
114 * Returns:
115 * `true` if statement uses exception handling
117 extern (D) final bool usesEH()
119 extern (C++) final class UsesEH : StoppableVisitor
121 alias visit = typeof(super).visit;
122 public:
123 override void visit(Statement s)
127 override void visit(TryCatchStatement s)
129 stop = true;
132 override void visit(TryFinallyStatement s)
134 stop = true;
137 override void visit(ScopeGuardStatement s)
139 stop = true;
142 override void visit(SynchronizedStatement s)
144 stop = true;
148 scope UsesEH ueh = new UsesEH();
149 return walkPostorder(this, ueh);
152 /**********************************
153 * Returns:
154 * `true` if statement 'comes from' somewhere else, like a goto
156 extern (D) final bool comeFrom()
158 extern (C++) final class ComeFrom : StoppableVisitor
160 alias visit = typeof(super).visit;
161 public:
162 override void visit(Statement s)
166 override void visit(CaseStatement s)
168 stop = true;
171 override void visit(DefaultStatement s)
173 stop = true;
176 override void visit(LabelStatement s)
178 stop = true;
181 override void visit(AsmStatement s)
183 stop = true;
187 scope ComeFrom cf = new ComeFrom();
188 return walkPostorder(this, cf);
191 /**********************************
192 * Returns:
193 * `true` if statement has executable code.
195 extern (D) final bool hasCode()
197 extern (C++) final class HasCode : StoppableVisitor
199 alias visit = typeof(super).visit;
200 public:
201 override void visit(Statement s)
203 stop = true;
206 override void visit(ExpStatement s)
208 if (s.exp !is null)
210 stop = s.exp.hasCode();
214 override void visit(CompoundStatement s)
218 override void visit(ScopeStatement s)
222 override void visit(ImportStatement s)
226 override void visit(CaseStatement s)
230 override void visit(DefaultStatement s)
234 override void visit(LabelStatement s)
239 scope HasCode hc = new HasCode();
240 return walkPostorder(this, hc);
243 /*******************************
244 * Find last statement in a sequence of statements.
245 * Returns:
246 * the last statement, or `null` if there isn't one
248 inout(Statement) last() inout nothrow pure
250 return this;
253 /**************************
254 * Support Visitor Pattern
255 * Params:
256 * v = visitor
258 override void accept(Visitor v)
260 v.visit(this);
263 /************************************
264 * Does this statement end with a return statement?
266 * I.e. is it a single return statement or some compound statement
267 * that unconditionally hits a return statement.
268 * Returns:
269 * return statement it ends with, otherwise null
271 pure nothrow @nogc
272 inout(ReturnStatement) endsWithReturnStatement() inout { return null; }
274 final pure inout nothrow @nogc @safe:
276 /********************
277 * A cheaper method of doing downcasting of Statements.
278 * Returns:
279 * the downcast statement if it can be downcasted, otherwise `null`
281 inout(ErrorStatement) isErrorStatement() { return stmt == STMT.Error ? cast(typeof(return))this : null; }
282 inout(PeelStatement) isPeelStatement() { return stmt == STMT.Peel ? cast(typeof(return))this : null; }
283 inout(ScopeStatement) isScopeStatement() { return stmt == STMT.Scope ? cast(typeof(return))this : null; }
284 inout(ExpStatement) isExpStatement() { return stmt == STMT.Exp ? cast(typeof(return))this : null; }
285 inout(CompoundStatement) isCompoundStatement() { return stmt == STMT.Compound ? cast(typeof(return))this : null; }
286 inout(ReturnStatement) isReturnStatement() { return stmt == STMT.Return ? cast(typeof(return))this : null; }
287 inout(IfStatement) isIfStatement() { return stmt == STMT.If ? cast(typeof(return))this : null; }
288 inout(ConditionalStatement) isConditionalStatement() { return stmt == STMT.Conditional ? cast(typeof(return))this : null; }
289 inout(StaticForeachStatement) isStaticForeachStatement() { return stmt == STMT.StaticForeach ? cast(typeof(return))this : null; }
290 inout(CaseStatement) isCaseStatement() { return stmt == STMT.Case ? cast(typeof(return))this : null; }
291 inout(DefaultStatement) isDefaultStatement() { return stmt == STMT.Default ? cast(typeof(return))this : null; }
292 inout(LabelStatement) isLabelStatement() { return stmt == STMT.Label ? cast(typeof(return))this : null; }
293 inout(GotoStatement) isGotoStatement() { return stmt == STMT.Goto ? cast(typeof(return))this : null; }
294 inout(GotoDefaultStatement) isGotoDefaultStatement() { return stmt == STMT.GotoDefault ? cast(typeof(return))this : null; }
295 inout(GotoCaseStatement) isGotoCaseStatement() { return stmt == STMT.GotoCase ? cast(typeof(return))this : null; }
296 inout(BreakStatement) isBreakStatement() { return stmt == STMT.Break ? cast(typeof(return))this : null; }
297 inout(DtorExpStatement) isDtorExpStatement() { return stmt == STMT.DtorExp ? cast(typeof(return))this : null; }
298 inout(MixinStatement) isMixinStatement() { return stmt == STMT.Mixin ? cast(typeof(return))this : null; }
299 inout(ForwardingStatement) isForwardingStatement() { return stmt == STMT.Forwarding ? cast(typeof(return))this : null; }
300 inout(DoStatement) isDoStatement() { return stmt == STMT.Do ? cast(typeof(return))this : null; }
301 inout(WhileStatement) isWhileStatement() { return stmt == STMT.While ? cast(typeof(return))this : null; }
302 inout(ForStatement) isForStatement() { return stmt == STMT.For ? cast(typeof(return))this : null; }
303 inout(ForeachStatement) isForeachStatement() { return stmt == STMT.Foreach ? cast(typeof(return))this : null; }
304 inout(SwitchStatement) isSwitchStatement() { return stmt == STMT.Switch ? cast(typeof(return))this : null; }
305 inout(ContinueStatement) isContinueStatement() { return stmt == STMT.Continue ? cast(typeof(return))this : null; }
306 inout(WithStatement) isWithStatement() { return stmt == STMT.With ? cast(typeof(return))this : null; }
307 inout(TryCatchStatement) isTryCatchStatement() { return stmt == STMT.TryCatch ? cast(typeof(return))this : null; }
308 inout(ThrowStatement) isThrowStatement() { return stmt == STMT.Throw ? cast(typeof(return))this : null; }
309 inout(DebugStatement) isDebugStatement() { return stmt == STMT.Debug ? cast(typeof(return))this : null; }
310 inout(TryFinallyStatement) isTryFinallyStatement() { return stmt == STMT.TryFinally ? cast(typeof(return))this : null; }
311 inout(ScopeGuardStatement) isScopeGuardStatement() { return stmt == STMT.ScopeGuard ? cast(typeof(return))this : null; }
312 inout(SwitchErrorStatement) isSwitchErrorStatement() { return stmt == STMT.SwitchError ? cast(typeof(return))this : null; }
313 inout(UnrolledLoopStatement) isUnrolledLoopStatement() { return stmt == STMT.UnrolledLoop ? cast(typeof(return))this : null; }
314 inout(ForeachRangeStatement) isForeachRangeStatement() { return stmt == STMT.ForeachRange ? cast(typeof(return))this : null; }
315 inout(CompoundDeclarationStatement) isCompoundDeclarationStatement() { return stmt == STMT.CompoundDeclaration ? cast(typeof(return))this : null; }
316 inout(CompoundAsmStatement) isCompoundAsmStatement() { return stmt == STMT.CompoundAsm ? cast(typeof(return))this : null; }
317 inout(PragmaStatement) isPragmaStatement() { return stmt == STMT.Pragma ? cast(typeof(return))this : null; }
318 inout(StaticAssertStatement) isStaticAssertStatement() { return stmt == STMT.StaticAssert ? cast(typeof(return))this : null; }
319 inout(CaseRangeStatement) isCaseRangeStatement() { return stmt == STMT.CaseRange ? cast(typeof(return))this : null; }
320 inout(SynchronizedStatement) isSynchronizedStatement() { return stmt == STMT.Synchronized ? cast(typeof(return))this : null; }
321 inout(AsmStatement) isAsmStatement() { return stmt == STMT.Asm ? cast(typeof(return))this : null; }
322 inout(InlineAsmStatement) isInlineAsmStatement() { return stmt == STMT.InlineAsm ? cast(typeof(return))this : null; }
323 inout(GccAsmStatement) isGccAsmStatement() { return stmt == STMT.GccAsm ? cast(typeof(return))this : null; }
324 inout(ImportStatement) isImportStatement() { return stmt == STMT.Import ? cast(typeof(return))this : null; }
327 /***********************************************************
328 * Any Statement that fails semantic() or has a component that is an ErrorExp or
329 * a TypeError should return an ErrorStatement from semantic().
331 extern (C++) final class ErrorStatement : Statement
333 extern (D) this()
335 super(Loc.initial, STMT.Error);
336 assert(global.gaggedErrors || global.errors);
339 override ErrorStatement syntaxCopy()
341 return this;
344 override void accept(Visitor v)
346 v.visit(this);
350 /***********************************************************
352 extern (C++) final class PeelStatement : Statement
354 Statement s;
356 extern (D) this(Statement s) @safe
358 super(s.loc, STMT.Peel);
359 this.s = s;
362 override void accept(Visitor v)
364 v.visit(this);
369 /***********************************************************
370 * https://dlang.org/spec/statement.html#ExpressionStatement
372 extern (C++) class ExpStatement : Statement
374 Expression exp;
376 final extern (D) this(const ref Loc loc, Expression exp) @safe
378 super(loc, STMT.Exp);
379 this.exp = exp;
382 final extern (D) this(const ref Loc loc, Expression exp, STMT stmt) @safe
384 super(loc, stmt);
385 this.exp = exp;
388 final extern (D) this(const ref Loc loc, Dsymbol declaration) @safe
390 super(loc, STMT.Exp);
391 this.exp = new DeclarationExp(loc, declaration);
394 static ExpStatement create(const ref Loc loc, Expression exp) @safe
396 return new ExpStatement(loc, exp);
399 override ExpStatement syntaxCopy()
401 return new ExpStatement(loc, exp ? exp.syntaxCopy() : null);
404 override void accept(Visitor v)
406 v.visit(this);
410 /***********************************************************
412 extern (C++) final class DtorExpStatement : ExpStatement
414 // Wraps an expression that is the destruction of 'var'
415 VarDeclaration var;
417 extern (D) this(const ref Loc loc, Expression exp, VarDeclaration var) @safe
419 super(loc, exp, STMT.DtorExp);
420 this.var = var;
423 override DtorExpStatement syntaxCopy()
425 return new DtorExpStatement(loc, exp ? exp.syntaxCopy() : null, var);
428 override void accept(Visitor v)
430 v.visit(this);
434 /***********************************************************
435 * https://dlang.org/spec/statement.html#mixin-statement
437 // Note: was called CompileStatement
438 extern (C++) final class MixinStatement : Statement
440 Expressions* exps;
442 extern (D) this(const ref Loc loc, Expression exp)
444 Expressions* exps = new Expressions();
445 exps.push(exp);
446 this(loc, exps);
449 extern (D) this(const ref Loc loc, Expressions* exps) @safe
451 super(loc, STMT.Mixin);
452 this.exps = exps;
455 override MixinStatement syntaxCopy()
457 return new MixinStatement(loc, Expression.arraySyntaxCopy(exps));
460 override void accept(Visitor v)
462 v.visit(this);
466 /***********************************************************
468 extern (C++) class CompoundStatement : Statement
470 Statements* statements;
473 * Construct a `CompoundStatement` using an already existing
474 * array of `Statement`s
476 * Params:
477 * loc = Instantiation information
478 * statements = An array of `Statement`s, that will referenced by this class
480 final extern (D) this(const ref Loc loc, Statements* statements) @safe
482 super(loc, STMT.Compound);
483 this.statements = statements;
486 final extern (D) this(const ref Loc loc, Statements* statements, STMT stmt) @safe
488 super(loc, stmt);
489 this.statements = statements;
493 * Construct a `CompoundStatement` from an array of `Statement`s
495 * Params:
496 * loc = Instantiation information
497 * sts = A variadic array of `Statement`s, that will copied in this class
498 * The entries themselves will not be copied.
500 final extern (D) this(const ref Loc loc, Statement[] sts...)
502 super(loc, STMT.Compound);
503 statements = new Statements();
504 statements.reserve(sts.length);
505 foreach (s; sts)
506 statements.push(s);
509 static CompoundStatement create(const ref Loc loc, Statement s1, Statement s2)
511 return new CompoundStatement(loc, s1, s2);
514 override CompoundStatement syntaxCopy()
516 return new CompoundStatement(loc, Statement.arraySyntaxCopy(statements));
519 override final inout(ReturnStatement) endsWithReturnStatement() inout nothrow pure
521 foreach (s; *statements)
523 if (s)
525 if (inout rs = s.endsWithReturnStatement())
526 return rs;
529 return null;
532 override final inout(Statement) last() inout nothrow pure
534 Statement s = null;
535 for (size_t i = statements.length; i; --i)
537 s = cast(Statement)(*statements)[i - 1];
538 if (s)
540 s = cast(Statement)s.last();
541 if (s)
542 break;
545 return cast(inout)s;
548 override void accept(Visitor v)
550 v.visit(this);
554 /***********************************************************
556 extern (C++) final class CompoundDeclarationStatement : CompoundStatement
558 extern (D) this(const ref Loc loc, Statements* statements) @safe
560 super(loc, statements, STMT.CompoundDeclaration);
563 override CompoundDeclarationStatement syntaxCopy()
565 return new CompoundDeclarationStatement(loc, Statement.arraySyntaxCopy(statements));
568 override void accept(Visitor v)
570 v.visit(this);
574 /***********************************************************
575 * The purpose of this is so that continue will go to the next
576 * of the statements, and break will go to the end of the statements.
578 extern (C++) final class UnrolledLoopStatement : Statement
580 Statements* statements;
582 extern (D) this(const ref Loc loc, Statements* statements) @safe
584 super(loc, STMT.UnrolledLoop);
585 this.statements = statements;
588 override UnrolledLoopStatement syntaxCopy()
590 return new UnrolledLoopStatement(loc, Statement.arraySyntaxCopy(statements));
593 override bool hasBreak() const pure nothrow
595 return true;
598 override bool hasContinue() const pure nothrow
600 return true;
603 override void accept(Visitor v)
605 v.visit(this);
609 /***********************************************************
611 extern (C++) final class ScopeStatement : Statement
613 Statement statement;
614 Loc endloc; // location of closing curly bracket
616 extern (D) this(const ref Loc loc, Statement statement, Loc endloc) @safe
618 super(loc, STMT.Scope);
619 this.statement = statement;
620 this.endloc = endloc;
623 override ScopeStatement syntaxCopy()
625 return new ScopeStatement(loc, statement ? statement.syntaxCopy() : null, endloc);
628 override inout(ReturnStatement) endsWithReturnStatement() inout nothrow pure
630 if (statement)
631 return statement.endsWithReturnStatement();
632 return null;
635 override bool hasBreak() const pure nothrow
637 //printf("ScopeStatement::hasBreak() %s\n", toChars());
638 return statement ? statement.hasBreak() : false;
641 override bool hasContinue() const pure nothrow
643 return statement ? statement.hasContinue() : false;
646 override void accept(Visitor v)
648 v.visit(this);
652 /***********************************************************
653 * Statement whose symbol table contains foreach index variables in a
654 * local scope and forwards other members to the parent scope. This
655 * wraps a statement.
657 * Also see: `dmd.attrib.ForwardingAttribDeclaration`
659 extern (C++) final class ForwardingStatement : Statement
661 /// The symbol containing the `static foreach` variables.
662 ForwardingScopeDsymbol sym = null;
663 /// The wrapped statement.
664 Statement statement;
666 extern (D) this(const ref Loc loc, ForwardingScopeDsymbol sym, Statement statement) @safe
668 super(loc, STMT.Forwarding);
669 this.sym = sym;
670 assert(statement);
671 this.statement = statement;
674 extern (D) this(const ref Loc loc, Statement statement) @safe
676 auto sym = new ForwardingScopeDsymbol();
677 sym.symtab = new DsymbolTable();
678 this(loc, sym, statement);
681 override ForwardingStatement syntaxCopy()
683 return new ForwardingStatement(loc, statement.syntaxCopy());
686 override void accept(Visitor v)
688 v.visit(this);
693 /***********************************************************
694 * https://dlang.org/spec/statement.html#while-statement
696 extern (C++) final class WhileStatement : Statement
698 Parameter param;
699 Expression condition;
700 Statement _body;
701 Loc endloc; // location of closing curly bracket
703 extern (D) this(const ref Loc loc, Expression condition, Statement _body, Loc endloc, Parameter param = null) @safe
705 super(loc, STMT.While);
706 this.condition = condition;
707 this._body = _body;
708 this.endloc = endloc;
709 this.param = param;
712 override WhileStatement syntaxCopy()
714 return new WhileStatement(loc,
715 condition.syntaxCopy(),
716 _body ? _body.syntaxCopy() : null,
717 endloc, param ? param.syntaxCopy() : null);
720 override bool hasBreak() const pure nothrow
722 return true;
725 override bool hasContinue() const pure nothrow
727 return true;
730 override void accept(Visitor v)
732 v.visit(this);
736 /***********************************************************
737 * https://dlang.org/spec/statement.html#do-statement
739 extern (C++) final class DoStatement : Statement
741 Statement _body;
742 Expression condition;
743 Loc endloc; // location of ';' after while
745 extern (D) this(const ref Loc loc, Statement _body, Expression condition, Loc endloc) @safe
747 super(loc, STMT.Do);
748 this._body = _body;
749 this.condition = condition;
750 this.endloc = endloc;
753 override DoStatement syntaxCopy()
755 return new DoStatement(loc,
756 _body ? _body.syntaxCopy() : null,
757 condition.syntaxCopy(),
758 endloc);
761 override bool hasBreak() const pure nothrow
763 return true;
766 override bool hasContinue() const pure nothrow
768 return true;
771 override void accept(Visitor v)
773 v.visit(this);
777 /***********************************************************
778 * https://dlang.org/spec/statement.html#for-statement
780 extern (C++) final class ForStatement : Statement
782 Statement _init;
783 Expression condition;
784 Expression increment;
785 Statement _body;
786 Loc endloc; // location of closing curly bracket
788 // When wrapped in try/finally clauses, this points to the outermost one,
789 // which may have an associated label. Internal break/continue statements
790 // treat that label as referring to this loop.
791 Statement relatedLabeled;
793 extern (D) this(const ref Loc loc, Statement _init, Expression condition, Expression increment, Statement _body, Loc endloc) @safe
795 super(loc, STMT.For);
796 this._init = _init;
797 this.condition = condition;
798 this.increment = increment;
799 this._body = _body;
800 this.endloc = endloc;
803 override ForStatement syntaxCopy()
805 return new ForStatement(loc,
806 _init ? _init.syntaxCopy() : null,
807 condition ? condition.syntaxCopy() : null,
808 increment ? increment.syntaxCopy() : null,
809 _body.syntaxCopy(),
810 endloc);
813 override Statement getRelatedLabeled()
815 return relatedLabeled ? relatedLabeled : this;
818 override bool hasBreak() const pure nothrow
820 //printf("ForStatement::hasBreak()\n");
821 return true;
824 override bool hasContinue() const pure nothrow
826 return true;
829 override void accept(Visitor v)
831 v.visit(this);
835 /***********************************************************
836 * https://dlang.org/spec/statement.html#foreach-statement
838 extern (C++) final class ForeachStatement : Statement
840 TOK op; // TOK.foreach_ or TOK.foreach_reverse_
841 Parameters* parameters; // array of Parameters, one for each ForeachType
842 Expression aggr; // ForeachAggregate
843 Statement _body; // NoScopeNonEmptyStatement
844 Loc endloc; // location of closing curly bracket
846 VarDeclaration key;
847 VarDeclaration value;
849 FuncDeclaration func; // function we're lexically in
851 Statements* cases; // put breaks, continues, gotos and returns here
852 ScopeStatements* gotos; // forward referenced goto's go here
854 extern (D) this(const ref Loc loc, TOK op, Parameters* parameters, Expression aggr, Statement _body, Loc endloc) @safe
856 super(loc, STMT.Foreach);
857 this.op = op;
858 this.parameters = parameters;
859 this.aggr = aggr;
860 this._body = _body;
861 this.endloc = endloc;
864 override ForeachStatement syntaxCopy()
866 return new ForeachStatement(loc, op,
867 Parameter.arraySyntaxCopy(parameters),
868 aggr.syntaxCopy(),
869 _body ? _body.syntaxCopy() : null,
870 endloc);
873 override bool hasBreak() const pure nothrow
875 return true;
878 override bool hasContinue() const pure nothrow
880 return true;
883 override void accept(Visitor v)
885 v.visit(this);
889 /***********************************************************
890 * https://dlang.org/spec/statement.html#foreach-range-statement
892 extern (C++) final class ForeachRangeStatement : Statement
894 TOK op; // TOK.foreach_ or TOK.foreach_reverse_
895 Parameter prm; // loop index variable
896 Expression lwr;
897 Expression upr;
898 Statement _body;
899 Loc endloc; // location of closing curly bracket
901 VarDeclaration key;
903 extern (D) this(const ref Loc loc, TOK op, Parameter prm, Expression lwr, Expression upr, Statement _body, Loc endloc) @safe
905 super(loc, STMT.ForeachRange);
906 this.op = op;
907 this.prm = prm;
908 this.lwr = lwr;
909 this.upr = upr;
910 this._body = _body;
911 this.endloc = endloc;
914 override ForeachRangeStatement syntaxCopy()
916 return new ForeachRangeStatement(loc, op, prm.syntaxCopy(), lwr.syntaxCopy(), upr.syntaxCopy(), _body ? _body.syntaxCopy() : null, endloc);
919 override bool hasBreak() const pure nothrow
921 return true;
924 override bool hasContinue() const pure nothrow
926 return true;
929 override void accept(Visitor v)
931 v.visit(this);
935 /***********************************************************
936 * https://dlang.org/spec/statement.html#if-statement
938 extern (C++) final class IfStatement : Statement
940 Parameter prm;
941 Expression condition;
942 Statement ifbody;
943 Statement elsebody;
944 VarDeclaration match; // for MatchExpression results
945 Loc endloc; // location of closing curly bracket
947 extern (D) this(const ref Loc loc, Parameter prm, Expression condition, Statement ifbody, Statement elsebody, Loc endloc) @safe
949 super(loc, STMT.If);
950 this.prm = prm;
951 this.condition = condition;
952 this.ifbody = ifbody;
953 this.elsebody = elsebody;
954 this.endloc = endloc;
957 override IfStatement syntaxCopy()
959 return new IfStatement(loc,
960 prm ? prm.syntaxCopy() : null,
961 condition.syntaxCopy(),
962 ifbody ? ifbody.syntaxCopy() : null,
963 elsebody ? elsebody.syntaxCopy() : null,
964 endloc);
967 override void accept(Visitor v)
969 v.visit(this);
972 /******
973 * Returns: true if `if (__ctfe)`
975 bool isIfCtfeBlock()
977 if (auto cv = condition.isVarExp())
978 return cv.var.ident == Id.ctfe;
979 return false;
983 /***********************************************************
984 * https://dlang.org/spec/version.html#ConditionalStatement
986 extern (C++) final class ConditionalStatement : Statement
988 Condition condition;
989 Statement ifbody;
990 Statement elsebody;
992 extern (D) this(const ref Loc loc, Condition condition, Statement ifbody, Statement elsebody) @safe
994 super(loc, STMT.Conditional);
995 this.condition = condition;
996 this.ifbody = ifbody;
997 this.elsebody = elsebody;
1000 override ConditionalStatement syntaxCopy()
1002 return new ConditionalStatement(loc, condition.syntaxCopy(), ifbody.syntaxCopy(), elsebody ? elsebody.syntaxCopy() : null);
1005 override void accept(Visitor v)
1007 v.visit(this);
1012 /***********************************************************
1013 * https://dlang.org/spec/version.html#StaticForeachStatement
1014 * Static foreach statements, like:
1015 * void main()
1017 * static foreach(i; 0 .. 10)
1019 * pragma(msg, i);
1023 extern (C++) final class StaticForeachStatement : Statement
1025 StaticForeach sfe;
1027 extern (D) this(const ref Loc loc, StaticForeach sfe) @safe
1029 super(loc, STMT.StaticForeach);
1030 this.sfe = sfe;
1033 override StaticForeachStatement syntaxCopy()
1035 return new StaticForeachStatement(loc, sfe.syntaxCopy());
1038 override void accept(Visitor v)
1040 v.visit(this);
1044 /***********************************************************
1045 * https://dlang.org/spec/statement.html#pragma-statement
1047 extern (C++) final class PragmaStatement : Statement
1049 const Identifier ident;
1050 Expressions* args; // array of Expression's
1051 Statement _body;
1053 extern (D) this(const ref Loc loc, const Identifier ident, Expressions* args, Statement _body) @safe
1055 super(loc, STMT.Pragma);
1056 this.ident = ident;
1057 this.args = args;
1058 this._body = _body;
1061 override PragmaStatement syntaxCopy()
1063 return new PragmaStatement(loc, ident, Expression.arraySyntaxCopy(args), _body ? _body.syntaxCopy() : null);
1066 override void accept(Visitor v)
1068 v.visit(this);
1072 /***********************************************************
1073 * https://dlang.org/spec/version.html#StaticAssert
1075 extern (C++) final class StaticAssertStatement : Statement
1077 StaticAssert sa;
1079 extern (D) this(StaticAssert sa) @safe
1081 super(sa.loc, STMT.StaticAssert);
1082 this.sa = sa;
1085 override StaticAssertStatement syntaxCopy()
1087 return new StaticAssertStatement(sa.syntaxCopy(null));
1090 override void accept(Visitor v)
1092 v.visit(this);
1096 /***********************************************************
1097 * https://dlang.org/spec/statement.html#switch-statement
1099 extern (C++) final class SwitchStatement : Statement
1101 Parameter param;
1102 Expression condition; /// switch(condition)
1103 Statement _body; ///
1104 bool isFinal; /// https://dlang.org/spec/statement.html#final-switch-statement
1105 Loc endloc;
1107 bool hasDefault; /// true if has default statement
1108 bool hasVars; /// true if has variable case values
1109 DefaultStatement sdefault; /// default:
1110 Statement tryBody; /// set to TryCatchStatement or TryFinallyStatement if in _body portion
1111 TryFinallyStatement tf; /// set if in the 'finally' block of a TryFinallyStatement
1112 GotoCaseStatements gotoCases; /// array of unresolved GotoCaseStatement's
1113 CaseStatements* cases; /// array of CaseStatement's
1114 VarDeclaration lastVar; /// last observed variable declaration in this statement
1116 extern (D) this(const ref Loc loc, Parameter param, Expression condition, Statement _body, bool isFinal, Loc endloc)
1118 super(loc, STMT.Switch);
1119 this.param = param;
1120 this.condition = condition;
1121 this._body = _body;
1122 this.isFinal = isFinal;
1123 this.endloc = endloc;
1126 override SwitchStatement syntaxCopy()
1128 return new SwitchStatement(loc,
1129 param ? param.syntaxCopy() : null,
1130 condition.syntaxCopy(),
1131 _body.syntaxCopy(),
1132 isFinal,
1133 endloc);
1136 override bool hasBreak() const pure nothrow
1138 return true;
1141 override void accept(Visitor v)
1143 v.visit(this);
1147 /***********************************************************
1148 * https://dlang.org/spec/statement.html#CaseStatement
1150 extern (C++) final class CaseStatement : Statement
1152 Expression exp;
1153 Statement statement;
1155 int index; // which case it is (since we sort this)
1156 VarDeclaration lastVar;
1157 void* extra; // for use by Statement_toIR()
1159 extern (D) this(const ref Loc loc, Expression exp, Statement statement) @safe
1161 super(loc, STMT.Case);
1162 this.exp = exp;
1163 this.statement = statement;
1166 override CaseStatement syntaxCopy()
1168 return new CaseStatement(loc, exp.syntaxCopy(), statement.syntaxCopy());
1171 override void accept(Visitor v)
1173 v.visit(this);
1177 /***********************************************************
1178 * https://dlang.org/spec/statement.html#CaseRangeStatement
1180 extern (C++) final class CaseRangeStatement : Statement
1182 Expression first;
1183 Expression last;
1184 Statement statement;
1186 extern (D) this(const ref Loc loc, Expression first, Expression last, Statement statement) @safe
1188 super(loc, STMT.CaseRange);
1189 this.first = first;
1190 this.last = last;
1191 this.statement = statement;
1194 override CaseRangeStatement syntaxCopy()
1196 return new CaseRangeStatement(loc, first.syntaxCopy(), last.syntaxCopy(), statement.syntaxCopy());
1199 override void accept(Visitor v)
1201 v.visit(this);
1205 /***********************************************************
1206 * https://dlang.org/spec/statement.html#DefaultStatement
1208 extern (C++) final class DefaultStatement : Statement
1210 Statement statement;
1212 VarDeclaration lastVar;
1214 extern (D) this(const ref Loc loc, Statement statement) @safe
1216 super(loc, STMT.Default);
1217 this.statement = statement;
1220 override DefaultStatement syntaxCopy()
1222 return new DefaultStatement(loc, statement.syntaxCopy());
1225 override void accept(Visitor v)
1227 v.visit(this);
1231 /***********************************************************
1232 * https://dlang.org/spec/statement.html#GotoStatement
1234 extern (C++) final class GotoDefaultStatement : Statement
1236 SwitchStatement sw;
1238 extern (D) this(const ref Loc loc) @safe
1240 super(loc, STMT.GotoDefault);
1243 override GotoDefaultStatement syntaxCopy()
1245 return new GotoDefaultStatement(loc);
1248 override void accept(Visitor v)
1250 v.visit(this);
1254 /***********************************************************
1255 * https://dlang.org/spec/statement.html#GotoStatement
1257 extern (C++) final class GotoCaseStatement : Statement
1259 Expression exp; // null, or which case to goto
1261 CaseStatement cs; // case statement it resolves to
1263 extern (D) this(const ref Loc loc, Expression exp) @safe
1265 super(loc, STMT.GotoCase);
1266 this.exp = exp;
1269 override GotoCaseStatement syntaxCopy()
1271 return new GotoCaseStatement(loc, exp ? exp.syntaxCopy() : null);
1274 override void accept(Visitor v)
1276 v.visit(this);
1280 /***********************************************************
1282 extern (C++) final class SwitchErrorStatement : Statement
1284 Expression exp;
1286 extern (D) this(const ref Loc loc) @safe
1288 super(loc, STMT.SwitchError);
1291 final extern (D) this(const ref Loc loc, Expression exp) @safe
1293 super(loc, STMT.SwitchError);
1294 this.exp = exp;
1297 override void accept(Visitor v)
1299 v.visit(this);
1303 /***********************************************************
1304 * https://dlang.org/spec/statement.html#return-statement
1306 extern (C++) final class ReturnStatement : Statement
1308 Expression exp;
1309 size_t caseDim;
1311 extern (D) this(const ref Loc loc, Expression exp) @safe
1313 super(loc, STMT.Return);
1314 this.exp = exp;
1317 override ReturnStatement syntaxCopy()
1319 return new ReturnStatement(loc, exp ? exp.syntaxCopy() : null);
1322 override inout(ReturnStatement) endsWithReturnStatement() inout nothrow pure
1324 return this;
1327 override void accept(Visitor v)
1329 v.visit(this);
1333 /***********************************************************
1334 * https://dlang.org/spec/statement.html#break-statement
1336 extern (C++) final class BreakStatement : Statement
1338 Identifier ident;
1340 extern (D) this(const ref Loc loc, Identifier ident) @safe
1342 super(loc, STMT.Break);
1343 this.ident = ident;
1346 override BreakStatement syntaxCopy()
1348 return new BreakStatement(loc, ident);
1351 override void accept(Visitor v)
1353 v.visit(this);
1357 /***********************************************************
1358 * https://dlang.org/spec/statement.html#continue-statement
1360 extern (C++) final class ContinueStatement : Statement
1362 Identifier ident;
1364 extern (D) this(const ref Loc loc, Identifier ident) @safe
1366 super(loc, STMT.Continue);
1367 this.ident = ident;
1370 override ContinueStatement syntaxCopy()
1372 return new ContinueStatement(loc, ident);
1375 override void accept(Visitor v)
1377 v.visit(this);
1381 /***********************************************************
1382 * https://dlang.org/spec/statement.html#SynchronizedStatement
1384 extern (C++) final class SynchronizedStatement : Statement
1386 Expression exp;
1387 Statement _body;
1389 extern (D) this(const ref Loc loc, Expression exp, Statement _body) @safe
1391 super(loc, STMT.Synchronized);
1392 this.exp = exp;
1393 this._body = _body;
1396 override SynchronizedStatement syntaxCopy()
1398 return new SynchronizedStatement(loc, exp ? exp.syntaxCopy() : null, _body ? _body.syntaxCopy() : null);
1401 override bool hasBreak() const pure nothrow
1403 return false; //true;
1406 override bool hasContinue() const pure nothrow
1408 return false; //true;
1411 override void accept(Visitor v)
1413 v.visit(this);
1417 /***********************************************************
1418 * https://dlang.org/spec/statement.html#with-statement
1420 extern (C++) final class WithStatement : Statement
1422 Expression exp;
1423 Statement _body;
1424 VarDeclaration wthis;
1425 Loc endloc;
1427 extern (D) this(const ref Loc loc, Expression exp, Statement _body, Loc endloc) @safe
1429 super(loc, STMT.With);
1430 this.exp = exp;
1431 this._body = _body;
1432 this.endloc = endloc;
1435 override WithStatement syntaxCopy()
1437 return new WithStatement(loc, exp.syntaxCopy(), _body ? _body.syntaxCopy() : null, endloc);
1440 override void accept(Visitor v)
1442 v.visit(this);
1446 /***********************************************************
1447 * https://dlang.org/spec/statement.html#try-statement
1449 extern (C++) final class TryCatchStatement : Statement
1451 Statement _body;
1452 Catches* catches;
1454 Statement tryBody; /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
1456 extern (D) this(const ref Loc loc, Statement _body, Catches* catches) @safe
1458 super(loc, STMT.TryCatch);
1459 this._body = _body;
1460 this.catches = catches;
1463 override TryCatchStatement syntaxCopy()
1465 auto a = new Catches(catches.length);
1466 foreach (i, c; *catches)
1468 (*a)[i] = c.syntaxCopy();
1470 return new TryCatchStatement(loc, _body.syntaxCopy(), a);
1473 override bool hasBreak() const pure nothrow
1475 return false;
1478 override void accept(Visitor v)
1480 v.visit(this);
1484 /***********************************************************
1485 * https://dlang.org/spec/statement.html#Catch
1487 extern (C++) final class Catch : RootObject
1489 const Loc loc;
1490 Type type;
1491 Identifier ident;
1492 Statement handler;
1494 VarDeclaration var;
1495 bool errors; // set if semantic processing errors
1497 // was generated by the compiler, wasn't present in source code
1498 bool internalCatch;
1500 extern (D) this(const ref Loc loc, Type type, Identifier ident, Statement handler) @safe
1502 //printf("Catch(%s, loc = %s)\n", id.toChars(), loc.toChars());
1503 this.loc = loc;
1504 this.type = type;
1505 this.ident = ident;
1506 this.handler = handler;
1509 Catch syntaxCopy()
1511 auto c = new Catch(loc, type ? type.syntaxCopy() : getThrowable(), ident, (handler ? handler.syntaxCopy() : null));
1512 c.internalCatch = internalCatch;
1513 return c;
1517 /***********************************************************
1518 * https://dlang.org/spec/statement.html#try-statement
1520 extern (C++) final class TryFinallyStatement : Statement
1522 Statement _body;
1523 Statement finalbody;
1525 Statement tryBody; /// set to enclosing TryCatchStatement or TryFinallyStatement if in _body portion
1526 bool bodyFallsThru; /// true if _body falls through to finally
1528 extern (D) this(const ref Loc loc, Statement _body, Statement finalbody) @safe
1530 super(loc, STMT.TryFinally);
1531 this._body = _body;
1532 this.finalbody = finalbody;
1533 this.bodyFallsThru = true; // assume true until statementSemantic()
1536 static TryFinallyStatement create(const ref Loc loc, Statement _body, Statement finalbody) @safe
1538 return new TryFinallyStatement(loc, _body, finalbody);
1541 override TryFinallyStatement syntaxCopy()
1543 return new TryFinallyStatement(loc, _body.syntaxCopy(), finalbody.syntaxCopy());
1546 override bool hasBreak() const pure nothrow
1548 return false; //true;
1551 override bool hasContinue() const pure nothrow
1553 return false; //true;
1556 override void accept(Visitor v)
1558 v.visit(this);
1562 /***********************************************************
1563 * https://dlang.org/spec/statement.html#scope-guard-statement
1565 extern (C++) final class ScopeGuardStatement : Statement
1567 TOK tok;
1568 Statement statement;
1570 extern (D) this(const ref Loc loc, TOK tok, Statement statement) @safe
1572 super(loc, STMT.ScopeGuard);
1573 this.tok = tok;
1574 this.statement = statement;
1577 override ScopeGuardStatement syntaxCopy()
1579 return new ScopeGuardStatement(loc, tok, statement.syntaxCopy());
1582 override void accept(Visitor v)
1584 v.visit(this);
1588 /***********************************************************
1589 * https://dlang.org/spec/statement.html#throw-statement
1591 extern (C++) final class ThrowStatement : Statement
1593 Expression exp;
1595 // was generated by the compiler, wasn't present in source code
1596 bool internalThrow;
1598 extern (D) this(const ref Loc loc, Expression exp) @safe
1600 super(loc, STMT.Throw);
1601 this.exp = exp;
1604 override ThrowStatement syntaxCopy()
1606 auto s = new ThrowStatement(loc, exp.syntaxCopy());
1607 s.internalThrow = internalThrow;
1608 return s;
1611 override void accept(Visitor v)
1613 v.visit(this);
1617 /***********************************************************
1619 extern (C++) final class DebugStatement : Statement
1621 Statement statement;
1623 extern (D) this(const ref Loc loc, Statement statement) @safe
1625 super(loc, STMT.Debug);
1626 this.statement = statement;
1629 override DebugStatement syntaxCopy()
1631 return new DebugStatement(loc, statement ? statement.syntaxCopy() : null);
1634 override void accept(Visitor v)
1636 v.visit(this);
1640 /***********************************************************
1641 * https://dlang.org/spec/statement.html#goto-statement
1643 extern (C++) final class GotoStatement : Statement
1645 Identifier ident;
1646 LabelDsymbol label;
1647 Statement tryBody; /// set to TryCatchStatement or TryFinallyStatement if in _body portion
1648 TryFinallyStatement tf;
1649 ScopeGuardStatement os;
1650 VarDeclaration lastVar;
1651 bool inCtfeBlock; /// set if goto is inside an `if (__ctfe)` block
1653 extern (D) this(const ref Loc loc, Identifier ident) @safe
1655 super(loc, STMT.Goto);
1656 this.ident = ident;
1659 override GotoStatement syntaxCopy()
1661 return new GotoStatement(loc, ident);
1664 override void accept(Visitor v)
1666 v.visit(this);
1670 /***********************************************************
1671 * https://dlang.org/spec/statement.html#LabeledStatement
1673 extern (C++) final class LabelStatement : Statement
1675 Identifier ident;
1676 Statement statement;
1678 Statement tryBody; /// set to TryCatchStatement or TryFinallyStatement if in _body portion
1679 TryFinallyStatement tf;
1680 ScopeGuardStatement os;
1681 VarDeclaration lastVar;
1682 Statement gotoTarget; // interpret
1683 void* extra; // used by Statement_toIR()
1684 bool breaks; // someone did a 'break ident'
1685 bool inCtfeBlock; // inside a block dominated by `if (__ctfe)`
1687 extern (D) this(const ref Loc loc, Identifier ident, Statement statement) @safe
1689 super(loc, STMT.Label);
1690 this.ident = ident;
1691 this.statement = statement;
1694 override LabelStatement syntaxCopy()
1696 return new LabelStatement(loc, ident, statement ? statement.syntaxCopy() : null);
1699 override void accept(Visitor v)
1701 v.visit(this);
1705 /***********************************************************
1707 extern (C++) final class LabelDsymbol : Dsymbol
1709 LabelStatement statement;
1711 bool deleted; // set if rewritten to return in foreach delegate
1712 bool iasm; // set if used by inline assembler
1714 // set if label was defined multiple times, to avoid duplicate errors
1715 // can be removed if generic error message deduplication is implemented
1716 bool duplicated;
1718 extern (D) this(Identifier ident, const ref Loc loc = Loc.initial) @safe
1720 super(loc, ident);
1723 static LabelDsymbol create(Identifier ident) @safe
1725 return new LabelDsymbol(ident);
1728 // is this a LabelDsymbol()?
1729 override LabelDsymbol isLabel()
1731 return this;
1734 override void accept(Visitor v)
1736 v.visit(this);
1740 /***********************************************************
1741 * https://dlang.org/spec/statement.html#asm
1743 extern (C++) class AsmStatement : Statement
1745 Token* tokens;
1746 bool caseSensitive; // for register names
1748 extern (D) this(const ref Loc loc, Token* tokens) @safe
1750 super(loc, STMT.Asm);
1751 this.tokens = tokens;
1754 extern (D) this(const ref Loc loc, Token* tokens, STMT stmt) @safe
1756 super(loc, stmt);
1757 this.tokens = tokens;
1760 override AsmStatement syntaxCopy()
1762 return new AsmStatement(loc, tokens);
1765 override void accept(Visitor v)
1767 v.visit(this);
1771 /***********************************************************
1772 * https://dlang.org/spec/iasm.html
1774 extern (C++) final class InlineAsmStatement : AsmStatement
1776 code* asmcode;
1777 uint asmalign; // alignment of this statement
1778 uint regs; // mask of registers modified (must match regm_t in back end)
1779 bool refparam; // true if function parameter is referenced
1780 bool naked; // true if function is to be naked
1782 extern (D) this(const ref Loc loc, Token* tokens) @safe
1784 super(loc, tokens, STMT.InlineAsm);
1787 override InlineAsmStatement syntaxCopy()
1789 return new InlineAsmStatement(loc, tokens);
1792 override void accept(Visitor v)
1794 v.visit(this);
1798 /***********************************************************
1799 * https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
1800 * Assembler instructions with D expression operands.
1802 extern (C++) final class GccAsmStatement : AsmStatement
1804 StorageClass stc; // attributes of the asm {} block
1805 Expression insn; // string expression that is the template for assembler code
1806 Expressions* args; // input and output operands of the statement
1807 uint outputargs; // of the operands in 'args', the number of output operands
1808 Identifiers* names; // list of symbolic names for the operands
1809 Expressions* constraints; // list of string constants specifying constraints on operands
1810 Expressions* clobbers; // list of string constants specifying clobbers and scratch registers
1811 Identifiers* labels; // list of goto labels
1812 GotoStatements* gotos; // of the goto labels, the equivalent statements they represent
1814 extern (D) this(const ref Loc loc, Token* tokens) @safe
1816 super(loc, tokens, STMT.GccAsm);
1819 override GccAsmStatement syntaxCopy()
1821 return new GccAsmStatement(loc, tokens);
1824 override void accept(Visitor v)
1826 v.visit(this);
1830 /***********************************************************
1831 * a complete asm {} block
1833 extern (C++) final class CompoundAsmStatement : CompoundStatement
1835 StorageClass stc; // postfix attributes like nothrow/pure/@trusted
1837 extern (D) this(const ref Loc loc, Statements* statements, StorageClass stc) @safe
1839 super(loc, statements, STMT.CompoundAsm);
1840 this.stc = stc;
1843 override CompoundAsmStatement syntaxCopy()
1845 return new CompoundAsmStatement(loc, Statement.arraySyntaxCopy(statements), stc);
1848 override void accept(Visitor v)
1850 v.visit(this);
1854 /***********************************************************
1855 * https://dlang.org/spec/module.html#ImportDeclaration
1857 extern (C++) final class ImportStatement : Statement
1859 Dsymbols* imports; // Array of Import's
1861 extern (D) this(const ref Loc loc, Dsymbols* imports) @safe
1863 super(loc, STMT.Import);
1864 this.imports = imports;
1867 override ImportStatement syntaxCopy()
1869 auto m = new Dsymbols(imports.length);
1870 foreach (i, s; *imports)
1872 (*m)[i] = s.syntaxCopy(null);
1874 return new ImportStatement(loc, m);
1877 override void accept(Visitor v)
1879 v.visit(this);
1884 mixin template VisitStatement(Result)
1886 Result VisitStatement(Statement s)
1888 final switch (s.stmt)
1890 case STMT.Error: mixin(visitStmtCase("Error"));
1891 case STMT.Scope: mixin(visitStmtCase("Scope"));
1892 case STMT.Exp: mixin(visitStmtCase("Exp"));
1893 case STMT.Compound: mixin(visitStmtCase("Compound"));
1894 case STMT.Return: mixin(visitStmtCase("Return"));
1895 case STMT.If: mixin(visitStmtCase("If"));
1896 case STMT.Conditional: mixin(visitStmtCase("Conditional"));
1897 case STMT.StaticForeach: mixin(visitStmtCase("StaticForeach"));
1898 case STMT.Case: mixin(visitStmtCase("Case"));
1899 case STMT.Default: mixin(visitStmtCase("Default"));
1900 case STMT.Label: mixin(visitStmtCase("Label"));
1901 case STMT.Goto: mixin(visitStmtCase("Goto"));
1902 case STMT.GotoDefault: mixin(visitStmtCase("GotoDefault"));
1903 case STMT.GotoCase: mixin(visitStmtCase("GotoCase"));
1904 case STMT.Break: mixin(visitStmtCase("Break"));
1905 case STMT.DtorExp: mixin(visitStmtCase("DtorExp"));
1906 case STMT.Mixin: mixin(visitStmtCase("Mixin"));
1907 case STMT.Forwarding: mixin(visitStmtCase("Forwarding"));
1908 case STMT.Do: mixin(visitStmtCase("Do"));
1909 case STMT.While: mixin(visitStmtCase("While"));
1910 case STMT.For: mixin(visitStmtCase("For"));
1911 case STMT.Foreach: mixin(visitStmtCase("Foreach"));
1912 case STMT.Switch: mixin(visitStmtCase("Switch"));
1913 case STMT.Continue: mixin(visitStmtCase("Continue"));
1914 case STMT.With: mixin(visitStmtCase("With"));
1915 case STMT.TryCatch: mixin(visitStmtCase("TryCatch"));
1916 case STMT.Throw: mixin(visitStmtCase("Throw"));
1917 case STMT.Debug: mixin(visitStmtCase("Debug"));
1918 case STMT.TryFinally: mixin(visitStmtCase("TryFinally"));
1919 case STMT.ScopeGuard: mixin(visitStmtCase("ScopeGuard"));
1920 case STMT.SwitchError: mixin(visitStmtCase("SwitchError"));
1921 case STMT.UnrolledLoop: mixin(visitStmtCase("UnrolledLoop"));
1922 case STMT.ForeachRange: mixin(visitStmtCase("ForeachRange"));
1923 case STMT.CompoundDeclaration: mixin(visitStmtCase("CompoundDeclaration"));
1924 case STMT.Peel: mixin(visitStmtCase("Peel"));
1925 case STMT.CompoundAsm: mixin(visitStmtCase("CompoundAsm"));
1926 case STMT.Pragma: mixin(visitStmtCase("Pragma"));
1927 case STMT.StaticAssert: mixin(visitStmtCase("StaticAssert"));
1928 case STMT.CaseRange: mixin(visitStmtCase("CaseRange"));
1929 case STMT.Synchronized: mixin(visitStmtCase("Synchronized"));
1930 case STMT.Asm: mixin(visitStmtCase("Asm"));
1931 case STMT.InlineAsm: mixin(visitStmtCase("InlineAsm"));
1932 case STMT.GccAsm: mixin(visitStmtCase("GccAsm"));
1933 case STMT.Import: mixin(visitStmtCase("Import"));
1938 /****************************************
1939 * CTFE-only helper function for VisitInitializer.
1940 * Params:
1941 * handler = string for the name of the visit handler
1942 * Returns: boilerplate code for a case
1944 pure string visitStmtCase(string handler) @safe
1946 if (__ctfe)
1948 return
1950 enum isVoid = is(Result == void);
1951 auto sx = s.is"~handler~"Statement();
1952 static if (__traits(compiles, visit"~handler~"(sx)))
1954 static if (isVoid)
1956 visit"~handler~"(sx);
1957 return;
1959 else
1961 if (Result r = visit"~handler~"(sx))
1962 return r;
1963 return Result.init;
1966 else static if (__traits(compiles, visitDefaultCase(s)))
1968 static if (isVoid)
1970 visitDefaultCase(sx);
1971 return;
1973 else
1975 if (Result r = visitDefaultCase(s))
1976 return r;
1977 return Result.init;
1980 else
1981 static assert(0, "~handler~");
1984 assert(0);