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.ProtDeclaration d) 533 { 534 //printf("Visiting ProtDeclaration\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.VarDeclaration d) 785 { 786 //printf("Visiting VarDeclaration\n"); 787 visitVarDecl(d); 788 } 789 790 override void visit(AST.FuncDeclaration f) 791 { 792 //printf("Visiting FuncDeclaration\n"); 793 auto tf = cast(AST.TypeFunction)f.type; 794 visitType(tf); 795 visitFuncBody(f); 796 } 797 798 override void visit(AST.FuncLiteralDeclaration f) 799 { 800 //printf("Visiting FuncLiteralDeclaration\n"); 801 if (f.type.ty == AST.Terror) 802 return; 803 AST.TypeFunction tf = cast(AST.TypeFunction)f.type; 804 if (!f.inferRetType && tf.next) 805 visitType(tf.next); 806 visitParameters(tf.parameterList.parameters); 807 AST.CompoundStatement cs = f.fbody.isCompoundStatement(); 808 AST.Statement s = !cs ? f.fbody : null; 809 AST.ReturnStatement rs = s ? s.isReturnStatement() : null; 810 if (rs && rs.exp) 811 rs.exp.accept(this); 812 else 813 visitFuncBody(f); 814 } 815 816 override void visit(AST.PostBlitDeclaration d) 817 { 818 //printf("Visiting PostBlitDeclaration\n"); 819 visitFuncBody(d); 820 } 821 822 override void visit(AST.DtorDeclaration d) 823 { 824 //printf("Visiting DtorDeclaration\n"); 825 visitFuncBody(d); 826 } 827 828 override void visit(AST.StaticCtorDeclaration d) 829 { 830 //printf("Visiting StaticCtorDeclaration\n"); 831 visitFuncBody(d); 832 } 833 834 override void visit(AST.StaticDtorDeclaration d) 835 { 836 //printf("Visiting StaticDtorDeclaration\n"); 837 visitFuncBody(d); 838 } 839 840 override void visit(AST.InvariantDeclaration d) 841 { 842 //printf("Visiting InvariantDeclaration\n"); 843 visitFuncBody(d); 844 } 845 846 override void visit(AST.UnitTestDeclaration d) 847 { 848 //printf("Visiting UnitTestDeclaration\n"); 849 visitFuncBody(d); 850 } 851 852 override void visit(AST.NewDeclaration d) 853 { 854 //printf("Visiting NewDeclaration\n"); 855 visitParameters(d.parameterList.parameters); 856 visitFuncBody(d); 857 } 858 859 // Initializers 860 //============================================================ 861 862 override void visit(AST.StructInitializer si) 863 { 864 //printf("Visiting StructInitializer\n"); 865 foreach (i, const id; si.field) 866 if (auto iz = si.value[i]) 867 iz.accept(this); 868 } 869 870 override void visit(AST.ArrayInitializer ai) 871 { 872 //printf("Visiting ArrayInitializer\n"); 873 foreach (i, ex; ai.index) 874 { 875 if (ex) 876 ex.accept(this); 877 if (auto iz = ai.value[i]) 878 iz.accept(this); 879 } 880 } 881 882 override void visit(AST.ExpInitializer ei) 883 { 884 //printf("Visiting ExpInitializer\n"); 885 ei.exp.accept(this); 886 } 887 888 // Expressions 889 //=================================================== 890 891 override void visit(AST.ArrayLiteralExp e) 892 { 893 //printf("Visiting ArrayLiteralExp\n"); 894 visitArgs(e.elements, e.basis); 895 } 896 897 override void visit(AST.AssocArrayLiteralExp e) 898 { 899 //printf("Visiting AssocArrayLiteralExp\n"); 900 foreach (i, key; *e.keys) 901 { 902 key.accept(this); 903 ((*e.values)[i]).accept(this); 904 } 905 } 906 907 override void visit(AST.TypeExp e) 908 { 909 //printf("Visiting TypeExp\n"); 910 visitType(e.type); 911 } 912 913 override void visit(AST.ScopeExp e) 914 { 915 //printf("Visiting ScopeExp\n"); 916 if (e.sds.isTemplateInstance()) 917 e.sds.accept(this); 918 } 919 920 override void visit(AST.NewExp e) 921 { 922 //printf("Visiting NewExp\n"); 923 if (e.thisexp) 924 e.thisexp.accept(this); 925 if (e.newargs && e.newargs.dim) 926 visitArgs(e.newargs); 927 visitType(e.newtype); 928 if (e.arguments && e.arguments.dim) 929 visitArgs(e.arguments); 930 } 931 932 override void visit(AST.NewAnonClassExp e) 933 { 934 //printf("Visiting NewAnonClassExp\n"); 935 if (e.thisexp) 936 e.thisexp.accept(this); 937 if (e.newargs && e.newargs.dim) 938 visitArgs(e.newargs); 939 if (e.arguments && e.arguments.dim) 940 visitArgs(e.arguments); 941 if (e.cd) 942 e.cd.accept(this); 943 } 944 945 override void visit(AST.TupleExp e) 946 { 947 //printf("Visiting TupleExp\n"); 948 if (e.e0) 949 e.e0.accept(this); 950 visitArgs(e.exps); 951 } 952 953 override void visit(AST.FuncExp e) 954 { 955 //printf("Visiting FuncExp\n"); 956 e.fd.accept(this); 957 } 958 959 override void visit(AST.DeclarationExp e) 960 { 961 //printf("Visiting DeclarationExp\n"); 962 if (auto v = e.declaration.isVarDeclaration()) 963 visitVarDecl(v); 964 else 965 e.declaration.accept(this); 966 } 967 968 override void visit(AST.TypeidExp e) 969 { 970 //printf("Visiting TypeidExp\n"); 971 visitObject(e.obj); 972 } 973 974 override void visit(AST.TraitsExp e) 975 { 976 //printf("Visiting TraitExp\n"); 977 if (e.args) 978 foreach (arg; *e.args) 979 visitObject(arg); 980 } 981 982 override void visit(AST.IsExp e) 983 { 984 //printf("Visiting IsExp\n"); 985 visitType(e.targ); 986 if (e.tspec) 987 visitType(e.tspec); 988 if (e.parameters && e.parameters.dim) 989 visitTemplateParameters(e.parameters); 990 } 991 992 override void visit(AST.UnaExp e) 993 { 994 //printf("Visiting UnaExp\n"); 995 e.e1.accept(this); 996 } 997 998 override void visit(AST.BinExp e) 999 { 1000 //printf("Visiting BinExp\n"); 1001 e.e1.accept(this); 1002 e.e2.accept(this); 1003 } 1004 1005 override void visit(AST.CompileExp e) 1006 { 1007 //printf("Visiting CompileExp\n"); 1008 visitArgs(e.exps); 1009 } 1010 1011 override void visit(AST.ImportExp e) 1012 { 1013 //printf("Visiting ImportExp\n"); 1014 e.e1.accept(this); 1015 } 1016 1017 override void visit(AST.AssertExp e) 1018 { 1019 //printf("Visiting AssertExp\n"); 1020 e.e1.accept(this); 1021 if (e.msg) 1022 e.msg.accept(this); 1023 } 1024 1025 override void visit(AST.DotIdExp e) 1026 { 1027 //printf("Visiting DotIdExp\n"); 1028 e.e1.accept(this); 1029 } 1030 1031 override void visit(AST.DotTemplateInstanceExp e) 1032 { 1033 //printf("Visiting DotTemplateInstanceExp\n"); 1034 e.e1.accept(this); 1035 e.ti.accept(this); 1036 } 1037 1038 override void visit(AST.CallExp e) 1039 { 1040 //printf("Visiting CallExp\n"); 1041 e.e1.accept(this); 1042 visitArgs(e.arguments); 1043 } 1044 1045 override void visit(AST.PtrExp e) 1046 { 1047 //printf("Visiting PtrExp\n"); 1048 e.e1.accept(this); 1049 } 1050 1051 override void visit(AST.DeleteExp e) 1052 { 1053 //printf("Visiting DeleteExp\n"); 1054 e.e1.accept(this); 1055 } 1056 1057 override void visit(AST.CastExp e) 1058 { 1059 //printf("Visiting CastExp\n"); 1060 if (e.to) 1061 visitType(e.to); 1062 e.e1.accept(this); 1063 } 1064 1065 override void visit(AST.IntervalExp e) 1066 { 1067 //printf("Visiting IntervalExp\n"); 1068 e.lwr.accept(this); 1069 e.upr.accept(this); 1070 } 1071 1072 override void visit(AST.ArrayExp e) 1073 { 1074 //printf("Visiting ArrayExp\n"); 1075 e.e1.accept(this); 1076 visitArgs(e.arguments); 1077 } 1078 1079 override void visit(AST.PostExp e) 1080 { 1081 //printf("Visiting PostExp\n"); 1082 e.e1.accept(this); 1083 } 1084 1085 override void visit(AST.CondExp e) 1086 { 1087 //printf("Visiting CondExp\n"); 1088 e.econd.accept(this); 1089 e.e1.accept(this); 1090 e.e2.accept(this); 1091 } 1092 1093 // Template Parameter 1094 //=========================================================== 1095 1096 override void visit(AST.TemplateTypeParameter tp) 1097 { 1098 //printf("Visiting TemplateTypeParameter\n"); 1099 if (tp.specType) 1100 visitType(tp.specType); 1101 if (tp.defaultType) 1102 visitType(tp.defaultType); 1103 } 1104 1105 override void visit(AST.TemplateThisParameter tp) 1106 { 1107 //printf("Visiting TemplateThisParameter\n"); 1108 visit(cast(AST.TemplateTypeParameter)tp); 1109 } 1110 1111 override void visit(AST.TemplateAliasParameter tp) 1112 { 1113 //printf("Visiting TemplateAliasParameter\n"); 1114 if (tp.specType) 1115 visitType(tp.specType); 1116 if (tp.specAlias) 1117 visitObject(tp.specAlias); 1118 if (tp.defaultAlias) 1119 visitObject(tp.defaultAlias); 1120 } 1121 1122 override void visit(AST.TemplateValueParameter tp) 1123 { 1124 //printf("Visiting TemplateValueParameter\n"); 1125 visitType(tp.valType); 1126 if (tp.specValue) 1127 tp.specValue.accept(this); 1128 if (tp.defaultValue) 1129 tp.defaultValue.accept(this); 1130 } 1131 1132 //=========================================================== 1133 1134 override void visit(AST.StaticIfCondition c) 1135 { 1136 //printf("Visiting StaticIfCondition\n"); 1137 c.exp.accept(this); 1138 } 1139 1140 override void visit(AST.Parameter p) 1141 { 1142 //printf("Visiting Parameter\n"); 1143 visitType(p.type); 1144 if (p.defaultArg) 1145 p.defaultArg.accept(this); 1146 } 1147 1148 override void visit(AST.Module m) 1149 { 1150 //printf("Visiting Module\n"); 1151 foreach (s; *m.members) 1152 { 1153 s.accept(this); 1154 } 1155 } 1156 }