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