comparison gcc/d/dmd/statement.h @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
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
20 struct OutBuffer;
21 struct Scope;
22 class Expression;
23 class LabelDsymbol;
24 class Identifier;
25 class IfStatement;
26 class ExpStatement;
27 class DefaultStatement;
28 class VarDeclaration;
29 class Condition;
30 class Module;
31 struct Token;
32 class ErrorStatement;
33 class ReturnStatement;
34 class CompoundStatement;
35 class Parameter;
36 class StaticAssert;
37 class AsmStatement;
38 class GotoStatement;
39 class ScopeStatement;
40 class TryCatchStatement;
41 class TryFinallyStatement;
42 class CaseStatement;
43 class DefaultStatement;
44 class LabelStatement;
45 class StaticForeach;
46
47 // Back end
48 struct code;
49
50 bool inferAggregate(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply);
51 bool inferApplyArgTypes(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply);
52
53 /* How a statement exits; this is returned by blockExit()
54 */
55 enum 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
69 class Statement : public RootObject
70 {
71 public:
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 */
114 class ErrorStatement : public Statement
115 {
116 public:
117 ErrorStatement();
118 Statement *syntaxCopy();
119
120 ErrorStatement *isErrorStatement() { return this; }
121 void accept(Visitor *v) { v->visit(this); }
122 };
123
124 class PeelStatement : public Statement
125 {
126 public:
127 Statement *s;
128
129 PeelStatement(Statement *s);
130 void accept(Visitor *v) { v->visit(this); }
131 };
132
133 class ExpStatement : public Statement
134 {
135 public:
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
149 class DtorExpStatement : public ExpStatement
150 {
151 public:
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
164 class CompileStatement : public Statement
165 {
166 public:
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
175 class CompoundStatement : public Statement
176 {
177 public:
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
193 class CompoundDeclarationStatement : public CompoundStatement
194 {
195 public:
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 */
204 class UnrolledLoopStatement : public Statement
205 {
206 public:
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
217 class ScopeStatement : public Statement
218 {
219 public:
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
233 class 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
249 class WhileStatement : public Statement
250 {
251 public:
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
264 class DoStatement : public Statement
265 {
266 public:
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
279 class ForStatement : public Statement
280 {
281 public:
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
303 class ForeachStatement : public Statement
304 {
305 public:
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
329 class ForeachRangeStatement : public Statement
330 {
331 public:
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
350 class IfStatement : public Statement
351 {
352 public:
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
368 class ConditionalStatement : public Statement
369 {
370 public:
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
382 class StaticForeachStatement : public Statement
383 {
384 public:
385 StaticForeach *sfe;
386
387 Statement *syntaxCopy();
388 Statements *flatten(Scope *sc);
389
390 void accept(Visitor *v) { v->visit(this); }
391 };
392
393 class PragmaStatement : public Statement
394 {
395 public:
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
406 class StaticAssertStatement : public Statement
407 {
408 public:
409 StaticAssert *sa;
410
411 StaticAssertStatement(StaticAssert *sa);
412 Statement *syntaxCopy();
413
414 void accept(Visitor *v) { v->visit(this); }
415 };
416
417 class SwitchStatement : public Statement
418 {
419 public:
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
440 class CaseStatement : public Statement
441 {
442 public:
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
458 class CaseRangeStatement : public Statement
459 {
460 public:
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
471 class DefaultStatement : public Statement
472 {
473 public:
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
484 class GotoDefaultStatement : public Statement
485 {
486 public:
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
496 class GotoCaseStatement : public Statement
497 {
498 public:
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
509 class SwitchErrorStatement : public Statement
510 {
511 public:
512 SwitchErrorStatement(Loc loc);
513
514 void accept(Visitor *v) { v->visit(this); }
515 };
516
517 class ReturnStatement : public Statement
518 {
519 public:
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
530 class BreakStatement : public Statement
531 {
532 public:
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
542 class ContinueStatement : public Statement
543 {
544 public:
545 Identifier *ident;
546
547 ContinueStatement(Loc loc, Identifier *ident);
548 Statement *syntaxCopy();
549
550 void accept(Visitor *v) { v->visit(this); }
551 };
552
553 class SynchronizedStatement : public Statement
554 {
555 public:
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
567 class WithStatement : public Statement
568 {
569 public:
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
581 class TryCatchStatement : public Statement
582 {
583 public:
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
594 class Catch : public RootObject
595 {
596 public:
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
614 class TryFinallyStatement : public Statement
615 {
616 public:
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
629 class OnScopeStatement : public Statement
630 {
631 public:
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
642 class ThrowStatement : public Statement
643 {
644 public:
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
656 class DebugStatement : public Statement
657 {
658 public:
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
667 class GotoStatement : public Statement
668 {
669 public:
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
683 class LabelStatement : public Statement
684 {
685 public:
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
705 class LabelDsymbol : public Dsymbol
706 {
707 public:
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
716 Statement* asmSemantic(AsmStatement *s, Scope *sc);
717
718 class AsmStatement : public Statement
719 {
720 public:
721 Token *tokens;
722
723 AsmStatement(Loc loc, Token *tokens);
724 Statement *syntaxCopy();
725 void accept(Visitor *v) { v->visit(this); }
726 };
727
728 class InlineAsmStatement : public AsmStatement
729 {
730 public:
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
743 class GccAsmStatement : public AsmStatement
744 {
745 public:
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
762 class CompoundAsmStatement : public CompoundStatement
763 {
764 public:
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
774 class ImportStatement : public Statement
775 {
776 public:
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 };