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 // Miscellaneous 468 //======================================================== 469 470 override void visit(AST.StaticAssert s) 471 { 472 //printf("Visiting StaticAssert\n"); 473 s.exp.accept(this); 474 if (s.msg) 475 s.msg.accept(this); 476 } 477 478 override void visit(AST.EnumMember em) 479 { 480 //printf("Visiting EnumMember\n"); 481 if (em.type) 482 visitType(em.type); 483 if (em.value) 484 em.value.accept(this); 485 } 486 487 // Declarations 488 //========================================================= 489 void visitAttribDeclaration(AST.AttribDeclaration d) 490 { 491 if (d.decl) 492 foreach (de; *d.decl) 493 de.accept(this); 494 } 495 496 override void visit(AST.AttribDeclaration d) 497 { 498 //printf("Visiting AttribDeclaration\n"); 499 visitAttribDeclaration(d); 500 } 501 502 override void visit(AST.StorageClassDeclaration d) 503 { 504 //printf("Visiting StorageClassDeclaration\n"); 505 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 506 } 507 508 override void visit(AST.DeprecatedDeclaration d) 509 { 510 //printf("Visiting DeprecatedDeclaration\n"); 511 d.msg.accept(this); 512 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 513 } 514 515 override void visit(AST.LinkDeclaration d) 516 { 517 //printf("Visiting LinkDeclaration\n"); 518 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 519 } 520 521 override void visit(AST.CPPMangleDeclaration d) 522 { 523 //printf("Visiting CPPMangleDeclaration\n"); 524 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 525 } 526 527 override void visit(AST.ProtDeclaration d) 528 { 529 //printf("Visiting ProtDeclaration\n"); 530 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 531 } 532 533 override void visit(AST.AlignDeclaration d) 534 { 535 //printf("Visiting AlignDeclaration\n"); 536 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 537 } 538 539 override void visit(AST.AnonDeclaration d) 540 { 541 //printf("Visiting AnonDeclaration\n"); 542 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 543 } 544 545 override void visit(AST.PragmaDeclaration d) 546 { 547 //printf("Visiting PragmaDeclaration\n"); 548 if (d.args && d.args.dim) 549 visitArgs(d.args); 550 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 551 } 552 553 override void visit(AST.ConditionalDeclaration d) 554 { 555 //printf("Visiting ConditionalDeclaration\n"); 556 d.condition.accept(this); 557 if (d.decl) 558 foreach (de; *d.decl) 559 de.accept(this); 560 if (d.elsedecl) 561 foreach (de; *d.elsedecl) 562 de.accept(this); 563 } 564 565 override void visit(AST.CompileDeclaration d) 566 { 567 //printf("Visiting compileDeclaration\n"); 568 visitArgs(d.exps); 569 } 570 571 override void visit(AST.UserAttributeDeclaration d) 572 { 573 //printf("Visiting UserAttributeDeclaration\n"); 574 visitArgs(d.atts); 575 visitAttribDeclaration(cast(AST.AttribDeclaration)d); 576 } 577 578 void visitFuncBody(AST.FuncDeclaration f) 579 { 580 //printf("Visiting funcBody\n"); 581 if (f.frequires) 582 { 583 foreach (frequire; *f.frequires) 584 { 585 frequire.accept(this); 586 } 587 } 588 if (f.fensures) 589 { 590 foreach (fensure; *f.fensures) 591 { 592 fensure.ensure.accept(this); 593 } 594 } 595 if (f.fbody) 596 { 597 f.fbody.accept(this); 598 } 599 } 600 601 void visitBaseClasses(AST.ClassDeclaration d) 602 { 603 //printf("Visiting ClassDeclaration\n"); 604 if (!d || !d.baseclasses.dim) 605 return; 606 foreach (b; *d.baseclasses) 607 visitType(b.type); 608 } 609 610 bool visitEponymousMember(AST.TemplateDeclaration d) 611 { 612 //printf("Visiting EponymousMember\n"); 613 if (!d.members || d.members.dim != 1) 614 return false; 615 AST.Dsymbol onemember = (*d.members)[0]; 616 if (onemember.ident != d.ident) 617 return false; 618 619 if (AST.FuncDeclaration fd = onemember.isFuncDeclaration()) 620 { 621 assert(fd.type); 622 visitFunctionType(cast(AST.TypeFunction)fd.type, d); 623 if (d.constraint) 624 d.constraint.accept(this); 625 visitFuncBody(fd); 626 627 return true; 628 } 629 630 if (AST.AggregateDeclaration ad = onemember.isAggregateDeclaration()) 631 { 632 visitTemplateParameters(d.parameters); 633 if (d.constraint) 634 d.constraint.accept(this); 635 visitBaseClasses(ad.isClassDeclaration()); 636 637 if (ad.members) 638 foreach (s; *ad.members) 639 s.accept(this); 640 641 return true; 642 } 643 644 if (AST.VarDeclaration vd = onemember.isVarDeclaration()) 645 { 646 if (d.constraint) 647 return false; 648 if (vd.type) 649 visitType(vd.type); 650 visitTemplateParameters(d.parameters); 651 if (vd._init) 652 { 653 AST.ExpInitializer ie = vd._init.isExpInitializer(); 654 if (ie && (ie.exp.op == TOK.construct || ie.exp.op == TOK.blit)) 655 (cast(AST.AssignExp)ie.exp).e2.accept(this); 656 else 657 vd._init.accept(this); 658 659 return true; 660 } 661 } 662 663 return false; 664 } 665 666 void visitTemplateParameters(AST.TemplateParameters* parameters) 667 { 668 if (!parameters || !parameters.dim) 669 return; 670 foreach (p; *parameters) 671 p.accept(this); 672 } 673 674 override void visit(AST.TemplateDeclaration d) 675 { 676 //printf("Visiting TemplateDeclaration\n"); 677 if (visitEponymousMember(d)) 678 return; 679 680 visitTemplateParameters(d.parameters); 681 if (d.constraint) 682 d.constraint.accept(this); 683 684 foreach (s; *d.members) 685 s.accept(this); 686 } 687 688 void visitObject(RootObject oarg) 689 { 690 if (auto t = AST.isType(oarg)) 691 { 692 visitType(t); 693 } 694 else if (auto e = AST.isExpression(oarg)) 695 { 696 e.accept(this); 697 } 698 else if (auto v = AST.isTuple(oarg)) 699 { 700 auto args = &v.objects; 701 foreach (arg; *args) 702 visitObject(arg); 703 } 704 } 705 706 void visitTiargs(AST.TemplateInstance ti) 707 { 708 //printf("Visiting tiargs\n"); 709 if (!ti.tiargs) 710 return; 711 foreach (arg; *ti.tiargs) 712 { 713 visitObject(arg); 714 } 715 } 716 717 override void visit(AST.TemplateInstance ti) 718 { 719 //printf("Visiting TemplateInstance\n"); 720 visitTiargs(ti); 721 } 722 723 override void visit(AST.TemplateMixin tm) 724 { 725 //printf("Visiting TemplateMixin\n"); 726 visitType(tm.tqual); 727 visitTiargs(tm); 728 } 729 730 override void visit(AST.EnumDeclaration d) 731 { 732 //printf("Visiting EnumDeclaration\n"); 733 if (d.memtype) 734 visitType(d.memtype); 735 if (!d.members) 736 return; 737 foreach (em; *d.members) 738 { 739 if (!em) 740 continue; 741 em.accept(this); 742 } 743 } 744 745 override void visit(AST.Nspace d) 746 { 747 //printf("Visiting Nspace\n"); 748 foreach(s; *d.members) 749 s.accept(this); 750 } 751 752 override void visit(AST.StructDeclaration d) 753 { 754 //printf("Visiting StructDeclaration\n"); 755 if (!d.members) 756 return; 757 foreach (s; *d.members) 758 s.accept(this); 759 } 760 761 override void visit(AST.ClassDeclaration d) 762 { 763 //printf("Visiting ClassDeclaration\n"); 764 visitBaseClasses(d); 765 if (d.members) 766 foreach (s; *d.members) 767 s.accept(this); 768 } 769 770 override void visit(AST.AliasDeclaration d) 771 { 772 //printf("Visting AliasDeclaration\n"); 773 if (d.aliassym) 774 d.aliassym.accept(this); 775 else 776 visitType(d.type); 777 } 778 779 override void visit(AST.VarDeclaration d) 780 { 781 //printf("Visiting VarDeclaration\n"); 782 visitVarDecl(d); 783 } 784 785 override void visit(AST.FuncDeclaration f) 786 { 787 //printf("Visiting FuncDeclaration\n"); 788 auto tf = cast(AST.TypeFunction)f.type; 789 visitType(tf); 790 visitFuncBody(f); 791 } 792 793 override void visit(AST.FuncLiteralDeclaration f) 794 { 795 //printf("Visiting FuncLiteralDeclaration\n"); 796 if (f.type.ty == AST.Terror) 797 return; 798 AST.TypeFunction tf = cast(AST.TypeFunction)f.type; 799 if (!f.inferRetType && tf.next) 800 visitType(tf.next); 801 visitParameters(tf.parameterList.parameters); 802 AST.CompoundStatement cs = f.fbody.isCompoundStatement(); 803 AST.Statement s = !cs ? f.fbody : null; 804 AST.ReturnStatement rs = s ? s.isReturnStatement() : null; 805 if (rs && rs.exp) 806 rs.exp.accept(this); 807 else 808 visitFuncBody(f); 809 } 810 811 override void visit(AST.PostBlitDeclaration d) 812 { 813 //printf("Visiting PostBlitDeclaration\n"); 814 visitFuncBody(d); 815 } 816 817 override void visit(AST.DtorDeclaration d) 818 { 819 //printf("Visiting DtorDeclaration\n"); 820 visitFuncBody(d); 821 } 822 823 override void visit(AST.StaticCtorDeclaration d) 824 { 825 //printf("Visiting StaticCtorDeclaration\n"); 826 visitFuncBody(d); 827 } 828 829 override void visit(AST.StaticDtorDeclaration d) 830 { 831 //printf("Visiting StaticDtorDeclaration\n"); 832 visitFuncBody(d); 833 } 834 835 override void visit(AST.InvariantDeclaration d) 836 { 837 //printf("Visiting InvariantDeclaration\n"); 838 visitFuncBody(d); 839 } 840 841 override void visit(AST.UnitTestDeclaration d) 842 { 843 //printf("Visiting UnitTestDeclaration\n"); 844 visitFuncBody(d); 845 } 846 847 override void visit(AST.NewDeclaration d) 848 { 849 //printf("Visiting NewDeclaration\n"); 850 visitParameters(d.parameters); 851 visitFuncBody(d); 852 } 853 854 // Initializers 855 //============================================================ 856 857 override void visit(AST.StructInitializer si) 858 { 859 //printf("Visiting StructInitializer\n"); 860 foreach (i, const id; si.field) 861 if (auto iz = si.value[i]) 862 iz.accept(this); 863 } 864 865 override void visit(AST.ArrayInitializer ai) 866 { 867 //printf("Visiting ArrayInitializer\n"); 868 foreach (i, ex; ai.index) 869 { 870 if (ex) 871 ex.accept(this); 872 if (auto iz = ai.value[i]) 873 iz.accept(this); 874 } 875 } 876 877 override void visit(AST.ExpInitializer ei) 878 { 879 //printf("Visiting ExpInitializer\n"); 880 ei.exp.accept(this); 881 } 882 883 // Expressions 884 //=================================================== 885 886 override void visit(AST.ArrayLiteralExp e) 887 { 888 //printf("Visiting ArrayLiteralExp\n"); 889 visitArgs(e.elements, e.basis); 890 } 891 892 override void visit(AST.AssocArrayLiteralExp e) 893 { 894 //printf("Visiting AssocArrayLiteralExp\n"); 895 foreach (i, key; *e.keys) 896 { 897 key.accept(this); 898 ((*e.values)[i]).accept(this); 899 } 900 } 901 902 override void visit(AST.TypeExp e) 903 { 904 //printf("Visiting TypeExp\n"); 905 visitType(e.type); 906 } 907 908 override void visit(AST.ScopeExp e) 909 { 910 //printf("Visiting ScopeExp\n"); 911 if (e.sds.isTemplateInstance()) 912 e.sds.accept(this); 913 } 914 915 override void visit(AST.NewExp e) 916 { 917 //printf("Visiting NewExp\n"); 918 if (e.thisexp) 919 e.thisexp.accept(this); 920 if (e.newargs && e.newargs.dim) 921 visitArgs(e.newargs); 922 visitType(e.newtype); 923 if (e.arguments && e.arguments.dim) 924 visitArgs(e.arguments); 925 } 926 927 override void visit(AST.NewAnonClassExp e) 928 { 929 //printf("Visiting NewAnonClassExp\n"); 930 if (e.thisexp) 931 e.thisexp.accept(this); 932 if (e.newargs && e.newargs.dim) 933 visitArgs(e.newargs); 934 if (e.arguments && e.arguments.dim) 935 visitArgs(e.arguments); 936 if (e.cd) 937 e.cd.accept(this); 938 } 939 940 override void visit(AST.TupleExp e) 941 { 942 //printf("Visiting TupleExp\n"); 943 if (e.e0) 944 e.e0.accept(this); 945 visitArgs(e.exps); 946 } 947 948 override void visit(AST.FuncExp e) 949 { 950 //printf("Visiting FuncExp\n"); 951 e.fd.accept(this); 952 } 953 954 override void visit(AST.DeclarationExp e) 955 { 956 //printf("Visiting DeclarationExp\n"); 957 if (auto v = e.declaration.isVarDeclaration()) 958 visitVarDecl(v); 959 else 960 e.declaration.accept(this); 961 } 962 963 override void visit(AST.TypeidExp e) 964 { 965 //printf("Visiting TypeidExp\n"); 966 visitObject(e.obj); 967 } 968 969 override void visit(AST.TraitsExp e) 970 { 971 //printf("Visiting TraitExp\n"); 972 if (e.args) 973 foreach (arg; *e.args) 974 visitObject(arg); 975 } 976 977 override void visit(AST.IsExp e) 978 { 979 //printf("Visiting IsExp\n"); 980 visitType(e.targ); 981 if (e.tspec) 982 visitType(e.tspec); 983 if (e.parameters && e.parameters.dim) 984 visitTemplateParameters(e.parameters); 985 } 986 987 override void visit(AST.UnaExp e) 988 { 989 //printf("Visiting UnaExp\n"); 990 e.e1.accept(this); 991 } 992 993 override void visit(AST.BinExp e) 994 { 995 //printf("Visiting BinExp\n"); 996 e.e1.accept(this); 997 e.e2.accept(this); 998 } 999 1000 override void visit(AST.CompileExp e) 1001 { 1002 //printf("Visiting CompileExp\n"); 1003 visitArgs(e.exps); 1004 } 1005 1006 override void visit(AST.ImportExp e) 1007 { 1008 //printf("Visiting ImportExp\n"); 1009 e.e1.accept(this); 1010 } 1011 1012 override void visit(AST.AssertExp e) 1013 { 1014 //printf("Visiting AssertExp\n"); 1015 e.e1.accept(this); 1016 if (e.msg) 1017 e.msg.accept(this); 1018 } 1019 1020 override void visit(AST.DotIdExp e) 1021 { 1022 //printf("Visiting DotIdExp\n"); 1023 e.e1.accept(this); 1024 } 1025 1026 override void visit(AST.DotTemplateInstanceExp e) 1027 { 1028 //printf("Visiting DotTemplateInstanceExp\n"); 1029 e.e1.accept(this); 1030 e.ti.accept(this); 1031 } 1032 1033 override void visit(AST.CallExp e) 1034 { 1035 //printf("Visiting CallExp\n"); 1036 e.e1.accept(this); 1037 visitArgs(e.arguments); 1038 } 1039 1040 override void visit(AST.PtrExp e) 1041 { 1042 //printf("Visiting PtrExp\n"); 1043 e.e1.accept(this); 1044 } 1045 1046 override void visit(AST.DeleteExp e) 1047 { 1048 //printf("Visiting DeleteExp\n"); 1049 e.e1.accept(this); 1050 } 1051 1052 override void visit(AST.CastExp e) 1053 { 1054 //printf("Visiting CastExp\n"); 1055 if (e.to) 1056 visitType(e.to); 1057 e.e1.accept(this); 1058 } 1059 1060 override void visit(AST.IntervalExp e) 1061 { 1062 //printf("Visiting IntervalExp\n"); 1063 e.lwr.accept(this); 1064 e.upr.accept(this); 1065 } 1066 1067 override void visit(AST.ArrayExp e) 1068 { 1069 //printf("Visiting ArrayExp\n"); 1070 e.e1.accept(this); 1071 visitArgs(e.arguments); 1072 } 1073 1074 override void visit(AST.PostExp e) 1075 { 1076 //printf("Visiting PostExp\n"); 1077 e.e1.accept(this); 1078 } 1079 1080 override void visit(AST.CondExp e) 1081 { 1082 //printf("Visiting CondExp\n"); 1083 e.econd.accept(this); 1084 e.e1.accept(this); 1085 e.e2.accept(this); 1086 } 1087 1088 // Template Parameter 1089 //=========================================================== 1090 1091 override void visit(AST.TemplateTypeParameter tp) 1092 { 1093 //printf("Visiting TemplateTypeParameter\n"); 1094 if (tp.specType) 1095 visitType(tp.specType); 1096 if (tp.defaultType) 1097 visitType(tp.defaultType); 1098 } 1099 1100 override void visit(AST.TemplateThisParameter tp) 1101 { 1102 //printf("Visiting TemplateThisParameter\n"); 1103 visit(cast(AST.TemplateTypeParameter)tp); 1104 } 1105 1106 override void visit(AST.TemplateAliasParameter tp) 1107 { 1108 //printf("Visiting TemplateAliasParameter\n"); 1109 if (tp.specType) 1110 visitType(tp.specType); 1111 if (tp.specAlias) 1112 visitObject(tp.specAlias); 1113 if (tp.defaultAlias) 1114 visitObject(tp.defaultAlias); 1115 } 1116 1117 override void visit(AST.TemplateValueParameter tp) 1118 { 1119 //printf("Visiting TemplateValueParameter\n"); 1120 visitType(tp.valType); 1121 if (tp.specValue) 1122 tp.specValue.accept(this); 1123 if (tp.defaultValue) 1124 tp.defaultValue.accept(this); 1125 } 1126 1127 //=========================================================== 1128 1129 override void visit(AST.StaticIfCondition c) 1130 { 1131 //printf("Visiting StaticIfCondition\n"); 1132 c.exp.accept(this); 1133 } 1134 1135 override void visit(AST.Parameter p) 1136 { 1137 //printf("Visiting Parameter\n"); 1138 visitType(p.type); 1139 if (p.defaultArg) 1140 p.defaultArg.accept(this); 1141 } 1142 1143 override void visit(AST.Module m) 1144 { 1145 //printf("Visiting Module\n"); 1146 foreach (s; *m.members) 1147 { 1148 s.accept(this); 1149 } 1150 } 1151 }