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, ...); getRelatedLabeled()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 isErrorStatement()94 virtual ErrorStatement *isErrorStatement() { return NULL; } isScopeStatement()95 virtual ScopeStatement *isScopeStatement() { return NULL; } isExpStatement()96 virtual ExpStatement *isExpStatement() { return NULL; } isCompoundStatement()97 virtual CompoundStatement *isCompoundStatement() { return NULL; } isReturnStatement()98 virtual ReturnStatement *isReturnStatement() { return NULL; } isIfStatement()99 virtual IfStatement *isIfStatement() { return NULL; } isCaseStatement()100 virtual CaseStatement *isCaseStatement() { return NULL; } isDefaultStatement()101 virtual DefaultStatement *isDefaultStatement() { return NULL; } isLabelStatement()102 virtual LabelStatement *isLabelStatement() { return NULL; } isGotoDefaultStatement()103 virtual GotoDefaultStatement *isGotoDefaultStatement() { return NULL; } isGotoCaseStatement()104 virtual GotoCaseStatement *isGotoCaseStatement() { return NULL; } isBreakStatement()105 virtual BreakStatement *isBreakStatement() { return NULL; } isDtorExpStatement()106 virtual DtorExpStatement *isDtorExpStatement() { return NULL; } isForwardingStatement()107 virtual ForwardingStatement *isForwardingStatement() { return NULL; } accept(Visitor * v)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 isErrorStatement()120 ErrorStatement *isErrorStatement() { return this; } accept(Visitor * v)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); accept(Visitor * v)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 isExpStatement()145 ExpStatement *isExpStatement() { return this; } accept(Visitor * v)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(); accept(Visitor * v)159 void accept(Visitor *v) { v->visit(this); } 160 isDtorExpStatement()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); accept(Visitor * v)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 isCompoundStatement()189 CompoundStatement *isCompoundStatement() { return this; } accept(Visitor * v)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(); accept(Visitor * v)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 accept(Visitor * v)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(); isScopeStatement()225 ScopeStatement *isScopeStatement() { return this; } 226 ReturnStatement *isReturnStatement(); 227 bool hasBreak(); 228 bool hasContinue(); 229 accept(Visitor * v)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); isForwardingStatement()245 ForwardingStatement *isForwardingStatement() { return this; } accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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); getRelatedLabeled()296 Statement *getRelatedLabeled() { return relatedLabeled ? relatedLabeled : this; } 297 bool hasBreak(); 298 bool hasContinue(); 299 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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(); isIfStatement()363 IfStatement *isIfStatement() { return this; } 364 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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); isCaseStatement()452 CaseStatement *isCaseStatement() { return this; } 453 accept(Visitor * v)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(); accept(Visitor * v)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(); isDefaultStatement()479 DefaultStatement *isDefaultStatement() { return this; } 480 accept(Visitor * v)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(); isGotoDefaultStatement()491 GotoDefaultStatement *isGotoDefaultStatement() { return this; } 492 accept(Visitor * v)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(); isGotoCaseStatement()504 GotoCaseStatement *isGotoCaseStatement() { return this; } 505 accept(Visitor * v)506 void accept(Visitor *v) { v->visit(this); } 507 }; 508 509 class SwitchErrorStatement : public Statement 510 { 511 public: 512 SwitchErrorStatement(Loc loc); 513 accept(Visitor * v)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 isReturnStatement()526 ReturnStatement *isReturnStatement() { return this; } accept(Visitor * v)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 isBreakStatement()538 BreakStatement *isBreakStatement() { return this; } accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)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); accept(Visitor * v)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 accept(Visitor * v)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 isLabelStatement()700 LabelStatement *isLabelStatement() { return this; } 701 accept(Visitor * v)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(); accept(Visitor * v)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(); accept(Visitor * v)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(); accept(Visitor * v)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(); accept(Visitor * v)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 accept(Visitor * v)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 accept(Visitor * v)782 void accept(Visitor *v) { v->visit(this); } 783 }; 784