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