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