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