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 public: 236 ForwardingScopeDsymbol *sym; 237 Statement *statement; 238 239 ForwardingStatement(Loc loc, ForwardingScopeDsymbol *sym, Statement *s); 240 ForwardingStatement(Loc loc, Statement *s); 241 Statement *syntaxCopy(); 242 Statements *flatten(Scope *sc); isForwardingStatement()243 ForwardingStatement *isForwardingStatement() { return this; } accept(Visitor * v)244 void accept(Visitor *v) { v->visit(this); } 245 }; 246 247 class WhileStatement : public Statement 248 { 249 public: 250 Expression *condition; 251 Statement *_body; 252 Loc endloc; // location of closing curly bracket 253 254 WhileStatement(Loc loc, Expression *c, Statement *b, Loc endloc); 255 Statement *syntaxCopy(); 256 bool hasBreak(); 257 bool hasContinue(); 258 accept(Visitor * v)259 void accept(Visitor *v) { v->visit(this); } 260 }; 261 262 class DoStatement : public Statement 263 { 264 public: 265 Statement *_body; 266 Expression *condition; 267 Loc endloc; // location of ';' after while 268 269 DoStatement(Loc loc, Statement *b, Expression *c, Loc endloc); 270 Statement *syntaxCopy(); 271 bool hasBreak(); 272 bool hasContinue(); 273 accept(Visitor * v)274 void accept(Visitor *v) { v->visit(this); } 275 }; 276 277 class ForStatement : public Statement 278 { 279 public: 280 Statement *_init; 281 Expression *condition; 282 Expression *increment; 283 Statement *_body; 284 Loc endloc; // location of closing curly bracket 285 286 // When wrapped in try/finally clauses, this points to the outermost one, 287 // which may have an associated label. Internal break/continue statements 288 // treat that label as referring to this loop. 289 Statement *relatedLabeled; 290 291 ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body, Loc endloc); 292 Statement *syntaxCopy(); 293 Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); getRelatedLabeled()294 Statement *getRelatedLabeled() { return relatedLabeled ? relatedLabeled : this; } 295 bool hasBreak(); 296 bool hasContinue(); 297 accept(Visitor * v)298 void accept(Visitor *v) { v->visit(this); } 299 }; 300 301 class ForeachStatement : public Statement 302 { 303 public: 304 TOK op; // TOKforeach or TOKforeach_reverse 305 Parameters *parameters; // array of Parameter*'s 306 Expression *aggr; 307 Statement *_body; 308 Loc endloc; // location of closing curly bracket 309 310 VarDeclaration *key; 311 VarDeclaration *value; 312 313 FuncDeclaration *func; // function we're lexically in 314 315 Statements *cases; // put breaks, continues, gotos and returns here 316 ScopeStatements *gotos; // forward referenced goto's go here 317 318 ForeachStatement(Loc loc, TOK op, Parameters *parameters, Expression *aggr, Statement *body, Loc endloc); 319 Statement *syntaxCopy(); 320 bool checkForArgTypes(); 321 bool hasBreak(); 322 bool hasContinue(); 323 accept(Visitor * v)324 void accept(Visitor *v) { v->visit(this); } 325 }; 326 327 class ForeachRangeStatement : public Statement 328 { 329 public: 330 TOK op; // TOKforeach or TOKforeach_reverse 331 Parameter *prm; // loop index variable 332 Expression *lwr; 333 Expression *upr; 334 Statement *_body; 335 Loc endloc; // location of closing curly bracket 336 337 VarDeclaration *key; 338 339 ForeachRangeStatement(Loc loc, TOK op, Parameter *prm, 340 Expression *lwr, Expression *upr, Statement *body, Loc endloc); 341 Statement *syntaxCopy(); 342 bool hasBreak(); 343 bool hasContinue(); 344 accept(Visitor * v)345 void accept(Visitor *v) { v->visit(this); } 346 }; 347 348 class IfStatement : public Statement 349 { 350 public: 351 Parameter *prm; 352 Expression *condition; 353 Statement *ifbody; 354 Statement *elsebody; 355 Loc endloc; // location of closing curly bracket 356 357 VarDeclaration *match; // for MatchExpression results 358 359 IfStatement(Loc loc, Parameter *prm, Expression *condition, Statement *ifbody, Statement *elsebody, Loc endloc); 360 Statement *syntaxCopy(); isIfStatement()361 IfStatement *isIfStatement() { return this; } 362 accept(Visitor * v)363 void accept(Visitor *v) { v->visit(this); } 364 }; 365 366 class ConditionalStatement : public Statement 367 { 368 public: 369 Condition *condition; 370 Statement *ifbody; 371 Statement *elsebody; 372 373 ConditionalStatement(Loc loc, Condition *condition, Statement *ifbody, Statement *elsebody); 374 Statement *syntaxCopy(); 375 Statements *flatten(Scope *sc); 376 accept(Visitor * v)377 void accept(Visitor *v) { v->visit(this); } 378 }; 379 380 class StaticForeachStatement : public Statement 381 { 382 public: 383 StaticForeach *sfe; 384 385 StaticForeachStatement(Loc loc, StaticForeach *sfe); 386 Statement *syntaxCopy(); 387 Statements *flatten(Scope *sc); 388 accept(Visitor * v)389 void accept(Visitor *v) { v->visit(this); } 390 }; 391 392 class PragmaStatement : public Statement 393 { 394 public: 395 Identifier *ident; 396 Expressions *args; // array of Expression's 397 Statement *_body; 398 399 PragmaStatement(Loc loc, Identifier *ident, Expressions *args, Statement *body); 400 Statement *syntaxCopy(); 401 accept(Visitor * v)402 void accept(Visitor *v) { v->visit(this); } 403 }; 404 405 class StaticAssertStatement : public Statement 406 { 407 public: 408 StaticAssert *sa; 409 410 StaticAssertStatement(StaticAssert *sa); 411 Statement *syntaxCopy(); 412 accept(Visitor * v)413 void accept(Visitor *v) { v->visit(this); } 414 }; 415 416 class SwitchStatement : public Statement 417 { 418 public: 419 Expression *condition; 420 Statement *_body; 421 bool isFinal; 422 423 DefaultStatement *sdefault; 424 TryFinallyStatement *tf; 425 GotoCaseStatements gotoCases; // array of unresolved GotoCaseStatement's 426 CaseStatements *cases; // array of CaseStatement's 427 int hasNoDefault; // !=0 if no default statement 428 int hasVars; // !=0 if has variable case values 429 VarDeclaration *lastVar; 430 431 SwitchStatement(Loc loc, Expression *c, Statement *b, bool isFinal); 432 Statement *syntaxCopy(); 433 bool hasBreak(); 434 bool checkLabel(); 435 accept(Visitor * v)436 void accept(Visitor *v) { v->visit(this); } 437 }; 438 439 class CaseStatement : public Statement 440 { 441 public: 442 Expression *exp; 443 Statement *statement; 444 445 int index; // which case it is (since we sort this) 446 VarDeclaration *lastVar; 447 448 CaseStatement(Loc loc, Expression *exp, Statement *s); 449 Statement *syntaxCopy(); 450 int compare(RootObject *obj); isCaseStatement()451 CaseStatement *isCaseStatement() { return this; } 452 accept(Visitor * v)453 void accept(Visitor *v) { v->visit(this); } 454 }; 455 456 457 class CaseRangeStatement : public Statement 458 { 459 public: 460 Expression *first; 461 Expression *last; 462 Statement *statement; 463 464 CaseRangeStatement(Loc loc, Expression *first, Expression *last, Statement *s); 465 Statement *syntaxCopy(); accept(Visitor * v)466 void accept(Visitor *v) { v->visit(this); } 467 }; 468 469 470 class DefaultStatement : public Statement 471 { 472 public: 473 Statement *statement; 474 VarDeclaration *lastVar; 475 476 DefaultStatement(Loc loc, Statement *s); 477 Statement *syntaxCopy(); isDefaultStatement()478 DefaultStatement *isDefaultStatement() { return this; } 479 accept(Visitor * v)480 void accept(Visitor *v) { v->visit(this); } 481 }; 482 483 class GotoDefaultStatement : public Statement 484 { 485 public: 486 SwitchStatement *sw; 487 488 GotoDefaultStatement(Loc loc); 489 Statement *syntaxCopy(); isGotoDefaultStatement()490 GotoDefaultStatement *isGotoDefaultStatement() { return this; } 491 accept(Visitor * v)492 void accept(Visitor *v) { v->visit(this); } 493 }; 494 495 class GotoCaseStatement : public Statement 496 { 497 public: 498 Expression *exp; // NULL, or which case to goto 499 CaseStatement *cs; // case statement it resolves to 500 501 GotoCaseStatement(Loc loc, Expression *exp); 502 Statement *syntaxCopy(); isGotoCaseStatement()503 GotoCaseStatement *isGotoCaseStatement() { return this; } 504 accept(Visitor * v)505 void accept(Visitor *v) { v->visit(this); } 506 }; 507 508 class SwitchErrorStatement : public Statement 509 { 510 public: 511 SwitchErrorStatement(Loc loc); 512 accept(Visitor * v)513 void accept(Visitor *v) { v->visit(this); } 514 }; 515 516 class ReturnStatement : public Statement 517 { 518 public: 519 Expression *exp; 520 size_t caseDim; 521 522 ReturnStatement(Loc loc, Expression *exp); 523 Statement *syntaxCopy(); 524 isReturnStatement()525 ReturnStatement *isReturnStatement() { return this; } accept(Visitor * v)526 void accept(Visitor *v) { v->visit(this); } 527 }; 528 529 class BreakStatement : public Statement 530 { 531 public: 532 Identifier *ident; 533 534 BreakStatement(Loc loc, Identifier *ident); 535 Statement *syntaxCopy(); 536 isBreakStatement()537 BreakStatement *isBreakStatement() { return this; } accept(Visitor * v)538 void accept(Visitor *v) { v->visit(this); } 539 }; 540 541 class ContinueStatement : public Statement 542 { 543 public: 544 Identifier *ident; 545 546 ContinueStatement(Loc loc, Identifier *ident); 547 Statement *syntaxCopy(); 548 accept(Visitor * v)549 void accept(Visitor *v) { v->visit(this); } 550 }; 551 552 class SynchronizedStatement : public Statement 553 { 554 public: 555 Expression *exp; 556 Statement *_body; 557 558 SynchronizedStatement(Loc loc, Expression *exp, Statement *body); 559 Statement *syntaxCopy(); 560 bool hasBreak(); 561 bool hasContinue(); 562 accept(Visitor * v)563 void accept(Visitor *v) { v->visit(this); } 564 }; 565 566 class WithStatement : public Statement 567 { 568 public: 569 Expression *exp; 570 Statement *_body; 571 VarDeclaration *wthis; 572 Loc endloc; 573 574 WithStatement(Loc loc, Expression *exp, Statement *body, Loc endloc); 575 Statement *syntaxCopy(); 576 accept(Visitor * v)577 void accept(Visitor *v) { v->visit(this); } 578 }; 579 580 class TryCatchStatement : public Statement 581 { 582 public: 583 Statement *_body; 584 Catches *catches; 585 586 TryCatchStatement(Loc loc, Statement *body, Catches *catches); 587 Statement *syntaxCopy(); 588 bool hasBreak(); 589 accept(Visitor * v)590 void accept(Visitor *v) { v->visit(this); } 591 }; 592 593 class Catch : public RootObject 594 { 595 public: 596 Loc loc; 597 Type *type; 598 Identifier *ident; 599 VarDeclaration *var; 600 Statement *handler; 601 602 // set if semantic processing errors 603 bool errors; 604 605 // was generated by the compiler, 606 // wasn't present in source code 607 bool internalCatch; 608 609 Catch(Loc loc, Type *t, Identifier *id, Statement *handler); 610 Catch *syntaxCopy(); 611 }; 612 613 class TryFinallyStatement : public Statement 614 { 615 public: 616 Statement *_body; 617 Statement *finalbody; 618 619 TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody); 620 static TryFinallyStatement *create(Loc loc, Statement *body, Statement *finalbody); 621 Statement *syntaxCopy(); 622 bool hasBreak(); 623 bool hasContinue(); 624 accept(Visitor * v)625 void accept(Visitor *v) { v->visit(this); } 626 }; 627 628 class OnScopeStatement : public Statement 629 { 630 public: 631 TOK tok; 632 Statement *statement; 633 634 OnScopeStatement(Loc loc, TOK tok, Statement *statement); 635 Statement *syntaxCopy(); 636 Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); 637 accept(Visitor * v)638 void accept(Visitor *v) { v->visit(this); } 639 }; 640 641 class ThrowStatement : public Statement 642 { 643 public: 644 Expression *exp; 645 // was generated by the compiler, 646 // wasn't present in source code 647 bool internalThrow; 648 649 ThrowStatement(Loc loc, Expression *exp); 650 Statement *syntaxCopy(); 651 accept(Visitor * v)652 void accept(Visitor *v) { v->visit(this); } 653 }; 654 655 class DebugStatement : public Statement 656 { 657 public: 658 Statement *statement; 659 660 DebugStatement(Loc loc, Statement *statement); 661 Statement *syntaxCopy(); 662 Statements *flatten(Scope *sc); accept(Visitor * v)663 void accept(Visitor *v) { v->visit(this); } 664 }; 665 666 class GotoStatement : public Statement 667 { 668 public: 669 Identifier *ident; 670 LabelDsymbol *label; 671 TryFinallyStatement *tf; 672 OnScopeStatement *os; 673 VarDeclaration *lastVar; 674 675 GotoStatement(Loc loc, Identifier *ident); 676 Statement *syntaxCopy(); 677 bool checkLabel(); 678 accept(Visitor * v)679 void accept(Visitor *v) { v->visit(this); } 680 }; 681 682 class LabelStatement : public Statement 683 { 684 public: 685 Identifier *ident; 686 Statement *statement; 687 TryFinallyStatement *tf; 688 OnScopeStatement *os; 689 VarDeclaration *lastVar; 690 Statement *gotoTarget; // interpret 691 692 bool breaks; // someone did a 'break ident' 693 694 LabelStatement(Loc loc, Identifier *ident, Statement *statement); 695 Statement *syntaxCopy(); 696 Statements *flatten(Scope *sc); 697 Statement *scopeCode(Scope *sc, Statement **sentry, Statement **sexit, Statement **sfinally); 698 isLabelStatement()699 LabelStatement *isLabelStatement() { return this; } 700 accept(Visitor * v)701 void accept(Visitor *v) { v->visit(this); } 702 }; 703 704 class LabelDsymbol : public Dsymbol 705 { 706 public: 707 LabelStatement *statement; 708 709 LabelDsymbol(Identifier *ident); 710 static LabelDsymbol *create(Identifier *ident); 711 LabelDsymbol *isLabel(); accept(Visitor * v)712 void accept(Visitor *v) { v->visit(this); } 713 }; 714 715 Statement* asmSemantic(AsmStatement *s, Scope *sc); 716 717 class AsmStatement : public Statement 718 { 719 public: 720 Token *tokens; 721 722 AsmStatement(Loc loc, Token *tokens); 723 Statement *syntaxCopy(); accept(Visitor * v)724 void accept(Visitor *v) { v->visit(this); } 725 }; 726 727 class InlineAsmStatement : public AsmStatement 728 { 729 public: 730 code *asmcode; 731 unsigned asmalign; // alignment of this statement 732 unsigned regs; // mask of registers modified (must match regm_t in back end) 733 bool refparam; // true if function parameter is referenced 734 bool naked; // true if function is to be naked 735 736 InlineAsmStatement(Loc loc, Token *tokens); 737 Statement *syntaxCopy(); accept(Visitor * v)738 void accept(Visitor *v) { v->visit(this); } 739 }; 740 741 // A GCC asm statement - assembler instructions with D expression operands 742 class GccAsmStatement : public AsmStatement 743 { 744 public: 745 StorageClass stc; // attributes of the asm {} block 746 Expression *insn; // string expression that is the template for assembler code 747 Expressions *args; // input and output operands of the statement 748 unsigned outputargs; // of the operands in 'args', the number of output operands 749 Identifiers *names; // list of symbolic names for the operands 750 Expressions *constraints; // list of string constants specifying constraints on operands 751 Expressions *clobbers; // list of string constants specifying clobbers and scratch registers 752 Identifiers *labels; // list of goto labels 753 GotoStatements *gotos; // of the goto labels, the equivalent statements they represent 754 755 GccAsmStatement(Loc loc, Token *tokens); 756 Statement *syntaxCopy(); accept(Visitor * v)757 void accept(Visitor *v) { v->visit(this); } 758 }; 759 760 // a complete asm {} block 761 class CompoundAsmStatement : public CompoundStatement 762 { 763 public: 764 StorageClass stc; // postfix attributes like nothrow/pure/@trusted 765 766 CompoundAsmStatement(Loc loc, Statements *s, StorageClass stc); 767 CompoundAsmStatement *syntaxCopy(); 768 Statements *flatten(Scope *sc); 769 accept(Visitor * v)770 void accept(Visitor *v) { v->visit(this); } 771 }; 772 773 class ImportStatement : public Statement 774 { 775 public: 776 Dsymbols *imports; // Array of Import's 777 778 ImportStatement(Loc loc, Dsymbols *imports); 779 Statement *syntaxCopy(); 780 accept(Visitor * v)781 void accept(Visitor *v) { v->visit(this); } 782 }; 783