xref: /freebsd/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 && 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, GenericSelectionExpr, RequiresExpr,
162               OpenACCWaitConstruct, SYCLKernelCallStmt>(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     // FIXME: Provide a NestedNameSpecifier visitor.
397     NestedNameSpecifier *Qualifier = T->getQualifier();
398     if (NestedNameSpecifier::SpecifierKind K = Qualifier->getKind();
399         K == NestedNameSpecifier::TypeSpec)
400       Visit(Qualifier->getAsType());
401     if (T->isSugared())
402       Visit(T->getMostRecentCXXRecordDecl()->getTypeForDecl());
403     Visit(T->getPointeeType());
404   }
VisitArrayType(const ArrayType * T)405   void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
VisitVariableArrayType(const VariableArrayType * T)406   void VisitVariableArrayType(const VariableArrayType *T) {
407     VisitArrayType(T);
408     Visit(T->getSizeExpr());
409   }
VisitDependentSizedArrayType(const DependentSizedArrayType * T)410   void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
411     Visit(T->getElementType());
412     Visit(T->getSizeExpr());
413   }
VisitDependentSizedExtVectorType(const DependentSizedExtVectorType * T)414   void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
415     Visit(T->getElementType());
416     Visit(T->getSizeExpr());
417   }
VisitVectorType(const VectorType * T)418   void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); }
VisitFunctionType(const FunctionType * T)419   void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); }
VisitFunctionProtoType(const FunctionProtoType * T)420   void VisitFunctionProtoType(const FunctionProtoType *T) {
421     VisitFunctionType(T);
422     for (const QualType &PT : T->getParamTypes())
423       Visit(PT);
424   }
VisitTypeOfExprType(const TypeOfExprType * T)425   void VisitTypeOfExprType(const TypeOfExprType *T) {
426     Visit(T->getUnderlyingExpr());
427   }
VisitDecltypeType(const DecltypeType * T)428   void VisitDecltypeType(const DecltypeType *T) {
429     Visit(T->getUnderlyingExpr());
430   }
431 
VisitPackIndexingType(const PackIndexingType * T)432   void VisitPackIndexingType(const PackIndexingType *T) {
433     Visit(T->getPattern());
434     Visit(T->getIndexExpr());
435   }
436 
VisitUnaryTransformType(const UnaryTransformType * T)437   void VisitUnaryTransformType(const UnaryTransformType *T) {
438     Visit(T->getBaseType());
439   }
VisitAttributedType(const AttributedType * T)440   void VisitAttributedType(const AttributedType *T) {
441     // FIXME: AttrKind
442     if (T->getModifiedType() != T->getEquivalentType())
443       Visit(T->getModifiedType());
444   }
VisitBTFTagAttributedType(const BTFTagAttributedType * T)445   void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
446     Visit(T->getWrappedType());
447   }
VisitHLSLAttributedResourceType(const HLSLAttributedResourceType * T)448   void VisitHLSLAttributedResourceType(const HLSLAttributedResourceType *T) {
449     QualType Contained = T->getContainedType();
450     if (!Contained.isNull())
451       Visit(Contained);
452   }
VisitHLSLInlineSpirvType(const HLSLInlineSpirvType * T)453   void VisitHLSLInlineSpirvType(const HLSLInlineSpirvType *T) {
454     for (auto &Operand : T->getOperands()) {
455       using SpirvOperandKind = SpirvOperand::SpirvOperandKind;
456 
457       switch (Operand.getKind()) {
458       case SpirvOperandKind::ConstantId:
459       case SpirvOperandKind::Literal:
460         break;
461 
462       case SpirvOperandKind::TypeId:
463         Visit(Operand.getResultType());
464         break;
465 
466       default:
467         llvm_unreachable("Invalid SpirvOperand kind!");
468       }
469     }
470   }
VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *)471   void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {}
472   void
VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType * T)473   VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
474     Visit(T->getArgumentPack());
475   }
VisitTemplateSpecializationType(const TemplateSpecializationType * T)476   void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
477     for (const auto &Arg : T->template_arguments())
478       Visit(Arg);
479   }
VisitObjCObjectPointerType(const ObjCObjectPointerType * T)480   void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
481     Visit(T->getPointeeType());
482   }
VisitAtomicType(const AtomicType * T)483   void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); }
VisitPipeType(const PipeType * T)484   void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); }
VisitAdjustedType(const AdjustedType * T)485   void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); }
VisitPackExpansionType(const PackExpansionType * T)486   void VisitPackExpansionType(const PackExpansionType *T) {
487     if (!T->isSugared())
488       Visit(T->getPattern());
489   }
VisitAutoType(const AutoType * T)490   void VisitAutoType(const AutoType *T) {
491     for (const auto &Arg : T->getTypeConstraintArguments())
492       Visit(Arg);
493   }
494   // FIXME: ElaboratedType, DependentNameType,
495   // DependentTemplateSpecializationType, ObjCObjectType
496 
497   // For TypeLocs, we automatically visit the inner type loc (pointee type etc).
498   // We must explicitly visit other lexically-nested nodes.
VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL)499   void VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
500     TypeLocVisitor<Derived>::VisitFunctionTypeLoc(TL);
501     for (const auto *Param : TL.getParams())
502       Visit(Param, /*VisitTypeLocs=*/true);
503   }
VisitAutoTypeLoc(AutoTypeLoc TL)504   void VisitAutoTypeLoc(AutoTypeLoc TL) {
505     if (const auto *CR = TL.getConceptReference()) {
506       if (auto *Args = CR->getTemplateArgsAsWritten())
507         for (const auto &Arg : Args->arguments())
508           dumpTemplateArgumentLoc(Arg);
509     }
510   }
VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL)511   void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
512     // FIXME: Provide NestedNamespecifierLoc visitor.
513     Visit(TL.getQualifierLoc().getTypeLoc());
514   }
VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL)515   void VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
516     Visit(TL.getSizeExpr());
517   }
VisitDependentSizedArrayTypeLoc(DependentSizedArrayTypeLoc TL)518   void VisitDependentSizedArrayTypeLoc(DependentSizedArrayTypeLoc TL) {
519     Visit(TL.getSizeExpr());
520   }
VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL)521   void VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) {
522     Visit(cast<DependentSizedExtVectorType>(TL.getType())->getSizeExpr());
523   }
VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL)524   void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
525     Visit(TL.getUnderlyingExpr());
526   }
VisitDecltypeType(DecltypeType TL)527   void VisitDecltypeType(DecltypeType TL) {
528     Visit(TL.getUnderlyingExpr());
529   }
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)530   void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
531     for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
532       dumpTemplateArgumentLoc(TL.getArgLoc(I));
533   }
VisitDependentTemplateSpecializationTypeLoc(DependentTemplateSpecializationTypeLoc TL)534   void VisitDependentTemplateSpecializationTypeLoc(
535       DependentTemplateSpecializationTypeLoc TL) {
536     for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
537       dumpTemplateArgumentLoc(TL.getArgLoc(I));
538   }
539 
VisitTypedefDecl(const TypedefDecl * D)540   void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }
541 
VisitEnumConstantDecl(const EnumConstantDecl * D)542   void VisitEnumConstantDecl(const EnumConstantDecl *D) {
543     if (const Expr *Init = D->getInitExpr())
544       Visit(Init);
545   }
546 
VisitFunctionDecl(const FunctionDecl * D)547   void VisitFunctionDecl(const FunctionDecl *D) {
548     if (FunctionTemplateSpecializationInfo *FTSI =
549             D->getTemplateSpecializationInfo())
550       dumpTemplateArgumentList(*FTSI->TemplateArguments);
551     else if (DependentFunctionTemplateSpecializationInfo *DFTSI =
552                  D->getDependentSpecializationInfo())
553       dumpASTTemplateArgumentListInfo(DFTSI->TemplateArgumentsAsWritten);
554 
555     if (D->param_begin())
556       for (const auto *Parameter : D->parameters())
557         Visit(Parameter);
558 
559     if (const AssociatedConstraint &TRC = D->getTrailingRequiresClause())
560       Visit(TRC.ConstraintExpr);
561 
562     if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isDefaulted())
563       return;
564 
565     if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
566       for (const auto *I : C->inits())
567         Visit(I);
568 
569     if (D->doesThisDeclarationHaveABody())
570       Visit(D->getBody());
571   }
572 
VisitFieldDecl(const FieldDecl * D)573   void VisitFieldDecl(const FieldDecl *D) {
574     if (D->isBitField())
575       Visit(D->getBitWidth());
576     if (Expr *Init = D->getInClassInitializer())
577       Visit(Init);
578   }
579 
VisitVarDecl(const VarDecl * D)580   void VisitVarDecl(const VarDecl *D) {
581     if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isCXXForRangeDecl())
582       return;
583 
584     if (const auto *TSI = D->getTypeSourceInfo(); VisitLocs && TSI)
585       Visit(TSI->getTypeLoc());
586     if (D->hasInit())
587       Visit(D->getInit());
588   }
589 
VisitDecompositionDecl(const DecompositionDecl * D)590   void VisitDecompositionDecl(const DecompositionDecl *D) {
591     VisitVarDecl(D);
592     for (const auto *B : D->bindings())
593       Visit(B);
594   }
595 
VisitBindingDecl(const BindingDecl * D)596   void VisitBindingDecl(const BindingDecl *D) {
597     if (Traversal == TK_IgnoreUnlessSpelledInSource)
598       return;
599 
600     if (const auto *V = D->getHoldingVar())
601       Visit(V);
602 
603     if (const auto *E = D->getBinding())
604       Visit(E);
605   }
606 
VisitFileScopeAsmDecl(const FileScopeAsmDecl * D)607   void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
608     Visit(D->getAsmStringExpr());
609   }
610 
VisitTopLevelStmtDecl(const TopLevelStmtDecl * D)611   void VisitTopLevelStmtDecl(const TopLevelStmtDecl *D) { Visit(D->getStmt()); }
612 
VisitOutlinedFunctionDecl(const OutlinedFunctionDecl * D)613   void VisitOutlinedFunctionDecl(const OutlinedFunctionDecl *D) {
614     for (const ImplicitParamDecl *Parameter : D->parameters())
615       Visit(Parameter);
616     Visit(D->getBody());
617   }
618 
VisitCapturedDecl(const CapturedDecl * D)619   void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }
620 
VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl * D)621   void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
622     for (const auto *E : D->varlist())
623       Visit(E);
624   }
625 
VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl * D)626   void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
627     Visit(D->getCombiner());
628     if (const auto *Initializer = D->getInitializer())
629       Visit(Initializer);
630   }
631 
VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl * D)632   void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {
633     for (const auto *C : D->clauselists())
634       Visit(C);
635   }
636 
VisitOMPCapturedExprDecl(const OMPCapturedExprDecl * D)637   void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
638     Visit(D->getInit());
639   }
640 
VisitOMPAllocateDecl(const OMPAllocateDecl * D)641   void VisitOMPAllocateDecl(const OMPAllocateDecl *D) {
642     for (const auto *E : D->varlist())
643       Visit(E);
644     for (const auto *C : D->clauselists())
645       Visit(C);
646   }
647 
648   template <typename SpecializationDecl>
dumpTemplateDeclSpecialization(const SpecializationDecl * D)649   void dumpTemplateDeclSpecialization(const SpecializationDecl *D) {
650     for (const auto *RedeclWithBadType : D->redecls()) {
651       // FIXME: The redecls() range sometimes has elements of a less-specific
652       // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
653       // us TagDecls, and should give CXXRecordDecls).
654       auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
655       if (!Redecl) {
656         // Found the injected-class-name for a class template. This will be
657         // dumped as part of its surrounding class so we don't need to dump it
658         // here.
659         assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
660                "expected an injected-class-name");
661         continue;
662       }
663       Visit(Redecl);
664     }
665   }
666 
667   template <typename TemplateDecl>
dumpTemplateDecl(const TemplateDecl * D)668   void dumpTemplateDecl(const TemplateDecl *D) {
669     dumpTemplateParameters(D->getTemplateParameters());
670 
671     Visit(D->getTemplatedDecl());
672 
673     if (Traversal == TK_AsIs) {
674       for (const auto *Child : D->specializations())
675         dumpTemplateDeclSpecialization(Child);
676     }
677   }
678 
VisitTypeAliasDecl(const TypeAliasDecl * D)679   void VisitTypeAliasDecl(const TypeAliasDecl *D) {
680     Visit(D->getUnderlyingType());
681   }
682 
VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl * D)683   void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
684     dumpTemplateParameters(D->getTemplateParameters());
685     Visit(D->getTemplatedDecl());
686   }
687 
VisitStaticAssertDecl(const StaticAssertDecl * D)688   void VisitStaticAssertDecl(const StaticAssertDecl *D) {
689     Visit(D->getAssertExpr());
690     Visit(D->getMessage());
691   }
692 
VisitFunctionTemplateDecl(const FunctionTemplateDecl * D)693   void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
694     dumpTemplateDecl(D);
695   }
696 
VisitClassTemplateDecl(const ClassTemplateDecl * D)697   void VisitClassTemplateDecl(const ClassTemplateDecl *D) {
698     dumpTemplateDecl(D);
699   }
700 
VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl * D)701   void VisitClassTemplateSpecializationDecl(
702       const ClassTemplateSpecializationDecl *D) {
703     dumpTemplateArgumentList(D->getTemplateArgs());
704   }
705 
VisitClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl * D)706   void VisitClassTemplatePartialSpecializationDecl(
707       const ClassTemplatePartialSpecializationDecl *D) {
708     VisitClassTemplateSpecializationDecl(D);
709     dumpTemplateParameters(D->getTemplateParameters());
710   }
711 
VisitVarTemplateDecl(const VarTemplateDecl * D)712   void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); }
713 
VisitBuiltinTemplateDecl(const BuiltinTemplateDecl * D)714   void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
715     dumpTemplateParameters(D->getTemplateParameters());
716   }
717 
718   void
VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl * D)719   VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) {
720     dumpTemplateArgumentList(D->getTemplateArgs());
721     VisitVarDecl(D);
722   }
723 
VisitVarTemplatePartialSpecializationDecl(const VarTemplatePartialSpecializationDecl * D)724   void VisitVarTemplatePartialSpecializationDecl(
725       const VarTemplatePartialSpecializationDecl *D) {
726     dumpTemplateParameters(D->getTemplateParameters());
727     VisitVarTemplateSpecializationDecl(D);
728   }
729 
VisitTemplateTypeParmDecl(const TemplateTypeParmDecl * D)730   void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
731     if (const auto *TC = D->getTypeConstraint())
732       Visit(TC->getImmediatelyDeclaredConstraint());
733     if (D->hasDefaultArgument())
734       Visit(D->getDefaultArgument().getArgument(), SourceRange(),
735             D->getDefaultArgStorage().getInheritedFrom(),
736             D->defaultArgumentWasInherited() ? "inherited from" : "previous");
737   }
738 
VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl * D)739   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
740     if (const auto *E = D->getPlaceholderTypeConstraint())
741       Visit(E);
742     if (D->hasDefaultArgument())
743       dumpTemplateArgumentLoc(
744           D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
745           D->defaultArgumentWasInherited() ? "inherited from" : "previous");
746   }
747 
VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl * D)748   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
749     dumpTemplateParameters(D->getTemplateParameters());
750     if (D->hasDefaultArgument())
751       dumpTemplateArgumentLoc(
752           D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
753           D->defaultArgumentWasInherited() ? "inherited from" : "previous");
754   }
755 
VisitConceptDecl(const ConceptDecl * D)756   void VisitConceptDecl(const ConceptDecl *D) {
757     dumpTemplateParameters(D->getTemplateParameters());
758     Visit(D->getConstraintExpr());
759   }
760 
VisitImplicitConceptSpecializationDecl(const ImplicitConceptSpecializationDecl * CSD)761   void VisitImplicitConceptSpecializationDecl(
762       const ImplicitConceptSpecializationDecl *CSD) {
763     for (const TemplateArgument &Arg : CSD->getTemplateArguments())
764       Visit(Arg);
765   }
766 
VisitConceptSpecializationExpr(const ConceptSpecializationExpr * CSE)767   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) {
768     Visit(CSE->getSpecializationDecl());
769     if (CSE->hasExplicitTemplateArgs())
770       for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments())
771         dumpTemplateArgumentLoc(ArgLoc);
772   }
773 
VisitUsingShadowDecl(const UsingShadowDecl * D)774   void VisitUsingShadowDecl(const UsingShadowDecl *D) {
775     if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
776       Visit(TD->getTypeForDecl());
777   }
778 
VisitFriendDecl(const FriendDecl * D)779   void VisitFriendDecl(const FriendDecl *D) {
780     if (D->getFriendType()) {
781       // Traverse any CXXRecordDecl owned by this type, since
782       // it will not be in the parent context:
783       if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
784         if (auto *TD = ET->getOwnedTagDecl())
785           Visit(TD);
786     } else {
787       Visit(D->getFriendDecl());
788     }
789   }
790 
VisitObjCMethodDecl(const ObjCMethodDecl * D)791   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
792     if (D->isThisDeclarationADefinition())
793       dumpDeclContext(D);
794     else
795       for (const ParmVarDecl *Parameter : D->parameters())
796         Visit(Parameter);
797 
798     if (D->hasBody())
799       Visit(D->getBody());
800   }
801 
VisitObjCCategoryDecl(const ObjCCategoryDecl * D)802   void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
803     dumpObjCTypeParamList(D->getTypeParamList());
804   }
805 
VisitObjCInterfaceDecl(const ObjCInterfaceDecl * D)806   void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
807     dumpObjCTypeParamList(D->getTypeParamListAsWritten());
808   }
809 
VisitObjCImplementationDecl(const ObjCImplementationDecl * D)810   void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
811     for (const auto &I : D->inits())
812       Visit(I);
813   }
814 
VisitBlockDecl(const BlockDecl * D)815   void VisitBlockDecl(const BlockDecl *D) {
816     for (const auto &I : D->parameters())
817       Visit(I);
818 
819     for (const auto &I : D->captures())
820       Visit(I);
821     Visit(D->getBody());
822   }
823 
VisitDeclStmt(const DeclStmt * Node)824   void VisitDeclStmt(const DeclStmt *Node) {
825     for (const auto &D : Node->decls())
826       Visit(D);
827   }
828 
VisitAttributedStmt(const AttributedStmt * Node)829   void VisitAttributedStmt(const AttributedStmt *Node) {
830     for (const auto *A : Node->getAttrs())
831       Visit(A);
832   }
833 
VisitLabelStmt(const LabelStmt * Node)834   void VisitLabelStmt(const LabelStmt *Node) {
835     if (Node->getDecl()->hasAttrs()) {
836       for (const auto *A : Node->getDecl()->getAttrs())
837         Visit(A);
838     }
839   }
840 
VisitCXXCatchStmt(const CXXCatchStmt * Node)841   void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
842     Visit(Node->getExceptionDecl());
843   }
844 
VisitCapturedStmt(const CapturedStmt * Node)845   void VisitCapturedStmt(const CapturedStmt *Node) {
846     Visit(Node->getCapturedDecl());
847   }
848 
VisitSYCLKernelCallStmt(const SYCLKernelCallStmt * Node)849   void VisitSYCLKernelCallStmt(const SYCLKernelCallStmt *Node) {
850     Visit(Node->getOriginalStmt());
851     if (Traversal != TK_IgnoreUnlessSpelledInSource)
852       Visit(Node->getOutlinedFunctionDecl());
853   }
854 
VisitOMPExecutableDirective(const OMPExecutableDirective * Node)855   void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) {
856     for (const auto *C : Node->clauses())
857       Visit(C);
858   }
859 
VisitOpenACCConstructStmt(const OpenACCConstructStmt * Node)860   void VisitOpenACCConstructStmt(const OpenACCConstructStmt *Node) {
861     for (const auto *C : Node->clauses())
862       Visit(C);
863   }
864 
VisitOpenACCWaitConstruct(const OpenACCWaitConstruct * Node)865   void VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *Node) {
866     // Needs custom child checking to put clauses AFTER the children, which are
867     // the expressions in the 'wait' construct. Others likely need this as well,
868     // and might need to do the associated statement after it.
869     for (const Stmt *S : Node->children())
870       Visit(S);
871     for (const auto *C : Node->clauses())
872       Visit(C);
873   }
874 
VisitInitListExpr(const InitListExpr * ILE)875   void VisitInitListExpr(const InitListExpr *ILE) {
876     if (auto *Filler = ILE->getArrayFiller()) {
877       Visit(Filler, "array_filler");
878     }
879   }
880 
VisitCXXParenListInitExpr(const CXXParenListInitExpr * PLIE)881   void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
882     if (auto *Filler = PLIE->getArrayFiller()) {
883       Visit(Filler, "array_filler");
884     }
885   }
886 
VisitBlockExpr(const BlockExpr * Node)887   void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
888 
VisitOpaqueValueExpr(const OpaqueValueExpr * Node)889   void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
890     if (Expr *Source = Node->getSourceExpr())
891       Visit(Source);
892   }
893 
VisitGenericSelectionExpr(const GenericSelectionExpr * E)894   void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
895     if (E->isExprPredicate()) {
896       Visit(E->getControllingExpr());
897       Visit(E->getControllingExpr()->getType()); // FIXME: remove
898     } else
899       Visit(E->getControllingType()->getType());
900 
901     for (const auto Assoc : E->associations()) {
902       Visit(Assoc);
903     }
904   }
905 
VisitUnresolvedLookupExpr(const UnresolvedLookupExpr * E)906   void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *E) {
907     if (E->hasExplicitTemplateArgs())
908       for (auto Arg : E->template_arguments())
909         Visit(Arg.getArgument());
910   }
911 
VisitRequiresExpr(const RequiresExpr * E)912   void VisitRequiresExpr(const RequiresExpr *E) {
913     for (auto *D : E->getLocalParameters())
914       Visit(D);
915     for (auto *R : E->getRequirements())
916       Visit(R);
917   }
918 
VisitTypeTraitExpr(const TypeTraitExpr * E)919   void VisitTypeTraitExpr(const TypeTraitExpr *E) {
920     // Argument types are not children of the TypeTraitExpr.
921     for (auto *A : E->getArgs())
922       Visit(A->getType());
923   }
924 
VisitLambdaExpr(const LambdaExpr * Node)925   void VisitLambdaExpr(const LambdaExpr *Node) {
926     if (Traversal == TK_IgnoreUnlessSpelledInSource) {
927       for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) {
928         const auto *C = Node->capture_begin() + I;
929         if (!C->isExplicit())
930           continue;
931         if (Node->isInitCapture(C))
932           Visit(C->getCapturedVar());
933         else
934           Visit(Node->capture_init_begin()[I]);
935       }
936       dumpTemplateParameters(Node->getTemplateParameterList());
937       for (const auto *P : Node->getCallOperator()->parameters())
938         Visit(P);
939       Visit(Node->getBody());
940     } else {
941       return Visit(Node->getLambdaClass());
942     }
943   }
944 
VisitSizeOfPackExpr(const SizeOfPackExpr * Node)945   void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
946     if (Node->isPartiallySubstituted())
947       for (const auto &A : Node->getPartialArguments())
948         Visit(A);
949   }
950 
VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr * E)951   void VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) {
952     Visit(E->getParameter());
953   }
VisitSubstNonTypeTemplateParmPackExpr(const SubstNonTypeTemplateParmPackExpr * E)954   void VisitSubstNonTypeTemplateParmPackExpr(
955       const SubstNonTypeTemplateParmPackExpr *E) {
956     Visit(E->getParameterPack());
957     Visit(E->getArgumentPack());
958   }
959 
VisitObjCAtCatchStmt(const ObjCAtCatchStmt * Node)960   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
961     if (const VarDecl *CatchParam = Node->getCatchParamDecl())
962       Visit(CatchParam);
963   }
964 
VisitCXXForRangeStmt(const CXXForRangeStmt * Node)965   void VisitCXXForRangeStmt(const CXXForRangeStmt *Node) {
966     if (Traversal == TK_IgnoreUnlessSpelledInSource) {
967       Visit(Node->getInit());
968       Visit(Node->getLoopVariable());
969       Visit(Node->getRangeInit());
970       Visit(Node->getBody());
971     }
972   }
973 
VisitCallExpr(const CallExpr * Node)974   void VisitCallExpr(const CallExpr *Node) {
975     for (const auto *Child :
976          make_filter_range(Node->children(), [this](const Stmt *Child) {
977            if (Traversal != TK_IgnoreUnlessSpelledInSource)
978              return false;
979            return !isa<CXXDefaultArgExpr>(Child);
980          })) {
981       Visit(Child);
982     }
983   }
984 
VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator * Node)985   void VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *Node) {
986     if (Traversal == TK_IgnoreUnlessSpelledInSource) {
987       Visit(Node->getLHS());
988       Visit(Node->getRHS());
989     } else {
990       ConstStmtVisitor<Derived>::VisitCXXRewrittenBinaryOperator(Node);
991     }
992   }
993 
VisitExpressionTemplateArgument(const TemplateArgument & TA)994   void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
995     Visit(TA.getAsExpr());
996   }
997 
VisitTypeTemplateArgument(const TemplateArgument & TA)998   void VisitTypeTemplateArgument(const TemplateArgument &TA) {
999     Visit(TA.getAsType());
1000   }
1001 
VisitPackTemplateArgument(const TemplateArgument & TA)1002   void VisitPackTemplateArgument(const TemplateArgument &TA) {
1003     for (const auto &TArg : TA.pack_elements())
1004       Visit(TArg);
1005   }
1006 
VisitCXXDefaultArgExpr(const CXXDefaultArgExpr * Node)1007   void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) {
1008     Visit(Node->getExpr());
1009   }
1010 
VisitCXXDefaultInitExpr(const CXXDefaultInitExpr * Node)1011   void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {
1012     Visit(Node->getExpr());
1013   }
1014 
1015   // Implements Visit methods for Attrs.
1016 #include "clang/AST/AttrNodeTraverse.inc"
1017 };
1018 
1019 } // namespace clang
1020 
1021 #endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H
1022