1use crate::syntax;
70
71#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
76pub enum Visit {
77 Children,
81 Parent,
83}
84
85macro_rules! make_visitor_trait {
86 ($t:ident, $($ref:tt)*) => {
87 pub trait $t {
92 fn visit_translation_unit(&mut self, _: $($ref)* syntax::TranslationUnit) -> Visit {
93 Visit::Children
94 }
95
96 fn visit_external_declaration(&mut self, _: $($ref)* syntax::ExternalDeclaration) -> Visit {
97 Visit::Children
98 }
99
100 fn visit_identifier(&mut self, _: $($ref)* syntax::Identifier) -> Visit {
101 Visit::Children
102 }
103
104 fn visit_arrayed_identifier(&mut self, _: $($ref)* syntax::ArrayedIdentifier) -> Visit {
105 Visit::Children
106 }
107
108 fn visit_type_name(&mut self, _: $($ref)* syntax::TypeName) -> Visit {
109 Visit::Children
110 }
111
112 fn visit_block(&mut self, _: $($ref)* syntax::Block) -> Visit {
113 Visit::Children
114 }
115
116 fn visit_for_init_statement(&mut self, _: $($ref)* syntax::ForInitStatement) -> Visit {
117 Visit::Children
118 }
119
120 fn visit_for_rest_statement(&mut self, _: $($ref)* syntax::ForRestStatement) -> Visit {
121 Visit::Children
122 }
123
124 fn visit_function_definition(&mut self, _: $($ref)* syntax::FunctionDefinition) -> Visit {
125 Visit::Children
126 }
127
128 fn visit_function_parameter_declarator(
129 &mut self,
130 _: $($ref)* syntax::FunctionParameterDeclarator,
131 ) -> Visit {
132 Visit::Children
133 }
134
135 fn visit_function_prototype(&mut self, _: $($ref)* syntax::FunctionPrototype) -> Visit {
136 Visit::Children
137 }
138
139 fn visit_init_declarator_list(&mut self, _: $($ref)* syntax::InitDeclaratorList) -> Visit {
140 Visit::Children
141 }
142
143 fn visit_layout_qualifier(&mut self, _: $($ref)* syntax::LayoutQualifier) -> Visit {
144 Visit::Children
145 }
146
147 fn visit_preprocessor(&mut self, _: $($ref)* syntax::Preprocessor) -> Visit {
148 Visit::Children
149 }
150
151 fn visit_preprocessor_define(&mut self, _: $($ref)* syntax::PreprocessorDefine) -> Visit {
152 Visit::Children
153 }
154
155 fn visit_preprocessor_elif(&mut self, _: $($ref)* syntax::PreprocessorElIf) -> Visit {
156 Visit::Children
157 }
158
159 fn visit_preprocessor_error(&mut self, _: $($ref)* syntax::PreprocessorError) -> Visit {
160 Visit::Children
161 }
162
163 fn visit_preprocessor_extension(&mut self, _: $($ref)* syntax::PreprocessorExtension) -> Visit {
164 Visit::Children
165 }
166
167 fn visit_preprocessor_extension_behavior(
168 &mut self,
169 _: $($ref)* syntax::PreprocessorExtensionBehavior,
170 ) -> Visit {
171 Visit::Children
172 }
173
174 fn visit_preprocessor_extension_name(
175 &mut self,
176 _: $($ref)* syntax::PreprocessorExtensionName,
177 ) -> Visit {
178 Visit::Children
179 }
180
181 fn visit_preprocessor_if(&mut self, _: $($ref)* syntax::PreprocessorIf) -> Visit {
182 Visit::Children
183 }
184
185 fn visit_preprocessor_ifdef(&mut self, _: $($ref)* syntax::PreprocessorIfDef) -> Visit {
186 Visit::Children
187 }
188
189 fn visit_preprocessor_ifndef(&mut self, _: $($ref)* syntax::PreprocessorIfNDef) -> Visit {
190 Visit::Children
191 }
192
193 fn visit_preprocessor_include(&mut self, _: $($ref)* syntax::PreprocessorInclude) -> Visit {
194 Visit::Children
195 }
196
197 fn visit_preprocessor_line(&mut self, _: $($ref)* syntax::PreprocessorLine) -> Visit {
198 Visit::Children
199 }
200
201 fn visit_preprocessor_pragma(&mut self, _: $($ref)* syntax::PreprocessorPragma) -> Visit {
202 Visit::Children
203 }
204
205 fn visit_preprocessor_undef(&mut self, _: $($ref)* syntax::PreprocessorUndef) -> Visit {
206 Visit::Children
207 }
208
209 fn visit_preprocessor_version(&mut self, _: $($ref)* syntax::PreprocessorVersion) -> Visit {
210 Visit::Children
211 }
212
213 fn visit_preprocessor_version_profile(
214 &mut self,
215 _: $($ref)* syntax::PreprocessorVersionProfile,
216 ) -> Visit {
217 Visit::Children
218 }
219
220 fn visit_selection_statement(&mut self, _: $($ref)* syntax::SelectionStatement) -> Visit {
221 Visit::Children
222 }
223
224 fn visit_selection_rest_statement(&mut self, _: $($ref)* syntax::SelectionRestStatement) -> Visit {
225 Visit::Children
226 }
227
228 fn visit_single_declaration(&mut self, _: $($ref)* syntax::SingleDeclaration) -> Visit {
229 Visit::Children
230 }
231
232 fn visit_single_declaration_no_type(&mut self, _: $($ref)* syntax::SingleDeclarationNoType) -> Visit {
233 Visit::Children
234 }
235
236 fn visit_struct_field_specifier(&mut self, _: $($ref)* syntax::StructFieldSpecifier) -> Visit {
237 Visit::Children
238 }
239
240 fn visit_struct_specifier(&mut self, _: $($ref)* syntax::StructSpecifier) -> Visit {
241 Visit::Children
242 }
243
244 fn visit_switch_statement(&mut self, _: $($ref)* syntax::SwitchStatement) -> Visit {
245 Visit::Children
246 }
247
248 fn visit_type_qualifier(&mut self, _: $($ref)* syntax::TypeQualifier) -> Visit {
249 Visit::Children
250 }
251
252 fn visit_type_specifier(&mut self, _: $($ref)* syntax::TypeSpecifier) -> Visit {
253 Visit::Children
254 }
255
256 fn visit_full_specified_type(&mut self, _: $($ref)* syntax::FullySpecifiedType) -> Visit {
257 Visit::Children
258 }
259
260 fn visit_array_specifier(&mut self, _: $($ref)* syntax::ArraySpecifier) -> Visit {
261 Visit::Children
262 }
263
264 fn visit_array_specifier_dimension(&mut self, _: $($ref)* syntax::ArraySpecifierDimension) -> Visit {
265 Visit::Children
266 }
267
268 fn visit_assignment_op(&mut self, _: $($ref)* syntax::AssignmentOp) -> Visit {
269 Visit::Children
270 }
271
272 fn visit_binary_op(&mut self, _: $($ref)* syntax::BinaryOp) -> Visit {
273 Visit::Children
274 }
275
276 fn visit_case_label(&mut self, _: $($ref)* syntax::CaseLabel) -> Visit {
277 Visit::Children
278 }
279
280 fn visit_condition(&mut self, _: $($ref)* syntax::Condition) -> Visit {
281 Visit::Children
282 }
283
284 fn visit_declaration(&mut self, _: $($ref)* syntax::Declaration) -> Visit {
285 Visit::Children
286 }
287
288 fn visit_expr(&mut self, _: $($ref)* syntax::Expr) -> Visit {
289 Visit::Children
290 }
291
292 fn visit_fun_identifier(&mut self, _: $($ref)* syntax::FunIdentifier) -> Visit {
293 Visit::Children
294 }
295
296 fn visit_function_parameter_declaration(
297 &mut self,
298 _: $($ref)* syntax::FunctionParameterDeclaration,
299 ) -> Visit {
300 Visit::Children
301 }
302
303 fn visit_initializer(&mut self, _: $($ref)* syntax::Initializer) -> Visit {
304 Visit::Children
305 }
306
307 fn visit_interpolation_qualifier(&mut self, _: $($ref)* syntax::InterpolationQualifier) -> Visit {
308 Visit::Children
309 }
310
311 fn visit_iteration_statement(&mut self, _: $($ref)* syntax::IterationStatement) -> Visit {
312 Visit::Children
313 }
314
315 fn visit_jump_statement(&mut self, _: $($ref)* syntax::JumpStatement) -> Visit {
316 Visit::Children
317 }
318
319 fn visit_layout_qualifier_spec(&mut self, _: $($ref)* syntax::LayoutQualifierSpec) -> Visit {
320 Visit::Children
321 }
322
323 fn visit_precision_qualifier(&mut self, _: $($ref)* syntax::PrecisionQualifier) -> Visit {
324 Visit::Children
325 }
326
327 fn visit_statement(&mut self, _: $($ref)* syntax::Statement) -> Visit {
328 Visit::Children
329 }
330
331 fn visit_compound_statement(&mut self, _: $($ref)* syntax::CompoundStatement) -> Visit {
332 Visit::Children
333 }
334
335 fn visit_simple_statement(&mut self, _: $($ref)* syntax::SimpleStatement) -> Visit {
336 Visit::Children
337 }
338
339 fn visit_storage_qualifier(&mut self, _: $($ref)* syntax::StorageQualifier) -> Visit {
340 Visit::Children
341 }
342
343 fn visit_type_qualifier_spec(&mut self, _: $($ref)* syntax::TypeQualifierSpec) -> Visit {
344 Visit::Children
345 }
346
347 fn visit_type_specifier_non_array(&mut self, _: $($ref)* syntax::TypeSpecifierNonArray) -> Visit {
348 Visit::Children
349 }
350
351 fn visit_unary_op(&mut self, _: $($ref)* syntax::UnaryOp) -> Visit {
352 Visit::Children
353 }
354
355 fn visit_expr_statement(&mut self, _: $($ref)* syntax::ExprStatement) -> Visit {
356 Visit::Children
357 }
358 }
359 }
360}
361
362macro_rules! make_host_trait {
363 ($host_ty:ident, $visitor_ty:ident, $mthd_name:ident, $($ref:tt)*) => {
364 pub trait $host_ty {
386 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
388 where
389 V: $visitor_ty;
390 }
391
392 impl<T> $host_ty for Option<T>
393 where
394 T: $host_ty,
395 {
396 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
397 where
398 V: $visitor_ty,
399 {
400 if let Some(x) = self {
401 x.$mthd_name(visitor);
402 }
403 }
404 }
405
406 impl<T> $host_ty for Box<T>
407 where
408 T: $host_ty,
409 {
410 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
411 where
412 V: $visitor_ty,
413 {
414 (**self).$mthd_name(visitor);
415 }
416 }
417
418 impl $host_ty for syntax::TranslationUnit {
419 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
420 where
421 V: $visitor_ty,
422 {
423 let visit = visitor.visit_translation_unit(self);
424
425 if visit == Visit::Children {
426 for ed in $($ref)* (self.0).0 {
427 ed.$mthd_name(visitor);
428 }
429 }
430 }
431 }
432
433 impl $host_ty for syntax::ExternalDeclaration {
434 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
435 where
436 V: $visitor_ty,
437 {
438 let visit = visitor.visit_external_declaration(self);
439
440 if visit == Visit::Children {
441 match self {
442 syntax::ExternalDeclaration::Preprocessor(p) => p.$mthd_name(visitor),
443 syntax::ExternalDeclaration::FunctionDefinition(fd) => fd.$mthd_name(visitor),
444 syntax::ExternalDeclaration::Declaration(d) => d.$mthd_name(visitor),
445 }
446 }
447 }
448 }
449
450 impl $host_ty for syntax::Preprocessor {
451 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
452 where
453 V: $visitor_ty,
454 {
455 let visit = visitor.visit_preprocessor(self);
456
457 if visit == Visit::Children {
458 match self {
459 syntax::Preprocessor::Define(pd) => pd.$mthd_name(visitor),
460 syntax::Preprocessor::Else => (),
461 syntax::Preprocessor::ElIf(pei) => pei.$mthd_name(visitor),
462 syntax::Preprocessor::EndIf => (),
463 syntax::Preprocessor::Error(pe) => pe.$mthd_name(visitor),
464 syntax::Preprocessor::If(pi) => pi.$mthd_name(visitor),
465 syntax::Preprocessor::IfDef(pid) => pid.$mthd_name(visitor),
466 syntax::Preprocessor::IfNDef(pind) => pind.$mthd_name(visitor),
467 syntax::Preprocessor::Include(pi) => pi.$mthd_name(visitor),
468 syntax::Preprocessor::Line(pl) => pl.$mthd_name(visitor),
469 syntax::Preprocessor::Pragma(pp) => pp.$mthd_name(visitor),
470 syntax::Preprocessor::Undef(pu) => pu.$mthd_name(visitor),
471 syntax::Preprocessor::Version(pv) => pv.$mthd_name(visitor),
472 syntax::Preprocessor::Extension(ext) => ext.$mthd_name(visitor),
473 }
474 }
475 }
476 }
477
478 impl $host_ty for syntax::PreprocessorDefine {
479 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
480 where
481 V: $visitor_ty,
482 {
483 let visit = visitor.visit_preprocessor_define(self);
484
485 if visit == Visit::Children {
486 match self {
487 syntax::PreprocessorDefine::ObjectLike { ident, .. } => {
488 ident.$mthd_name(visitor);
489 }
490
491 syntax::PreprocessorDefine::FunctionLike {
492 ident,
493 args,
494 ..
495 } => {
496 ident.$mthd_name(visitor);
497
498 for arg in args {
499 arg.$mthd_name(visitor);
500 }
501 }
502 }
503 }
504 }
505 }
506
507 impl $host_ty for syntax::PreprocessorElIf {
508 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
509 where
510 V: $visitor_ty,
511 {
512 let _ = visitor.visit_preprocessor_elif(self);
513 }
514 }
515
516 impl $host_ty for syntax::PreprocessorError {
517 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
518 where
519 V: $visitor_ty,
520 {
521 let _ = visitor.visit_preprocessor_error(self);
522 }
523 }
524
525 impl $host_ty for syntax::PreprocessorIf {
526 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
527 where
528 V: $visitor_ty,
529 {
530 let _ = visitor.visit_preprocessor_if(self);
531 }
532 }
533
534 impl $host_ty for syntax::PreprocessorIfDef {
535 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
536 where
537 V: $visitor_ty,
538 {
539 let visit = visitor.visit_preprocessor_ifdef(self);
540
541 if visit == Visit::Children {
542 self.ident.$mthd_name(visitor);
543 }
544 }
545 }
546
547 impl $host_ty for syntax::PreprocessorIfNDef {
548 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
549 where
550 V: $visitor_ty,
551 {
552 let visit = visitor.visit_preprocessor_ifndef(self);
553
554 if visit == Visit::Children {
555 self.ident.$mthd_name(visitor);
556 }
557 }
558 }
559
560 impl $host_ty for syntax::PreprocessorInclude {
561 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
562 where
563 V: $visitor_ty,
564 {
565 let _ = visitor.visit_preprocessor_include(self);
566 }
567 }
568
569 impl $host_ty for syntax::PreprocessorLine {
570 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
571 where
572 V: $visitor_ty,
573 {
574 let _ = visitor.visit_preprocessor_line(self);
575 }
576 }
577
578 impl $host_ty for syntax::PreprocessorPragma {
579 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
580 where
581 V: $visitor_ty,
582 {
583 let _ = visitor.visit_preprocessor_pragma(self);
584 }
585 }
586
587 impl $host_ty for syntax::PreprocessorUndef {
588 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
589 where
590 V: $visitor_ty,
591 {
592 let visit = visitor.visit_preprocessor_undef(self);
593
594 if visit == Visit::Children {
595 self.name.$mthd_name(visitor);
596 }
597 }
598 }
599
600 impl $host_ty for syntax::PreprocessorVersion {
601 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
602 where
603 V: $visitor_ty,
604 {
605 let visit = visitor.visit_preprocessor_version(self);
606
607 if visit == Visit::Children {
608 self.profile.$mthd_name(visitor);
609 }
610 }
611 }
612
613 impl $host_ty for syntax::PreprocessorVersionProfile {
614 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
615 where
616 V: $visitor_ty,
617 {
618 let _ = visitor.visit_preprocessor_version_profile(self);
619 }
620 }
621
622 impl $host_ty for syntax::PreprocessorExtension {
623 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
624 where
625 V: $visitor_ty,
626 {
627 let visit = visitor.visit_preprocessor_extension(self);
628
629 if visit == Visit::Children {
630 self.name.$mthd_name(visitor);
631 self.behavior.$mthd_name(visitor);
632 }
633 }
634 }
635
636 impl $host_ty for syntax::PreprocessorExtensionBehavior {
637 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
638 where
639 V: $visitor_ty,
640 {
641 let _ = visitor.visit_preprocessor_extension_behavior(self);
642 }
643 }
644
645 impl $host_ty for syntax::PreprocessorExtensionName {
646 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
647 where
648 V: $visitor_ty,
649 {
650 let _ = visitor.visit_preprocessor_extension_name(self);
651 }
652 }
653
654 impl $host_ty for syntax::FunctionPrototype {
655 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
656 where
657 V: $visitor_ty,
658 {
659 let visit = visitor.visit_function_prototype(self);
660
661 if visit == Visit::Children {
662 self.ty.$mthd_name(visitor);
663 self.name.$mthd_name(visitor);
664
665 for param in $($ref)* self.parameters {
666 param.$mthd_name(visitor);
667 }
668 }
669 }
670 }
671
672 impl $host_ty for syntax::FunctionParameterDeclaration {
673 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
674 where
675 V: $visitor_ty,
676 {
677 let visit = visitor.visit_function_parameter_declaration(self);
678
679 if visit == Visit::Children {
680 match self {
681 syntax::FunctionParameterDeclaration::Named(tq, fpd) => {
682 tq.$mthd_name(visitor);
683 fpd.$mthd_name(visitor);
684 }
685
686 syntax::FunctionParameterDeclaration::Unnamed(tq, ty) => {
687 tq.$mthd_name(visitor);
688 ty.$mthd_name(visitor);
689 }
690 }
691 }
692 }
693 }
694
695 impl $host_ty for syntax::FunctionParameterDeclarator {
696 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
697 where
698 V: $visitor_ty,
699 {
700 let visit = visitor.visit_function_parameter_declarator(self);
701
702 if visit == Visit::Children {
703 self.ty.$mthd_name(visitor);
704 self.ident.$mthd_name(visitor);
705 }
706 }
707 }
708
709 impl $host_ty for syntax::FunctionDefinition {
710 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
711 where
712 V: $visitor_ty,
713 {
714 let visit = visitor.visit_function_definition(self);
715
716 if visit == Visit::Children {
717 self.prototype.$mthd_name(visitor);
718 self.statement.$mthd_name(visitor);
719 }
720 }
721 }
722
723 impl $host_ty for syntax::Declaration {
724 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
725 where
726 V: $visitor_ty,
727 {
728 let visit = visitor.visit_declaration(self);
729
730 if visit == Visit::Children {
731 match self {
732 syntax::Declaration::FunctionPrototype(fp) => fp.$mthd_name(visitor),
733
734 syntax::Declaration::InitDeclaratorList(idl) => idl.$mthd_name(visitor),
735
736 syntax::Declaration::Precision(pq, ty) => {
737 pq.$mthd_name(visitor);
738 ty.$mthd_name(visitor);
739 }
740
741 syntax::Declaration::Block(block) => block.$mthd_name(visitor),
742
743 syntax::Declaration::Global(tq, idents) => {
744 tq.$mthd_name(visitor);
745
746 for ident in idents {
747 ident.$mthd_name(visitor);
748 }
749 }
750 }
751 }
752 }
753 }
754
755 impl $host_ty for syntax::Block {
756 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
757 where
758 V: $visitor_ty,
759 {
760 let visit = visitor.visit_block(self);
761
762 if visit == Visit::Children {
763 self.qualifier.$mthd_name(visitor);
764 self.name.$mthd_name(visitor);
765
766 for field in $($ref)* self.fields {
767 field.$mthd_name(visitor);
768 }
769
770 self.identifier.$mthd_name(visitor);
771 }
772 }
773 }
774
775 impl $host_ty for syntax::InitDeclaratorList {
776 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
777 where
778 V: $visitor_ty,
779 {
780 let visit = visitor.visit_init_declarator_list(self);
781
782 if visit == Visit::Children {
783 self.head.$mthd_name(visitor);
784
785 for d in $($ref)* self.tail {
786 d.$mthd_name(visitor);
787 }
788 }
789 }
790 }
791
792 impl $host_ty for syntax::SingleDeclaration {
793 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
794 where
795 V: $visitor_ty,
796 {
797 let visit = visitor.visit_single_declaration(self);
798
799 if visit == Visit::Children {
800 self.ty.$mthd_name(visitor);
801 self.name.$mthd_name(visitor);
802 self.array_specifier.$mthd_name(visitor);
803 self.initializer.$mthd_name(visitor);
804 }
805 }
806 }
807
808 impl $host_ty for syntax::SingleDeclarationNoType {
809 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
810 where
811 V: $visitor_ty,
812 {
813 let visit = visitor.visit_single_declaration_no_type(self);
814
815 if visit == Visit::Children {
816 self.ident.$mthd_name(visitor);
817 self.initializer.$mthd_name(visitor);
818 }
819 }
820 }
821
822 impl $host_ty for syntax::FullySpecifiedType {
823 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
824 where
825 V: $visitor_ty,
826 {
827 let visit = visitor.visit_full_specified_type(self);
828
829 if visit == Visit::Children {
830 self.qualifier.$mthd_name(visitor);
831 self.ty.$mthd_name(visitor);
832 }
833 }
834 }
835
836 impl $host_ty for syntax::TypeSpecifier {
837 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
838 where
839 V: $visitor_ty,
840 {
841 let visit = visitor.visit_type_specifier(self);
842
843 if visit == Visit::Children {
844 self.ty.$mthd_name(visitor);
845 self.array_specifier.$mthd_name(visitor);
846 }
847 }
848 }
849
850 impl $host_ty for syntax::TypeSpecifierNonArray {
851 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
852 where
853 V: $visitor_ty,
854 {
855 let visit = visitor.visit_type_specifier_non_array(self);
856
857 if visit == Visit::Children {
858 match self {
859 syntax::TypeSpecifierNonArray::Struct(ss) => ss.$mthd_name(visitor),
860 syntax::TypeSpecifierNonArray::TypeName(tn) => tn.$mthd_name(visitor),
861 _ => (),
862 }
863 }
864 }
865 }
866
867 impl $host_ty for syntax::TypeQualifier {
868 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
869 where
870 V: $visitor_ty,
871 {
872 let visit = visitor.visit_type_qualifier(self);
873
874 if visit == Visit::Children {
875 for tqs in $($ref)* self.qualifiers.0 {
876 tqs.$mthd_name(visitor);
877 }
878 }
879 }
880 }
881
882 impl $host_ty for syntax::TypeQualifierSpec {
883 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
884 where
885 V: $visitor_ty,
886 {
887 let visit = visitor.visit_type_qualifier_spec(self);
888
889 if visit == Visit::Children {
890 match self {
891 syntax::TypeQualifierSpec::Storage(sq) => sq.$mthd_name(visitor),
892 syntax::TypeQualifierSpec::Layout(lq) => lq.$mthd_name(visitor),
893 syntax::TypeQualifierSpec::Precision(pq) => pq.$mthd_name(visitor),
894 syntax::TypeQualifierSpec::Interpolation(iq) => iq.$mthd_name(visitor),
895 _ => (),
896 }
897 }
898 }
899 }
900
901 impl $host_ty for syntax::StorageQualifier {
902 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
903 where
904 V: $visitor_ty,
905 {
906 let visit = visitor.visit_storage_qualifier(self);
907
908 if visit == Visit::Children {
909 if let syntax::StorageQualifier::Subroutine(names) = self {
910 for name in names {
911 name.$mthd_name(visitor);
912 }
913 }
914 }
915 }
916 }
917
918 impl $host_ty for syntax::LayoutQualifier {
919 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
920 where
921 V: $visitor_ty,
922 {
923 let visit = visitor.visit_layout_qualifier(self);
924
925 if visit == Visit::Children {
926 for lqs in $($ref)* self.ids.0 {
927 lqs.$mthd_name(visitor);
928 }
929 }
930 }
931 }
932
933 impl $host_ty for syntax::LayoutQualifierSpec {
934 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
935 where
936 V: $visitor_ty,
937 {
938 let visit = visitor.visit_layout_qualifier_spec(self);
939
940 if visit == Visit::Children {
941 if let syntax::LayoutQualifierSpec::Identifier(ident, expr) = self {
942 ident.$mthd_name(visitor);
943
944 if let Some(e) = expr {
945 e.$mthd_name(visitor);
946 }
947 }
948 }
949 }
950 }
951
952 impl $host_ty for syntax::PrecisionQualifier {
953 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
954 where
955 V: $visitor_ty,
956 {
957 let _ = visitor.visit_precision_qualifier(self);
958 }
959 }
960
961 impl $host_ty for syntax::InterpolationQualifier {
962 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
963 where
964 V: $visitor_ty,
965 {
966 let _ = visitor.visit_interpolation_qualifier(self);
967 }
968 }
969
970 impl $host_ty for syntax::TypeName {
971 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
972 where
973 V: $visitor_ty,
974 {
975 let _ = visitor.visit_type_name(self);
976 }
977 }
978
979 impl $host_ty for syntax::Identifier {
980 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
981 where
982 V: $visitor_ty,
983 {
984 let _ = visitor.visit_identifier(self);
985 }
986 }
987
988 impl $host_ty for syntax::ArrayedIdentifier {
989 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
990 where
991 V: $visitor_ty,
992 {
993 let visit = visitor.visit_arrayed_identifier(self);
994
995 if visit == Visit::Children {
996 self.ident.$mthd_name(visitor);
997 self.array_spec.$mthd_name(visitor);
998 }
999 }
1000 }
1001
1002 impl $host_ty for syntax::Expr {
1003 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1004 where
1005 V: $visitor_ty,
1006 {
1007 let visit = visitor.visit_expr(self);
1008
1009 if visit == Visit::Children {
1010 match self {
1011 syntax::Expr::Variable(ident) => ident.$mthd_name(visitor),
1012
1013 syntax::Expr::Unary(op, e) => {
1014 op.$mthd_name(visitor);
1015 e.$mthd_name(visitor);
1016 }
1017
1018 syntax::Expr::Binary(op, a, b) => {
1019 op.$mthd_name(visitor);
1020 a.$mthd_name(visitor);
1021 b.$mthd_name(visitor);
1022 }
1023
1024 syntax::Expr::Ternary(a, b, c) => {
1025 a.$mthd_name(visitor);
1026 b.$mthd_name(visitor);
1027 c.$mthd_name(visitor);
1028 }
1029
1030 syntax::Expr::Assignment(lhs, op, rhs) => {
1031 lhs.$mthd_name(visitor);
1032 op.$mthd_name(visitor);
1033 rhs.$mthd_name(visitor);
1034 }
1035
1036 syntax::Expr::Bracket(e, arr_spec) => {
1037 e.$mthd_name(visitor);
1038 arr_spec.$mthd_name(visitor);
1039 }
1040
1041 syntax::Expr::FunCall(fi, params) => {
1042 fi.$mthd_name(visitor);
1043
1044 for param in params {
1045 param.$mthd_name(visitor);
1046 }
1047 }
1048
1049 syntax::Expr::Dot(e, i) => {
1050 e.$mthd_name(visitor);
1051 i.$mthd_name(visitor);
1052 }
1053
1054 syntax::Expr::PostInc(e) => e.$mthd_name(visitor),
1055
1056 syntax::Expr::PostDec(e) => e.$mthd_name(visitor),
1057
1058 syntax::Expr::Comma(a, b) => {
1059 a.$mthd_name(visitor);
1060 b.$mthd_name(visitor);
1061 }
1062
1063 _ => (),
1064 }
1065 }
1066 }
1067 }
1068
1069 impl $host_ty for syntax::UnaryOp {
1070 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1071 where
1072 V: $visitor_ty,
1073 {
1074 let _ = visitor.visit_unary_op(self);
1075 }
1076 }
1077
1078 impl $host_ty for syntax::BinaryOp {
1079 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1080 where
1081 V: $visitor_ty,
1082 {
1083 let _ = visitor.visit_binary_op(self);
1084 }
1085 }
1086
1087 impl $host_ty for syntax::AssignmentOp {
1088 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1089 where
1090 V: $visitor_ty,
1091 {
1092 let _ = visitor.visit_assignment_op(self);
1093 }
1094 }
1095
1096 impl $host_ty for syntax::ArraySpecifier {
1097 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1098 where
1099 V: $visitor_ty,
1100 {
1101 let visit = visitor.visit_array_specifier(self);
1102
1103 if visit == Visit::Children {
1104 for dimension in $($ref)* self.dimensions {
1105 dimension.$mthd_name(visitor);
1106 }
1107 }
1108 }
1109 }
1110
1111 impl $host_ty for syntax::ArraySpecifierDimension {
1112 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1113 where
1114 V: $visitor_ty,
1115 {
1116 let visit = visitor.visit_array_specifier_dimension(self);
1117
1118 if visit == Visit::Children {
1119 if let syntax::ArraySpecifierDimension::ExplicitlySized(e) = self {
1120 e.$mthd_name(visitor);
1121 }
1122 }
1123 }
1124 }
1125
1126 impl $host_ty for syntax::FunIdentifier {
1127 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1128 where
1129 V: $visitor_ty,
1130 {
1131 let visit = visitor.visit_fun_identifier(self);
1132
1133 if visit == Visit::Children {
1134 match self {
1135 syntax::FunIdentifier::Identifier(i) => i.$mthd_name(visitor),
1136 syntax::FunIdentifier::Expr(e) => e.$mthd_name(visitor),
1137 }
1138 }
1139 }
1140 }
1141
1142 impl $host_ty for syntax::StructSpecifier {
1143 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1144 where
1145 V: $visitor_ty,
1146 {
1147 let visit = visitor.visit_struct_specifier(self);
1148
1149 if visit == Visit::Children {
1150 self.name.$mthd_name(visitor);
1151
1152 for field in $($ref)* self.fields.0 {
1153 field.$mthd_name(visitor);
1154 }
1155 }
1156 }
1157 }
1158
1159 impl $host_ty for syntax::StructFieldSpecifier {
1160 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1161 where
1162 V: $visitor_ty,
1163 {
1164 let visit = visitor.visit_struct_field_specifier(self);
1165
1166 if visit == Visit::Children {
1167 self.qualifier.$mthd_name(visitor);
1168 self.ty.$mthd_name(visitor);
1169
1170 for identifier in $($ref)* self.identifiers.0 {
1171 identifier.$mthd_name(visitor);
1172 }
1173 }
1174 }
1175 }
1176
1177 impl $host_ty for syntax::Statement {
1178 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1179 where
1180 V: $visitor_ty,
1181 {
1182 let visit = visitor.visit_statement(self);
1183
1184 if visit == Visit::Children {
1185 match self {
1186 syntax::Statement::Compound(cs) => cs.$mthd_name(visitor),
1187 syntax::Statement::Simple(ss) => ss.$mthd_name(visitor),
1188 }
1189 }
1190 }
1191 }
1192
1193 impl $host_ty for syntax::SimpleStatement {
1194 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1195 where
1196 V: $visitor_ty,
1197 {
1198 let visit = visitor.visit_simple_statement(self);
1199
1200 if visit == Visit::Children {
1201 match self {
1202 syntax::SimpleStatement::Declaration(d) => d.$mthd_name(visitor),
1203 syntax::SimpleStatement::Expression(e) => e.$mthd_name(visitor),
1204 syntax::SimpleStatement::Selection(s) => s.$mthd_name(visitor),
1205 syntax::SimpleStatement::Switch(s) => s.$mthd_name(visitor),
1206 syntax::SimpleStatement::CaseLabel(cl) => cl.$mthd_name(visitor),
1207 syntax::SimpleStatement::Iteration(i) => i.$mthd_name(visitor),
1208 syntax::SimpleStatement::Jump(j) => j.$mthd_name(visitor),
1209 }
1210 }
1211 }
1212 }
1213
1214 impl $host_ty for syntax::CompoundStatement {
1215 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1216 where
1217 V: $visitor_ty,
1218 {
1219 let visit = visitor.visit_compound_statement(self);
1220
1221 if visit == Visit::Children {
1222 for stmt in $($ref)* self.statement_list {
1223 stmt.$mthd_name(visitor);
1224 }
1225 }
1226 }
1227 }
1228
1229 impl $host_ty for syntax::SelectionStatement {
1230 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1231 where
1232 V: $visitor_ty,
1233 {
1234 let visit = visitor.visit_selection_statement(self);
1235
1236 if visit == Visit::Children {
1237 self.cond.$mthd_name(visitor);
1238 self.rest.$mthd_name(visitor);
1239 }
1240 }
1241 }
1242
1243 impl $host_ty for syntax::SelectionRestStatement {
1244 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1245 where
1246 V: $visitor_ty,
1247 {
1248 let visit = visitor.visit_selection_rest_statement(self);
1249
1250 if visit == Visit::Children {
1251 match self {
1252 syntax::SelectionRestStatement::Statement(s) => s.$mthd_name(visitor),
1253
1254 syntax::SelectionRestStatement::Else(a, b) => {
1255 a.$mthd_name(visitor);
1256 b.$mthd_name(visitor);
1257 }
1258 }
1259 }
1260 }
1261 }
1262
1263 impl $host_ty for syntax::SwitchStatement {
1264 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1265 where
1266 V: $visitor_ty,
1267 {
1268 let visit = visitor.visit_switch_statement(self);
1269
1270 if visit == Visit::Children {
1271 self.head.$mthd_name(visitor);
1272
1273 for s in $($ref)* self.body {
1274 s.$mthd_name(visitor);
1275 }
1276 }
1277 }
1278 }
1279
1280 impl $host_ty for syntax::CaseLabel {
1281 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1282 where
1283 V: $visitor_ty,
1284 {
1285 let visit = visitor.visit_case_label(self);
1286
1287 if visit == Visit::Children {
1288 if let syntax::CaseLabel::Case(e) = self {
1289 e.$mthd_name(visitor);
1290 }
1291 }
1292 }
1293 }
1294
1295 impl $host_ty for syntax::IterationStatement {
1296 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1297 where
1298 V: $visitor_ty,
1299 {
1300 let visit = visitor.visit_iteration_statement(self);
1301
1302 if visit == Visit::Children {
1303 match self {
1304 syntax::IterationStatement::While(c, s) => {
1305 c.$mthd_name(visitor);
1306 s.$mthd_name(visitor);
1307 }
1308
1309 syntax::IterationStatement::DoWhile(s, e) => {
1310 s.$mthd_name(visitor);
1311 e.$mthd_name(visitor);
1312 }
1313
1314 syntax::IterationStatement::For(fis, frs, s) => {
1315 fis.$mthd_name(visitor);
1316 frs.$mthd_name(visitor);
1317 s.$mthd_name(visitor);
1318 }
1319 }
1320 }
1321 }
1322 }
1323
1324 impl $host_ty for syntax::ForInitStatement {
1325 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1326 where
1327 V: $visitor_ty,
1328 {
1329 let visit = visitor.visit_for_init_statement(self);
1330
1331 if visit == Visit::Children {
1332 match self {
1333 syntax::ForInitStatement::Expression(e) => e.$mthd_name(visitor),
1334 syntax::ForInitStatement::Declaration(d) => d.$mthd_name(visitor),
1335 }
1336 }
1337 }
1338 }
1339
1340 impl $host_ty for syntax::ForRestStatement {
1341 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1342 where
1343 V: $visitor_ty,
1344 {
1345 let visit = visitor.visit_for_rest_statement(self);
1346
1347 if visit == Visit::Children {
1348 self.condition.$mthd_name(visitor);
1349 self.post_expr.$mthd_name(visitor);
1350 }
1351 }
1352 }
1353
1354 impl $host_ty for syntax::JumpStatement {
1355 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1356 where
1357 V: $visitor_ty,
1358 {
1359 let visit = visitor.visit_jump_statement(self);
1360
1361 if visit == Visit::Children {
1362 if let syntax::JumpStatement::Return(r) = self {
1363 r.$mthd_name(visitor);
1364 }
1365 }
1366 }
1367 }
1368
1369 impl $host_ty for syntax::Condition {
1370 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1371 where
1372 V: $visitor_ty,
1373 {
1374 let visit = visitor.visit_condition(self);
1375
1376 if visit == Visit::Children {
1377 match self {
1378 syntax::Condition::Expr(e) => e.$mthd_name(visitor),
1379
1380 syntax::Condition::Assignment(fst, ident, init) => {
1381 fst.$mthd_name(visitor);
1382 ident.$mthd_name(visitor);
1383 init.$mthd_name(visitor);
1384 }
1385 }
1386 }
1387 }
1388 }
1389
1390 impl $host_ty for syntax::Initializer {
1391 fn $mthd_name<V>($($ref)* self, visitor: &mut V)
1392 where
1393 V: $visitor_ty,
1394 {
1395 let visit = visitor.visit_initializer(self);
1396
1397 if visit == Visit::Children {
1398 match self {
1399 syntax::Initializer::Simple(e) => e.$mthd_name(visitor),
1400
1401 syntax::Initializer::List(i) => {
1402 for i in $($ref)* i.0 {
1403 i.$mthd_name(visitor);
1404 }
1405 }
1406 }
1407 }
1408 }
1409 }
1410 }
1411}
1412
1413make_visitor_trait!(Visitor, &);
1415make_host_trait!(Host, Visitor, visit, &);
1416
1417make_visitor_trait!(VisitorMut, &mut);
1419make_host_trait!(HostMut, VisitorMut, visit_mut, &mut);
1420
1421#[cfg(test)]
1422mod tests {
1423 use std::iter::FromIterator;
1424
1425 use super::*;
1426 use syntax;
1427
1428 #[test]
1429 fn count_variables() {
1430 let decl0 = syntax::Statement::declare_var(
1431 syntax::TypeSpecifierNonArray::Float,
1432 "x",
1433 None,
1434 Some(syntax::Expr::from(3.14).into()),
1435 );
1436
1437 let decl1 = syntax::Statement::declare_var(syntax::TypeSpecifierNonArray::Int, "y", None, None);
1438
1439 let decl2 =
1440 syntax::Statement::declare_var(syntax::TypeSpecifierNonArray::Vec4, "z", None, None);
1441
1442 let compound = syntax::CompoundStatement::from_iter(vec![decl0, decl1, decl2]);
1443
1444 struct Counter {
1446 var_nb: usize,
1447 }
1448
1449 impl Visitor for Counter {
1450 fn visit_single_declaration(&mut self, declaration: &syntax::SingleDeclaration) -> Visit {
1452 if declaration.name.is_some() {
1453 self.var_nb += 1;
1454 }
1455
1456 Visit::Parent
1458 }
1459 }
1460
1461 let mut counter = Counter { var_nb: 0 };
1462 compound.visit(&mut counter);
1463 assert_eq!(counter.var_nb, 3);
1464 }
1465}