]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / include / clang / AST / ASTNodeTraverser.h
1 //===--- ASTNodeTraverser.h - Traversal of AST nodes ----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the AST traversal facilities.  Other users
10 // of this class may make use of the same traversal logic by inheriting it,
11 // similar to RecursiveASTVisitor.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H
16 #define LLVM_CLANG_AST_ASTNODETRAVERSER_H
17
18 #include "clang/AST/AttrVisitor.h"
19 #include "clang/AST/CommentVisitor.h"
20 #include "clang/AST/DeclVisitor.h"
21 #include "clang/AST/LocInfoType.h"
22 #include "clang/AST/StmtVisitor.h"
23 #include "clang/AST/TemplateArgumentVisitor.h"
24 #include "clang/AST/TypeVisitor.h"
25
26 namespace clang {
27
28 /**
29
30 ASTNodeTraverser traverses the Clang AST for dumping purposes.
31
32 The `Derived::doGetNodeDelegate()` method is required to be an accessible member
33 which returns a reference of type `NodeDelegateType &` which implements the
34 following interface:
35
36 struct {
37   template <typename Fn> void AddChild(Fn DoAddChild);
38   template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild);
39
40   void Visit(const comments::Comment *C, const comments::FullComment *FC);
41   void Visit(const Attr *A);
42   void Visit(const TemplateArgument &TA, SourceRange R = {},
43              const Decl *From = nullptr, StringRef Label = {});
44   void Visit(const Stmt *Node);
45   void Visit(const Type *T);
46   void Visit(QualType T);
47   void Visit(const Decl *D);
48   void Visit(const CXXCtorInitializer *Init);
49   void Visit(const OMPClause *C);
50   void Visit(const BlockDecl::Capture &C);
51   void Visit(const GenericSelectionExpr::ConstAssociation &A);
52 };
53 */
54 template <typename Derived, typename NodeDelegateType>
55 class ASTNodeTraverser
56     : public ConstDeclVisitor<Derived>,
57       public ConstStmtVisitor<Derived>,
58       public comments::ConstCommentVisitor<Derived, void,
59                                            const comments::FullComment *>,
60       public TypeVisitor<Derived>,
61       public ConstAttrVisitor<Derived>,
62       public ConstTemplateArgumentVisitor<Derived> {
63
64   /// Indicates whether we should trigger deserialization of nodes that had
65   /// not already been loaded.
66   bool Deserialize = false;
67
68   ast_type_traits::TraversalKind Traversal =
69       ast_type_traits::TraversalKind::TK_AsIs;
70
71   NodeDelegateType &getNodeDelegate() {
72     return getDerived().doGetNodeDelegate();
73   }
74   Derived &getDerived() { return *static_cast<Derived *>(this); }
75
76 public:
77   void setDeserialize(bool D) { Deserialize = D; }
78   bool getDeserialize() const { return Deserialize; }
79
80   void SetTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; }
81
82   void Visit(const Decl *D) {
83     getNodeDelegate().AddChild([=] {
84       getNodeDelegate().Visit(D);
85       if (!D)
86         return;
87
88       ConstDeclVisitor<Derived>::Visit(D);
89
90       for (const auto &A : D->attrs())
91         Visit(A);
92
93       if (const comments::FullComment *Comment =
94               D->getASTContext().getLocalCommentForDeclUncached(D))
95         Visit(Comment, Comment);
96
97       // Decls within functions are visited by the body.
98       if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
99         if (const auto *DC = dyn_cast<DeclContext>(D))
100           dumpDeclContext(DC);
101       }
102     });
103   }
104
105   void Visit(const Stmt *Node, StringRef Label = {}) {
106     getNodeDelegate().AddChild(Label, [=] {
107       const Stmt *S = Node;
108
109       if (auto *E = dyn_cast_or_null<Expr>(S)) {
110         switch (Traversal) {
111         case ast_type_traits::TK_AsIs:
112           break;
113         case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses:
114           S = E->IgnoreParenImpCasts();
115           break;
116         case ast_type_traits::TK_IgnoreUnlessSpelledInSource:
117           S = E->IgnoreUnlessSpelledInSource();
118           break;
119         }
120       }
121
122       getNodeDelegate().Visit(S);
123
124       if (!S) {
125         return;
126       }
127
128       ConstStmtVisitor<Derived>::Visit(S);
129
130       // Some statements have custom mechanisms for dumping their children.
131       if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S))
132         return;
133
134       if (isa<LambdaExpr>(S) &&
135           Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource)
136         return;
137
138       for (const Stmt *SubStmt : S->children())
139         Visit(SubStmt);
140     });
141   }
142
143   void Visit(QualType T) {
144     SplitQualType SQT = T.split();
145     if (!SQT.Quals.hasQualifiers())
146       return Visit(SQT.Ty);
147
148     getNodeDelegate().AddChild([=] {
149       getNodeDelegate().Visit(T);
150       Visit(T.split().Ty);
151     });
152   }
153
154   void Visit(const Type *T) {
155     getNodeDelegate().AddChild([=] {
156       getNodeDelegate().Visit(T);
157       if (!T)
158         return;
159       TypeVisitor<Derived>::Visit(T);
160
161       QualType SingleStepDesugar =
162           T->getLocallyUnqualifiedSingleStepDesugaredType();
163       if (SingleStepDesugar != QualType(T, 0))
164         Visit(SingleStepDesugar);
165     });
166   }
167
168   void Visit(const Attr *A) {
169     getNodeDelegate().AddChild([=] {
170       getNodeDelegate().Visit(A);
171       ConstAttrVisitor<Derived>::Visit(A);
172     });
173   }
174
175   void Visit(const CXXCtorInitializer *Init) {
176     getNodeDelegate().AddChild([=] {
177       getNodeDelegate().Visit(Init);
178       Visit(Init->getInit());
179     });
180   }
181
182   void Visit(const TemplateArgument &A, SourceRange R = {},
183              const Decl *From = nullptr, const char *Label = nullptr) {
184     getNodeDelegate().AddChild([=] {
185       getNodeDelegate().Visit(A, R, From, Label);
186       ConstTemplateArgumentVisitor<Derived>::Visit(A);
187     });
188   }
189
190   void Visit(const BlockDecl::Capture &C) {
191     getNodeDelegate().AddChild([=] {
192       getNodeDelegate().Visit(C);
193       if (C.hasCopyExpr())
194         Visit(C.getCopyExpr());
195     });
196   }
197
198   void Visit(const OMPClause *C) {
199     getNodeDelegate().AddChild([=] {
200       getNodeDelegate().Visit(C);
201       for (const auto *S : C->children())
202         Visit(S);
203     });
204   }
205
206   void Visit(const GenericSelectionExpr::ConstAssociation &A) {
207     getNodeDelegate().AddChild([=] {
208       getNodeDelegate().Visit(A);
209       if (const TypeSourceInfo *TSI = A.getTypeSourceInfo())
210         Visit(TSI->getType());
211       Visit(A.getAssociationExpr());
212     });
213   }
214
215   void Visit(const comments::Comment *C, const comments::FullComment *FC) {
216     getNodeDelegate().AddChild([=] {
217       getNodeDelegate().Visit(C, FC);
218       if (!C) {
219         return;
220       }
221       comments::ConstCommentVisitor<Derived, void,
222                                     const comments::FullComment *>::visit(C,
223                                                                           FC);
224       for (comments::Comment::child_iterator I = C->child_begin(),
225                                              E = C->child_end();
226            I != E; ++I)
227         Visit(*I, FC);
228     });
229   }
230
231   void Visit(const ast_type_traits::DynTypedNode &N) {
232     // FIXME: Improve this with a switch or a visitor pattern.
233     if (const auto *D = N.get<Decl>())
234       Visit(D);
235     else if (const auto *S = N.get<Stmt>())
236       Visit(S);
237     else if (const auto *QT = N.get<QualType>())
238       Visit(*QT);
239     else if (const auto *T = N.get<Type>())
240       Visit(T);
241     else if (const auto *C = N.get<CXXCtorInitializer>())
242       Visit(C);
243     else if (const auto *C = N.get<OMPClause>())
244       Visit(C);
245     else if (const auto *T = N.get<TemplateArgument>())
246       Visit(*T);
247   }
248
249   void dumpDeclContext(const DeclContext *DC) {
250     if (!DC)
251       return;
252
253     for (const auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
254       Visit(D);
255   }
256
257   void dumpTemplateParameters(const TemplateParameterList *TPL) {
258     if (!TPL)
259       return;
260
261     for (const auto &TP : *TPL)
262       Visit(TP);
263
264     if (const Expr *RC = TPL->getRequiresClause())
265       Visit(RC);
266   }
267
268   void
269   dumpASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *TALI) {
270     if (!TALI)
271       return;
272
273     for (const auto &TA : TALI->arguments())
274       dumpTemplateArgumentLoc(TA);
275   }
276
277   void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
278                                const Decl *From = nullptr,
279                                const char *Label = nullptr) {
280     Visit(A.getArgument(), A.getSourceRange(), From, Label);
281   }
282
283   void dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
284     for (unsigned i = 0, e = TAL.size(); i < e; ++i)
285       Visit(TAL[i]);
286   }
287
288   void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
289     if (!typeParams)
290       return;
291
292     for (const auto &typeParam : *typeParams) {
293       Visit(typeParam);
294     }
295   }
296
297   void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); }
298   void VisitLocInfoType(const LocInfoType *T) {
299     Visit(T->getTypeSourceInfo()->getType());
300   }
301   void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); }
302   void VisitBlockPointerType(const BlockPointerType *T) {
303     Visit(T->getPointeeType());
304   }
305   void VisitReferenceType(const ReferenceType *T) {
306     Visit(T->getPointeeType());
307   }
308   void VisitMemberPointerType(const MemberPointerType *T) {
309     Visit(T->getClass());
310     Visit(T->getPointeeType());
311   }
312   void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
313   void VisitVariableArrayType(const VariableArrayType *T) {
314     VisitArrayType(T);
315     Visit(T->getSizeExpr());
316   }
317   void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
318     Visit(T->getElementType());
319     Visit(T->getSizeExpr());
320   }
321   void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
322     Visit(T->getElementType());
323     Visit(T->getSizeExpr());
324   }
325   void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); }
326   void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); }
327   void VisitFunctionProtoType(const FunctionProtoType *T) {
328     VisitFunctionType(T);
329     for (const QualType &PT : T->getParamTypes())
330       Visit(PT);
331   }
332   void VisitTypeOfExprType(const TypeOfExprType *T) {
333     Visit(T->getUnderlyingExpr());
334   }
335   void VisitDecltypeType(const DecltypeType *T) {
336     Visit(T->getUnderlyingExpr());
337   }
338   void VisitUnaryTransformType(const UnaryTransformType *T) {
339     Visit(T->getBaseType());
340   }
341   void VisitAttributedType(const AttributedType *T) {
342     // FIXME: AttrKind
343     Visit(T->getModifiedType());
344   }
345   void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
346     Visit(T->getReplacedParameter());
347   }
348   void
349   VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
350     Visit(T->getReplacedParameter());
351     Visit(T->getArgumentPack());
352   }
353   void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
354     for (const auto &Arg : *T)
355       Visit(Arg);
356     if (T->isTypeAlias())
357       Visit(T->getAliasedType());
358   }
359   void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
360     Visit(T->getPointeeType());
361   }
362   void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); }
363   void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); }
364   void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); }
365   void VisitPackExpansionType(const PackExpansionType *T) {
366     if (!T->isSugared())
367       Visit(T->getPattern());
368   }
369   // FIXME: ElaboratedType, DependentNameType,
370   // DependentTemplateSpecializationType, ObjCObjectType
371
372   void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }
373
374   void VisitEnumConstantDecl(const EnumConstantDecl *D) {
375     if (const Expr *Init = D->getInitExpr())
376       Visit(Init);
377   }
378
379   void VisitFunctionDecl(const FunctionDecl *D) {
380     if (const auto *FTSI = D->getTemplateSpecializationInfo())
381       dumpTemplateArgumentList(*FTSI->TemplateArguments);
382
383     if (D->param_begin())
384       for (const auto *Parameter : D->parameters())
385         Visit(Parameter);
386
387     if (const Expr *TRC = D->getTrailingRequiresClause())
388       Visit(TRC);
389
390     if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
391       for (const auto *I : C->inits())
392         Visit(I);
393
394     if (D->doesThisDeclarationHaveABody())
395       Visit(D->getBody());
396   }
397
398   void VisitFieldDecl(const FieldDecl *D) {
399     if (D->isBitField())
400       Visit(D->getBitWidth());
401     if (Expr *Init = D->getInClassInitializer())
402       Visit(Init);
403   }
404
405   void VisitVarDecl(const VarDecl *D) {
406     if (D->hasInit())
407       Visit(D->getInit());
408   }
409
410   void VisitDecompositionDecl(const DecompositionDecl *D) {
411     VisitVarDecl(D);
412     for (const auto *B : D->bindings())
413       Visit(B);
414   }
415
416   void VisitBindingDecl(const BindingDecl *D) {
417     if (const auto *E = D->getBinding())
418       Visit(E);
419   }
420
421   void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
422     Visit(D->getAsmString());
423   }
424
425   void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }
426
427   void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
428     for (const auto *E : D->varlists())
429       Visit(E);
430   }
431
432   void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
433     Visit(D->getCombiner());
434     if (const auto *Initializer = D->getInitializer())
435       Visit(Initializer);
436   }
437
438   void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {
439     for (const auto *C : D->clauselists())
440       Visit(C);
441   }
442
443   void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
444     Visit(D->getInit());
445   }
446
447   void VisitOMPAllocateDecl(const OMPAllocateDecl *D) {
448     for (const auto *E : D->varlists())
449       Visit(E);
450     for (const auto *C : D->clauselists())
451       Visit(C);
452   }
453
454   template <typename SpecializationDecl>
455   void dumpTemplateDeclSpecialization(const SpecializationDecl *D) {
456     for (const auto *RedeclWithBadType : D->redecls()) {
457       // FIXME: The redecls() range sometimes has elements of a less-specific
458       // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
459       // us TagDecls, and should give CXXRecordDecls).
460       auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
461       if (!Redecl) {
462         // Found the injected-class-name for a class template. This will be
463         // dumped as part of its surrounding class so we don't need to dump it
464         // here.
465         assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
466                "expected an injected-class-name");
467         continue;
468       }
469       Visit(Redecl);
470     }
471   }
472
473   template <typename TemplateDecl>
474   void dumpTemplateDecl(const TemplateDecl *D) {
475     dumpTemplateParameters(D->getTemplateParameters());
476
477     Visit(D->getTemplatedDecl());
478
479     for (const auto *Child : D->specializations())
480       dumpTemplateDeclSpecialization(Child);
481   }
482
483   void VisitTypeAliasDecl(const TypeAliasDecl *D) {
484     Visit(D->getUnderlyingType());
485   }
486
487   void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
488     dumpTemplateParameters(D->getTemplateParameters());
489     Visit(D->getTemplatedDecl());
490   }
491
492   void VisitStaticAssertDecl(const StaticAssertDecl *D) {
493     Visit(D->getAssertExpr());
494     Visit(D->getMessage());
495   }
496
497   void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
498     dumpTemplateDecl(D);
499   }
500
501   void VisitClassTemplateDecl(const ClassTemplateDecl *D) {
502     dumpTemplateDecl(D);
503   }
504
505   void VisitClassTemplateSpecializationDecl(
506       const ClassTemplateSpecializationDecl *D) {
507     dumpTemplateArgumentList(D->getTemplateArgs());
508   }
509
510   void VisitClassTemplatePartialSpecializationDecl(
511       const ClassTemplatePartialSpecializationDecl *D) {
512     VisitClassTemplateSpecializationDecl(D);
513     dumpTemplateParameters(D->getTemplateParameters());
514   }
515
516   void VisitClassScopeFunctionSpecializationDecl(
517       const ClassScopeFunctionSpecializationDecl *D) {
518     Visit(D->getSpecialization());
519     dumpASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
520   }
521   void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); }
522
523   void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
524     dumpTemplateParameters(D->getTemplateParameters());
525   }
526
527   void
528   VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) {
529     dumpTemplateArgumentList(D->getTemplateArgs());
530     VisitVarDecl(D);
531   }
532
533   void VisitVarTemplatePartialSpecializationDecl(
534       const VarTemplatePartialSpecializationDecl *D) {
535     dumpTemplateParameters(D->getTemplateParameters());
536     VisitVarTemplateSpecializationDecl(D);
537   }
538
539   void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
540     if (const auto *TC = D->getTypeConstraint())
541       if (TC->hasExplicitTemplateArgs())
542         for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
543           dumpTemplateArgumentLoc(ArgLoc);
544     if (D->hasDefaultArgument())
545       Visit(D->getDefaultArgument(), SourceRange(),
546             D->getDefaultArgStorage().getInheritedFrom(),
547             D->defaultArgumentWasInherited() ? "inherited from" : "previous");
548   }
549
550   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
551     if (const auto *E = D->getPlaceholderTypeConstraint())
552       Visit(E);
553     if (D->hasDefaultArgument())
554       Visit(D->getDefaultArgument(), SourceRange(),
555             D->getDefaultArgStorage().getInheritedFrom(),
556             D->defaultArgumentWasInherited() ? "inherited from" : "previous");
557   }
558
559   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
560     dumpTemplateParameters(D->getTemplateParameters());
561     if (D->hasDefaultArgument())
562       dumpTemplateArgumentLoc(
563           D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
564           D->defaultArgumentWasInherited() ? "inherited from" : "previous");
565   }
566
567   void VisitConceptDecl(const ConceptDecl *D) {
568     dumpTemplateParameters(D->getTemplateParameters());
569     Visit(D->getConstraintExpr());
570   }
571
572   void VisitUsingShadowDecl(const UsingShadowDecl *D) {
573     if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
574       Visit(TD->getTypeForDecl());
575   }
576
577   void VisitFriendDecl(const FriendDecl *D) {
578     if (!D->getFriendType())
579       Visit(D->getFriendDecl());
580   }
581
582   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
583     if (D->isThisDeclarationADefinition())
584       dumpDeclContext(D);
585     else
586       for (const ParmVarDecl *Parameter : D->parameters())
587         Visit(Parameter);
588
589     if (D->hasBody())
590       Visit(D->getBody());
591   }
592
593   void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
594     dumpObjCTypeParamList(D->getTypeParamList());
595   }
596
597   void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
598     dumpObjCTypeParamList(D->getTypeParamListAsWritten());
599   }
600
601   void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
602     for (const auto &I : D->inits())
603       Visit(I);
604   }
605
606   void VisitBlockDecl(const BlockDecl *D) {
607     for (const auto &I : D->parameters())
608       Visit(I);
609
610     for (const auto &I : D->captures())
611       Visit(I);
612     Visit(D->getBody());
613   }
614
615   void VisitDeclStmt(const DeclStmt *Node) {
616     for (const auto &D : Node->decls())
617       Visit(D);
618   }
619
620   void VisitAttributedStmt(const AttributedStmt *Node) {
621     for (const auto *A : Node->getAttrs())
622       Visit(A);
623   }
624
625   void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
626     Visit(Node->getExceptionDecl());
627   }
628
629   void VisitCapturedStmt(const CapturedStmt *Node) {
630     Visit(Node->getCapturedDecl());
631   }
632
633   void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) {
634     for (const auto *C : Node->clauses())
635       Visit(C);
636   }
637
638   void VisitInitListExpr(const InitListExpr *ILE) {
639     if (auto *Filler = ILE->getArrayFiller()) {
640       Visit(Filler, "array_filler");
641     }
642   }
643
644   void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
645
646   void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
647     if (Expr *Source = Node->getSourceExpr())
648       Visit(Source);
649   }
650
651   void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
652     Visit(E->getControllingExpr());
653     Visit(E->getControllingExpr()->getType()); // FIXME: remove
654
655     for (const auto Assoc : E->associations()) {
656       Visit(Assoc);
657     }
658   }
659
660   void VisitLambdaExpr(const LambdaExpr *Node) {
661     if (Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource) {
662       for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) {
663         const auto *C = Node->capture_begin() + I;
664         if (!C->isExplicit())
665           continue;
666         if (Node->isInitCapture(C))
667           Visit(C->getCapturedVar());
668         else
669           Visit(Node->capture_init_begin()[I]);
670       }
671       dumpTemplateParameters(Node->getTemplateParameterList());
672       for (const auto *P : Node->getCallOperator()->parameters())
673         Visit(P);
674       Visit(Node->getBody());
675     } else {
676       return Visit(Node->getLambdaClass());
677     }
678   }
679
680   void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
681     if (Node->isPartiallySubstituted())
682       for (const auto &A : Node->getPartialArguments())
683         Visit(A);
684   }
685
686   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
687     if (const VarDecl *CatchParam = Node->getCatchParamDecl())
688       Visit(CatchParam);
689   }
690
691   void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
692     Visit(TA.getAsExpr());
693   }
694   void VisitPackTemplateArgument(const TemplateArgument &TA) {
695     for (const auto &TArg : TA.pack_elements())
696       Visit(TArg);
697   }
698
699   // Implements Visit methods for Attrs.
700 #include "clang/AST/AttrNodeTraverse.inc"
701 };
702
703 } // namespace clang
704
705 #endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H