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