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