1 /** 2 * Documentation: https://dlang.org/phobos/dmd_transitivevisitor.html 3 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/transitivevisitor.d 4 */ 5 6 module dmd.transitivevisitor; 7 8 import dmd.permissivevisitor; 9 import dmd.tokens; 10 import dmd.root.rootobject; 11 12 import core.stdc.stdio; 13 14 /** Visitor that implements the AST traversal logic. The nodes just accept their children. 15 */ 16 extern(C++) class ParseTimeTransitiveVisitor(AST) : PermissiveVisitor!AST 17 { 18 alias visit = PermissiveVisitor!AST.visit; 19 mixin ParseVisitMethods!AST; 20 } 21 22 /* This mixin implements the AST traversal logic for parse time AST nodes. The same code 23 * is used for semantic time AST node traversal, so in order to not duplicate the code, 24 * the template mixin is used. 25 */ 26 package mixin template ParseVisitMethods(AST) 27 { 28 29 // Statement Nodes 30 //=========================================================== 31 override void visit(AST.ExpStatement s) 32 { 33 //printf("Visiting ExpStatement\n"); 34 if (s.exp && s.exp.op == TOK.declaration) 35 { 36 (cast(AST.DeclarationExp)s.exp).declaration.accept(this); 37 return; 38 } 39 if (s.exp) 40 s.exp.accept(this); 41 } 42 43 override void visit(AST.CompileStatement s) 44 { 45 //printf("Visiting CompileStatement\n"); 46 visitArgs(s.exps); 47 } 48 49 override void visit(AST.CompoundStatement s) 50 { 51 //printf("Visiting CompoundStatement\n"); 52 foreach (sx; *s.statements) 53 { 54 if (sx) 55 sx.accept(this); 56 } 57 } 58 59 void visitVarDecl(AST.VarDeclaration v) 60 { 61 //printf("Visiting VarDeclaration\n"); 62 if (v.type) 63 visitType(v.type); 64 if (v._init) 65 { 66 auto ie = v._init.isExpInitializer(); 67 if (ie && (ie.exp.op == TOK.construct || ie.exp.op == TOK.blit)) 68 (cast(AST.AssignExp)ie.exp).e2.accept(this); 69 else 70 v._init.accept(this); 71 } 72 } 73 74 override void visit(AST.CompoundDeclarationStatement s) 75 { 76 //printf("Visiting CompoundDeclarationStatement\n"); 77 foreach (sx; *s.statements) 78 { 79 auto ds = sx ? sx.isExpStatement() : null; 80 if (ds && ds.exp.op == TOK.declaration) 81 { 82 auto d = (cast(AST.DeclarationExp)ds.exp).declaration; 83 assert(d.isDeclaration()); 84 if (auto v = d.isVarDeclaration()) 85 visitVarDecl(v); 86 else 87 d.accept(this); 88 } 89 } 90 } 91 92 override void visit(AST.ScopeStatement s) 93 { 94 //printf("Visiting ScopeStatement\n"); 95 if (s.statement) 96 s.statement.accept(this); 97 } 98 99 override void visit(AST.WhileStatement s) 100 { 101 //printf("Visiting WhileStatement\n"); 102 s.condition.accept(this); 103 if (s._body) 104 s._body.accept(this); 105 } 106 107 override void visit(AST.DoStatement s) 108 { 109 //printf("Visiting DoStatement\n"); 110 if (s._body) 111 s._body.accept(this); 112 s.condition.accept(this); 113 } 114 115 override void visit(AST.ForStatement s) 116 { 117 //printf("Visiting ForStatement\n"); 118 if (s._init) 119 s._init.accept(this); 120 if (s.condition) 121 s.condition.accept(this); 122 if (s.increment) 123 s.increment.accept(this); 124 if (s._body) 125 s._body.accept(this); 126 } 127 128 override void visit(AST.ForeachStatement s) 129 { 130 //printf("Visiting ForeachStatement\n"); 131 foreach (p; *s.parameters) 132 if (p.type) 133 visitType(p.type); 134 s.aggr.accept(this); 135 if (s._body) 136 s._body.accept(this); 137 } 138 139 override void visit(AST.ForeachRangeStatement s) 140 { 141 //printf("Visiting ForeachRangeStatement\n"); 142 if (s.prm.type) 143 visitType(s.prm.type); 144 s.lwr.accept(this); 145 s.upr.accept(this); 146 if (s._body) 147 s._body.accept(this); 148 } 149 150 override void visit(AST.IfStatement s) 151 { 152 //printf("Visiting IfStatement\n"); 153 if (s.prm && s.prm.type) 154 visitType(s.prm.type); 155 s.condition.accept(this); 156 s.ifbody.accept(this); 157 if (s.elsebody) 158 s.elsebody.accept(this); 159 } 160 161 override void visit(AST.ConditionalStatement s) 162 { 163 //printf("Visiting ConditionalStatement\n"); 164 s.condition.accept(this); 165 if (s.ifbody) 166 s.ifbody.accept(this); 167 if (s.elsebody) 168 s.elsebody.accept(this); 169 } 170 171 void visitArgs(AST.Expressions* expressions, AST.Expression basis = null) 172 { 173 if (!expressions || !expressions.dim) 174 return; 175 foreach (el; *expressions) 176 { 177 if (!el) 178 el = basis; 179 if (el) 180 el.accept(this); 181 } 182 } 183 184 override void visit(AST.PragmaStatement s) 185 { 186 //printf("Visiting PragmaStatement\n"); 187 if (s.args && s.args.dim) 188 visitArgs(s.args); 189 if (s._body) 190 s._body.accept(this); 191 } 192 193 override void visit(AST.StaticAssertStatement s) 194 { 195 //printf("Visiting StaticAssertStatement\n"); 196 s.sa.accept(this); 197 } 198 199 override void visit(AST.SwitchStatement s) 200 { 201 //printf("Visiting SwitchStatement\n"); 202 s.condition.accept(this); 203 if (s._body) 204 s._body.accept(this); 205 } 206 207 override void visit(AST.CaseStatement s) 208 { 209 //printf("Visiting CaseStatement\n"); 210 s.exp.accept(this); 211 s.statement.accept(this); 212 } 213 214 override void visit(AST.CaseRangeStatement s) 215 { 216 //printf("Visiting CaseRangeStatement\n"); 217 s.first.accept(this); 218 s.last.accept(this); 219 s.statement.accept(this); 220 } 221 222 override void visit(AST.DefaultStatement s) 223 { 224 //printf("Visiting DefaultStatement\n"); 225 s.statement.accept(this); 226 } 227 228 override void visit(AST.GotoCaseStatement s) 229 { 230 //printf("Visiting GotoCaseStatement\n"); 231 if (s.exp) 232 s.exp.accept(this); 233 } 234 235 override void visit(AST.ReturnStatement s) 236 { 237 //printf("Visiting ReturnStatement\n"); 238 if (s.exp) 239 s.exp.accept(this); 240 } 241 242 override void visit(AST.SynchronizedStatement s) 243 { 244 //printf("Visiting SynchronizedStatement\n"); 245 if (s.exp) 246 s.exp.accept(this); 247 if (s._body) 248 s._body.accept(this); 249 } 250 251 override void visit(AST.WithStatement s) 252 { 253 //printf("Visiting WithStatement\n"); 254 s.exp.accept(this); 255 if (s._body) 256 s._body.accept(this); 257 } 258 259 override void visit(AST.TryCatchStatement s) 260 { 261 //printf("Visiting TryCatchStatement\n"); 262 if (s._body) 263 s._body.accept(this); 264 foreach (c; *s.catches) 265 visit(c); 266 } 267 268 override void visit(AST.TryFinallyStatement s) 269 { 270 //printf("Visiting TryFinallyStatement\n"); 271 s._body.accept(this); 272 s.finalbody.accept(this); 273 } 274 275 override void visit(AST.ScopeGuardStatement s) 276 { 277 //printf("Visiting ScopeGuardStatement\n"); 278 s.statement.accept(this); 279 } 280 281 override void visit(AST.ThrowStatement s) 282 { 283 //printf("Visiting ThrowStatement\n"); 284 s.exp.accept(this); 285 } 286 287 override void visit(AST.LabelStatement s) 288 { 289 //printf("Visiting LabelStatement\n"); 290 if (s.statement) 291 s.statement.accept(this); 292 } 293 294 override void visit(AST.ImportStatement s) 295 { 296 //printf("Visiting ImportStatement\n"); 297 foreach (imp; *s.imports) 298 imp.accept(this); 299 } 300 301 void visit(AST.Catch c) 302 { 303 //printf("Visiting Catch\n"); 304 if (c.type) 305 visitType(c.type); 306 if (c.handler) 307 c.handler.accept(this); 308 } 309 310 // Type Nodes 311 //============================================================ 312 313 void visitType(AST.Type t) 314 { 315 //printf("Visiting Type\n"); 316 if (!t) 317 return; 318 if (t.ty == AST.Tfunction) 319 { 320 visitFunctionType(cast(AST.TypeFunction)t, null); 321 return; 322 } 323 else 324 t.accept(this); 325 } 326 327 void visitFunctionType(AST.TypeFunction t, AST.TemplateDeclaration td) 328 { 329 if (t.next) 330 visitType(t.next); 331 if (td) 332 { 333 foreach (p; *td.origParameters) 334 p.accept(this); 335 } 336 visitParameters(t.parameterList.parameters); 337 } 338 339 void visitParameters(AST.Parameters* parameters) 340 { 341 if (parameters) 342 { 343 size_t dim = AST.Parameter.dim(parameters); 344 foreach(i; 0..dim) 345 { 346 AST.Parameter fparam = AST.Parameter.getNth(parameters, i); 347 fparam.accept(this); 348 } 349 } 350 } 351 352 override void visit(AST.TypeVector t) 353 { 354 //printf("Visiting TypeVector\n"); 355 if (!t.basetype) 356 return; 357 t.basetype.accept(this); 358 } 359 360 override void visit(AST.TypeSArray t) 361 { 362 //printf("Visiting TypeSArray\n"); 363 t.next.accept(this); 364 } 365 366 override void visit(AST.TypeDArray t) 367 { 368 //printf("Visiting TypeDArray\n"); 369 t.next.accept(this); 370 } 371 372 override void visit(AST.TypeAArray t) 373 { 374 //printf("Visiting TypeAArray\n"); 375 t.next.accept(this); 376 t.index.accept(this); 377 } 378 379 override void visit(AST.TypePointer t) 380 { 381 //printf("Visiting TypePointer\n"); 382 if (t.next.ty == AST.Tfunction) 383 { 384 visitFunctionType(cast(AST.TypeFunction)t.next, null); 385 } 386 else 387 t.next.accept(this); 388 } 389 390 override void visit(AST.TypeReference t) 391 { 392 //printf("Visiting TypeReference\n"); 393 t.next.accept(this); 394 } 395 396 override void visit(AST.TypeFunction t) 397 { 398 //printf("Visiting TypeFunction\n"); 399 visitFunctionType(t, null); 400 } 401 402 override void visit(AST.TypeDelegate t) 403 { 404 //printf("Visiting TypeDelegate\n"); 405 visitFunctionType(cast(AST.TypeFunction)t.next, null); 406 } 407 408 void visitTypeQualified(AST.TypeQualified t) 409 { 410 //printf("Visiting TypeQualified\n"); 411 foreach (id; t.idents) 412 { 413 if (id.dyncast() == DYNCAST.dsymbol) 414 (cast(AST.TemplateInstance)id).accept(this); 415 else if (id.dyncast() == DYNCAST.expression) 416 (cast(AST.Expression)id).accept(this); 417 else if (id.dyncast() == DYNCAST.type) 418 (cast(AST.Type)id).accept(this); 419 } 420 } 421 422 override void visit(AST.TypeIdentifier t) 423 { 424 //printf("Visiting TypeIdentifier\n"); 425 visitTypeQualified(t); 426 } 427 428 override void visit(AST.TypeInstance t) 429 { 430 //printf("Visiting TypeInstance\n"); 431 t.tempinst.accept(this); 432 visitTypeQualified(t); 433 } 434 435 override void visit(AST.TypeTypeof t) 436 { 437 //printf("Visiting TypeTypeof\n"); 438 t.exp.accept(this); 439 visitTypeQualified(t); 440 } 441 442 override void visit(AST.TypeReturn t) 443 { 444 //printf("Visiting TypeReturn\n"); 445 visitTypeQualified(t); 446 } 447 448 override void visit(AST.TypeTuple t) 449 { 450 //printf("Visiting TypeTuple\n"); 451 visitParameters(t.arguments); 452 } 453 454 override void visit(AST.TypeSlice t) 455 { 456 //printf("Visiting TypeSlice\n"); 457 t.next.accept(this); 458 t.lwr.accept(this); 459 t.upr.accept(this); 460 } 461 462 override void visit(AST.TypeTraits t) 463 { 464 t.exp.accept(this); 465 } 466 467 override void visit(AST.TypeMixin t) 468 { 469 visitArgs(t.exps); 470 } 471 472 // Miscellaneous 473 //======================================================== 474 475 override void visit(AST.StaticAssert s) 476 { 477 //printf("Visiting StaticAssert\n"); 478 s.exp.accept(this); 479 if (s.msg) 480 s.msg.accept(this); 481 } 482 483 override void visit(AST.EnumMember em) 484 { 485 //printf("Visiting EnumMember\n"); 486 if (em.type) 487 visitType(em.type); 488 if (em.value) 489 em.value.accept(this); 490 } 491 492 // Declarations 493 //========================================================= 494 void visitAttribDeclaration(AST.AttribDeclaration d) 495 { 496 if (d.decl) 497 foreach (de; *d.decl) 498 de.accept(this); 499 } 500 501 override void visit(AST.AttribDeclaration d) 502 { 503 //printf("Visiting AttribDeclaration\n"); 504 visitAttribDeclaration(d); 505 } 506 507 override void visit(AST.StorageClassDeclaration d) 508 { 509 //printf("Visiting StorageClassDeclaration\n"); 510 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 511 } 512 513 override void visit(AST.DeprecatedDeclaration d) 514 { 515 //printf("Visiting DeprecatedDeclaration\n"); 516 d.msg.accept(this); 517 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 518 } 519 520 override void visit(AST.LinkDeclaration d) 521 { 522 //printf("Visiting LinkDeclaration\n"); 523 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 524 } 525 526 override void visit(AST.CPPMangleDeclaration d) 527 { 528 //printf("Visiting CPPMangleDeclaration\n"); 529 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 530 } 531 532 override void visit(AST.VisibilityDeclaration d) 533 { 534 //printf("Visiting VisibilityDeclaration\n"); 535 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 536 } 537 538 override void visit(AST.AlignDeclaration d) 539 { 540 //printf("Visiting AlignDeclaration\n"); 541 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 542 } 543 544 override void visit(AST.AnonDeclaration d) 545 { 546 //printf("Visiting AnonDeclaration\n"); 547 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 548 } 549 550 override void visit(AST.PragmaDeclaration d) 551 { 552 //printf("Visiting PragmaDeclaration\n"); 553 if (d.args && d.args.dim) 554 visitArgs(d.args); 555 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 556 } 557 558 override void visit(AST.ConditionalDeclaration d) 559 { 560 //printf("Visiting ConditionalDeclaration\n"); 561 d.condition.accept(this); 562 if (d.decl) 563 foreach (de; *d.decl) 564 de.accept(this); 565 if (d.elsedecl) 566 foreach (de; *d.elsedecl) 567 de.accept(this); 568 } 569 570 override void visit(AST.CompileDeclaration d) 571 { 572 //printf("Visiting compileDeclaration\n"); 573 visitArgs(d.exps); 574 } 575 576 override void visit(AST.UserAttributeDeclaration d) 577 { 578 //printf("Visiting UserAttributeDeclaration\n"); 579 visitArgs(d.atts); 580 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 581 } 582 583 void visitFuncBody(AST.FuncDeclaration f) 584 { 585 //printf("Visiting funcBody\n"); 586 if (f.frequires) 587 { 588 foreach (frequire; *f.frequires) 589 { 590 frequire.accept(this); 591 } 592 } 593 if (f.fensures) 594 { 595 foreach (fensure; *f.fensures) 596 { 597 fensure.ensure.accept(this); 598 } 599 } 600 if (f.fbody) 601 { 602 f.fbody.accept(this); 603 } 604 } 605 606 void visitBaseClasses(AST.ClassDeclaration d) 607 { 608 //printf("Visiting ClassDeclaration\n"); 609 if (!d || !d.baseclasses.dim) 610 return; 611 foreach (b; *d.baseclasses) 612 visitType(b.type); 613 } 614 615 bool visitEponymousMember(AST.TemplateDeclaration d) 616 { 617 //printf("Visiting EponymousMember\n"); 618 if (!d.members || d.members.dim != 1) 619 return false; 620 AST.Dsymbol onemember = (*d.members)[0]; 621 if (onemember.ident != d.ident) 622 return false; 623 624 if (AST.FuncDeclaration fd = onemember.isFuncDeclaration()) 625 { 626 assert(fd.type); 627 visitFunctionType(cast(AST.TypeFunction)fd.type, d); 628 if (d.constraint) 629 d.constraint.accept(this); 630 visitFuncBody(fd); 631 632 return true; 633 } 634 635 if (AST.AggregateDeclaration ad = onemember.isAggregateDeclaration()) 636 { 637 visitTemplateParameters(d.parameters); 638 if (d.constraint) 639 d.constraint.accept(this); 640 visitBaseClasses(ad.isClassDeclaration()); 641 642 if (ad.members) 643 foreach (s; *ad.members) 644 s.accept(this); 645 646 return true; 647 } 648 649 if (AST.VarDeclaration vd = onemember.isVarDeclaration()) 650 { 651 if (d.constraint) 652 return false; 653 if (vd.type) 654 visitType(vd.type); 655 visitTemplateParameters(d.parameters); 656 if (vd._init) 657 { 658 AST.ExpInitializer ie = vd._init.isExpInitializer(); 659 if (ie && (ie.exp.op == TOK.construct || ie.exp.op == TOK.blit)) 660 (cast(AST.AssignExp)ie.exp).e2.accept(this); 661 else 662 vd._init.accept(this); 663 664 return true; 665 } 666 } 667 668 return false; 669 } 670 671 void visitTemplateParameters(AST.TemplateParameters* parameters) 672 { 673 if (!parameters || !parameters.dim) 674 return; 675 foreach (p; *parameters) 676 p.accept(this); 677 } 678 679 override void visit(AST.TemplateDeclaration d) 680 { 681 //printf("Visiting TemplateDeclaration\n"); 682 if (visitEponymousMember(d)) 683 return; 684 685 visitTemplateParameters(d.parameters); 686 if (d.constraint) 687 d.constraint.accept(this); 688 689 foreach (s; *d.members) 690 s.accept(this); 691 } 692 693 void visitObject(RootObject oarg) 694 { 695 if (auto t = AST.isType(oarg)) 696 { 697 visitType(t); 698 } 699 else if (auto e = AST.isExpression(oarg)) 700 { 701 e.accept(this); 702 } 703 else if (auto v = AST.isTuple(oarg)) 704 { 705 auto args = &v.objects; 706 foreach (arg; *args) 707 visitObject(arg); 708 } 709 } 710 711 void visitTiargs(AST.TemplateInstance ti) 712 { 713 //printf("Visiting tiargs\n"); 714 if (!ti.tiargs) 715 return; 716 foreach (arg; *ti.tiargs) 717 { 718 visitObject(arg); 719 } 720 } 721 722 override void visit(AST.TemplateInstance ti) 723 { 724 //printf("Visiting TemplateInstance\n"); 725 visitTiargs(ti); 726 } 727 728 override void visit(AST.TemplateMixin tm) 729 { 730 //printf("Visiting TemplateMixin\n"); 731 visitType(tm.tqual); 732 visitTiargs(tm); 733 } 734 735 override void visit(AST.EnumDeclaration d) 736 { 737 //printf("Visiting EnumDeclaration\n"); 738 if (d.memtype) 739 visitType(d.memtype); 740 if (!d.members) 741 return; 742 foreach (em; *d.members) 743 { 744 if (!em) 745 continue; 746 em.accept(this); 747 } 748 } 749 750 override void visit(AST.Nspace d) 751 { 752 //printf("Visiting Nspace\n"); 753 foreach(s; *d.members) 754 s.accept(this); 755 } 756 757 override void visit(AST.StructDeclaration d) 758 { 759 //printf("Visiting StructDeclaration\n"); 760 if (!d.members) 761 return; 762 foreach (s; *d.members) 763 s.accept(this); 764 } 765 766 override void visit(AST.ClassDeclaration d) 767 { 768 //printf("Visiting ClassDeclaration\n"); 769 visitBaseClasses(d); 770 if (d.members) 771 foreach (s; *d.members) 772 s.accept(this); 773 } 774 775 override void visit(AST.AliasDeclaration d) 776 { 777 //printf("Visting AliasDeclaration\n"); 778 if (d.aliassym) 779 d.aliassym.accept(this); 780 else 781 visitType(d.type); 782 } 783 784 override void visit(AST.AliasAssign d) 785 { 786 //printf("Visting AliasAssign\n"); 787 if (d.aliassym) 788 d.aliassym.accept(this); 789 else 790 visitType(d.type); 791 } 792 793 override void visit(AST.VarDeclaration d) 794 { 795 //printf("Visiting VarDeclaration\n"); 796 visitVarDecl(d); 797 } 798 799 override void visit(AST.FuncDeclaration f) 800 { 801 //printf("Visiting FuncDeclaration\n"); 802 auto tf = cast(AST.TypeFunction)f.type; 803 visitType(tf); 804 visitFuncBody(f); 805 } 806 807 override void visit(AST.FuncLiteralDeclaration f) 808 { 809 //printf("Visiting FuncLiteralDeclaration\n"); 810 if (f.type.ty == AST.Terror) 811 return; 812 AST.TypeFunction tf = cast(AST.TypeFunction)f.type; 813 if (!f.inferRetType && tf.next) 814 visitType(tf.next); 815 visitParameters(tf.parameterList.parameters); 816 AST.CompoundStatement cs = f.fbody.isCompoundStatement(); 817 AST.Statement s = !cs ? f.fbody : null; 818 AST.ReturnStatement rs = s ? s.isReturnStatement() : null; 819 if (rs && rs.exp) 820 rs.exp.accept(this); 821 else 822 visitFuncBody(f); 823 } 824 825 override void visit(AST.PostBlitDeclaration d) 826 { 827 //printf("Visiting PostBlitDeclaration\n"); 828 visitFuncBody(d); 829 } 830 831 override void visit(AST.DtorDeclaration d) 832 { 833 //printf("Visiting DtorDeclaration\n"); 834 visitFuncBody(d); 835 } 836 837 override void visit(AST.StaticCtorDeclaration d) 838 { 839 //printf("Visiting StaticCtorDeclaration\n"); 840 visitFuncBody(d); 841 } 842 843 override void visit(AST.StaticDtorDeclaration d) 844 { 845 //printf("Visiting StaticDtorDeclaration\n"); 846 visitFuncBody(d); 847 } 848 849 override void visit(AST.InvariantDeclaration d) 850 { 851 //printf("Visiting InvariantDeclaration\n"); 852 visitFuncBody(d); 853 } 854 855 override void visit(AST.UnitTestDeclaration d) 856 { 857 //printf("Visiting UnitTestDeclaration\n"); 858 visitFuncBody(d); 859 } 860 861 override void visit(AST.NewDeclaration d) 862 { 863 //printf("Visiting NewDeclaration\n"); 864 visitParameters(d.parameterList.parameters); 865 visitFuncBody(d); 866 } 867 868 // Initializers 869 //============================================================ 870 871 override void visit(AST.StructInitializer si) 872 { 873 //printf("Visiting StructInitializer\n"); 874 foreach (i, const id; si.field) 875 if (auto iz = si.value[i]) 876 iz.accept(this); 877 } 878 879 override void visit(AST.ArrayInitializer ai) 880 { 881 //printf("Visiting ArrayInitializer\n"); 882 foreach (i, ex; ai.index) 883 { 884 if (ex) 885 ex.accept(this); 886 if (auto iz = ai.value[i]) 887 iz.accept(this); 888 } 889 } 890 891 override void visit(AST.ExpInitializer ei) 892 { 893 //printf("Visiting ExpInitializer\n"); 894 ei.exp.accept(this); 895 } 896 897 // Expressions 898 //=================================================== 899 900 override void visit(AST.ArrayLiteralExp e) 901 { 902 //printf("Visiting ArrayLiteralExp\n"); 903 visitArgs(e.elements, e.basis); 904 } 905 906 override void visit(AST.AssocArrayLiteralExp e) 907 { 908 //printf("Visiting AssocArrayLiteralExp\n"); 909 foreach (i, key; *e.keys) 910 { 911 key.accept(this); 912 ((*e.values)[i]).accept(this); 913 } 914 } 915 916 override void visit(AST.TypeExp e) 917 { 918 //printf("Visiting TypeExp\n"); 919 visitType(e.type); 920 } 921 922 override void visit(AST.ScopeExp e) 923 { 924 //printf("Visiting ScopeExp\n"); 925 if (e.sds.isTemplateInstance()) 926 e.sds.accept(this); 927 } 928 929 override void visit(AST.NewExp e) 930 { 931 //printf("Visiting NewExp\n"); 932 if (e.thisexp) 933 e.thisexp.accept(this); 934 if (e.newargs && e.newargs.dim) 935 visitArgs(e.newargs); 936 visitType(e.newtype); 937 if (e.arguments && e.arguments.dim) 938 visitArgs(e.arguments); 939 } 940 941 override void visit(AST.NewAnonClassExp e) 942 { 943 //printf("Visiting NewAnonClassExp\n"); 944 if (e.thisexp) 945 e.thisexp.accept(this); 946 if (e.newargs && e.newargs.dim) 947 visitArgs(e.newargs); 948 if (e.arguments && e.arguments.dim) 949 visitArgs(e.arguments); 950 if (e.cd) 951 e.cd.accept(this); 952 } 953 954 override void visit(AST.TupleExp e) 955 { 956 //printf("Visiting TupleExp\n"); 957 if (e.e0) 958 e.e0.accept(this); 959 visitArgs(e.exps); 960 } 961 962 override void visit(AST.FuncExp e) 963 { 964 //printf("Visiting FuncExp\n"); 965 e.fd.accept(this); 966 } 967 968 override void visit(AST.DeclarationExp e) 969 { 970 //printf("Visiting DeclarationExp\n"); 971 if (auto v = e.declaration.isVarDeclaration()) 972 visitVarDecl(v); 973 else 974 e.declaration.accept(this); 975 } 976 977 override void visit(AST.TypeidExp e) 978 { 979 //printf("Visiting TypeidExp\n"); 980 visitObject(e.obj); 981 } 982 983 override void visit(AST.TraitsExp e) 984 { 985 //printf("Visiting TraitExp\n"); 986 if (e.args) 987 foreach (arg; *e.args) 988 visitObject(arg); 989 } 990 991 override void visit(AST.IsExp e) 992 { 993 //printf("Visiting IsExp\n"); 994 visitType(e.targ); 995 if (e.tspec) 996 visitType(e.tspec); 997 if (e.parameters && e.parameters.dim) 998 visitTemplateParameters(e.parameters); 999 } 1000 1001 override void visit(AST.UnaExp e) 1002 { 1003 //printf("Visiting UnaExp\n"); 1004 e.e1.accept(this); 1005 } 1006 1007 override void visit(AST.BinExp e) 1008 { 1009 //printf("Visiting BinExp\n"); 1010 e.e1.accept(this); 1011 e.e2.accept(this); 1012 } 1013 1014 override void visit(AST.MixinExp e) 1015 { 1016 //printf("Visiting MixinExp\n"); 1017 visitArgs(e.exps); 1018 } 1019 1020 override void visit(AST.ImportExp e) 1021 { 1022 //printf("Visiting ImportExp\n"); 1023 e.e1.accept(this); 1024 } 1025 1026 override void visit(AST.AssertExp e) 1027 { 1028 //printf("Visiting AssertExp\n"); 1029 e.e1.accept(this); 1030 if (e.msg) 1031 e.msg.accept(this); 1032 } 1033 1034 override void visit(AST.DotIdExp e) 1035 { 1036 //printf("Visiting DotIdExp\n"); 1037 e.e1.accept(this); 1038 } 1039 1040 override void visit(AST.DotTemplateInstanceExp e) 1041 { 1042 //printf("Visiting DotTemplateInstanceExp\n"); 1043 e.e1.accept(this); 1044 e.ti.accept(this); 1045 } 1046 1047 override void visit(AST.CallExp e) 1048 { 1049 //printf("Visiting CallExp\n"); 1050 e.e1.accept(this); 1051 visitArgs(e.arguments); 1052 } 1053 1054 override void visit(AST.PtrExp e) 1055 { 1056 //printf("Visiting PtrExp\n"); 1057 e.e1.accept(this); 1058 } 1059 1060 override void visit(AST.DeleteExp e) 1061 { 1062 //printf("Visiting DeleteExp\n"); 1063 e.e1.accept(this); 1064 } 1065 1066 override void visit(AST.CastExp e) 1067 { 1068 //printf("Visiting CastExp\n"); 1069 if (e.to) 1070 visitType(e.to); 1071 e.e1.accept(this); 1072 } 1073 1074 override void visit(AST.IntervalExp e) 1075 { 1076 //printf("Visiting IntervalExp\n"); 1077 e.lwr.accept(this); 1078 e.upr.accept(this); 1079 } 1080 1081 override void visit(AST.ArrayExp e) 1082 { 1083 //printf("Visiting ArrayExp\n"); 1084 e.e1.accept(this); 1085 visitArgs(e.arguments); 1086 } 1087 1088 override void visit(AST.PostExp e) 1089 { 1090 //printf("Visiting PostExp\n"); 1091 e.e1.accept(this); 1092 } 1093 1094 override void visit(AST.CondExp e) 1095 { 1096 //printf("Visiting CondExp\n"); 1097 e.econd.accept(this); 1098 e.e1.accept(this); 1099 e.e2.accept(this); 1100 } 1101 1102 // Template Parameter 1103 //=========================================================== 1104 1105 override void visit(AST.TemplateTypeParameter tp) 1106 { 1107 //printf("Visiting TemplateTypeParameter\n"); 1108 if (tp.specType) 1109 visitType(tp.specType); 1110 if (tp.defaultType) 1111 visitType(tp.defaultType); 1112 } 1113 1114 override void visit(AST.TemplateThisParameter tp) 1115 { 1116 //printf("Visiting TemplateThisParameter\n"); 1117 visit(cast(AST.TemplateTypeParameter)tp); 1118 } 1119 1120 override void visit(AST.TemplateAliasParameter tp) 1121 { 1122 //printf("Visiting TemplateAliasParameter\n"); 1123 if (tp.specType) 1124 visitType(tp.specType); 1125 if (tp.specAlias) 1126 visitObject(tp.specAlias); 1127 if (tp.defaultAlias) 1128 visitObject(tp.defaultAlias); 1129 } 1130 1131 override void visit(AST.TemplateValueParameter tp) 1132 { 1133 //printf("Visiting TemplateValueParameter\n"); 1134 visitType(tp.valType); 1135 if (tp.specValue) 1136 tp.specValue.accept(this); 1137 if (tp.defaultValue) 1138 tp.defaultValue.accept(this); 1139 } 1140 1141 //=========================================================== 1142 1143 override void visit(AST.StaticIfCondition c) 1144 { 1145 //printf("Visiting StaticIfCondition\n"); 1146 c.exp.accept(this); 1147 } 1148 1149 override void visit(AST.Parameter p) 1150 { 1151 //printf("Visiting Parameter\n"); 1152 visitType(p.type); 1153 if (p.defaultArg) 1154 p.defaultArg.accept(this); 1155 } 1156 1157 override void visit(AST.Module m) 1158 { 1159 //printf("Visiting Module\n"); 1160 foreach (s; *m.members) 1161 { 1162 s.accept(this); 1163 } 1164 } 1165 }