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 */
ParseVisitMethods(AST)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