Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:29

0001 //===--- ASTNodeTraverser.h - Traversal of AST nodes ----------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file implements the AST traversal facilities.  Other users
0010 // of this class may make use of the same traversal logic by inheriting it,
0011 // similar to RecursiveASTVisitor.
0012 //
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H
0016 #define LLVM_CLANG_AST_ASTNODETRAVERSER_H
0017 
0018 #include "clang/AST/ASTTypeTraits.h"
0019 #include "clang/AST/AttrVisitor.h"
0020 #include "clang/AST/CommentVisitor.h"
0021 #include "clang/AST/DeclVisitor.h"
0022 #include "clang/AST/LocInfoType.h"
0023 #include "clang/AST/StmtVisitor.h"
0024 #include "clang/AST/TemplateArgumentVisitor.h"
0025 #include "clang/AST/Type.h"
0026 #include "clang/AST/TypeLocVisitor.h"
0027 #include "clang/AST/TypeVisitor.h"
0028 #include "llvm/Support/SaveAndRestore.h"
0029 
0030 namespace clang {
0031 
0032 class APValue;
0033 
0034 /**
0035 
0036 ASTNodeTraverser traverses the Clang AST for dumping purposes.
0037 
0038 The `Derived::doGetNodeDelegate()` method is required to be an accessible member
0039 which returns a reference of type `NodeDelegateType &` which implements the
0040 following interface:
0041 
0042 struct {
0043   template <typename Fn> void AddChild(Fn DoAddChild);
0044   template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild);
0045 
0046   void Visit(const comments::Comment *C, const comments::FullComment *FC);
0047   void Visit(const Attr *A);
0048   void Visit(const TemplateArgument &TA, SourceRange R = {},
0049              const Decl *From = nullptr, StringRef Label = {});
0050   void Visit(const Stmt *Node);
0051   void Visit(const Type *T);
0052   void Visit(QualType T);
0053   void Visit(TypeLoc);
0054   void Visit(const Decl *D);
0055   void Visit(const CXXCtorInitializer *Init);
0056   void Visit(const OpenACCClause *C);
0057   void Visit(const OMPClause *C);
0058   void Visit(const BlockDecl::Capture &C);
0059   void Visit(const GenericSelectionExpr::ConstAssociation &A);
0060   void Visit(const concepts::Requirement *R);
0061   void Visit(const APValue &Value, QualType Ty);
0062 };
0063 */
0064 template <typename Derived, typename NodeDelegateType>
0065 class ASTNodeTraverser
0066     : public ConstDeclVisitor<Derived>,
0067       public ConstStmtVisitor<Derived>,
0068       public comments::ConstCommentVisitor<Derived, void,
0069                                            const comments::FullComment *>,
0070       public TypeVisitor<Derived>,
0071       public TypeLocVisitor<Derived>,
0072       public ConstAttrVisitor<Derived>,
0073       public ConstTemplateArgumentVisitor<Derived> {
0074 
0075   /// Indicates whether we should trigger deserialization of nodes that had
0076   /// not already been loaded.
0077   bool Deserialize = false;
0078 
0079   /// Tracks whether we should dump TypeLocs etc.
0080   ///
0081   /// Detailed location information such as TypeLoc nodes is not usually
0082   /// included in the dump (too verbose).
0083   /// But when explicitly asked to dump a Loc node, we do so recursively,
0084   /// including e.g. FunctionTypeLoc => ParmVarDecl => TypeLoc.
0085   bool VisitLocs = false;
0086 
0087   TraversalKind Traversal = TraversalKind::TK_AsIs;
0088 
0089   NodeDelegateType &getNodeDelegate() {
0090     return getDerived().doGetNodeDelegate();
0091   }
0092   Derived &getDerived() { return *static_cast<Derived *>(this); }
0093 
0094 public:
0095   void setDeserialize(bool D) { Deserialize = D; }
0096   bool getDeserialize() const { return Deserialize; }
0097 
0098   void SetTraversalKind(TraversalKind TK) { Traversal = TK; }
0099   TraversalKind GetTraversalKind() const { return Traversal; }
0100 
0101   void Visit(const Decl *D, bool VisitLocs = false) {
0102     if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isImplicit())
0103       return;
0104 
0105     getNodeDelegate().AddChild([=] {
0106       getNodeDelegate().Visit(D);
0107       if (!D)
0108         return;
0109 
0110       {
0111         llvm::SaveAndRestore RestoreVisitLocs(this->VisitLocs, VisitLocs);
0112         ConstDeclVisitor<Derived>::Visit(D);
0113       }
0114 
0115       for (const auto &A : D->attrs())
0116         Visit(A);
0117 
0118       if (const comments::FullComment *Comment =
0119               D->getASTContext().getLocalCommentForDeclUncached(D))
0120         Visit(Comment, Comment);
0121 
0122       // Decls within functions are visited by the body.
0123       if (!isa<FunctionDecl, ObjCMethodDecl, BlockDecl>(*D)) {
0124         if (Traversal != TK_AsIs) {
0125           if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
0126             auto SK = CTSD->getSpecializationKind();
0127             if (SK == TSK_ExplicitInstantiationDeclaration ||
0128                 SK == TSK_ExplicitInstantiationDefinition)
0129               return;
0130           }
0131         }
0132         if (const auto *DC = dyn_cast<DeclContext>(D))
0133           dumpDeclContext(DC);
0134       }
0135     });
0136   }
0137 
0138   void Visit(const Stmt *Node, StringRef Label = {}) {
0139     getNodeDelegate().AddChild(Label, [=] {
0140       const Stmt *S = Node;
0141 
0142       if (auto *E = dyn_cast_or_null<Expr>(S)) {
0143         switch (Traversal) {
0144         case TK_AsIs:
0145           break;
0146         case TK_IgnoreUnlessSpelledInSource:
0147           S = E->IgnoreUnlessSpelledInSource();
0148           break;
0149         }
0150       }
0151 
0152       getNodeDelegate().Visit(S);
0153 
0154       if (!S) {
0155         return;
0156       }
0157 
0158       ConstStmtVisitor<Derived>::Visit(S);
0159 
0160       // Some statements have custom mechanisms for dumping their children.
0161       if (isa<DeclStmt, GenericSelectionExpr, RequiresExpr,
0162               OpenACCWaitConstruct, SYCLKernelCallStmt>(S))
0163         return;
0164 
0165       if (Traversal == TK_IgnoreUnlessSpelledInSource &&
0166           isa<LambdaExpr, CXXForRangeStmt, CallExpr,
0167               CXXRewrittenBinaryOperator>(S))
0168         return;
0169 
0170       for (const Stmt *SubStmt : S->children())
0171         Visit(SubStmt);
0172     });
0173   }
0174 
0175   void Visit(QualType T) {
0176     SplitQualType SQT = T.split();
0177     if (!SQT.Quals.hasQualifiers())
0178       return Visit(SQT.Ty);
0179 
0180     getNodeDelegate().AddChild([=] {
0181       getNodeDelegate().Visit(T);
0182       Visit(T.split().Ty);
0183     });
0184   }
0185 
0186   void Visit(const Type *T) {
0187     getNodeDelegate().AddChild([=] {
0188       getNodeDelegate().Visit(T);
0189       if (!T)
0190         return;
0191       TypeVisitor<Derived>::Visit(T);
0192 
0193       QualType SingleStepDesugar =
0194           T->getLocallyUnqualifiedSingleStepDesugaredType();
0195       if (SingleStepDesugar != QualType(T, 0))
0196         Visit(SingleStepDesugar);
0197     });
0198   }
0199 
0200   void Visit(TypeLoc T) {
0201     getNodeDelegate().AddChild([=] {
0202       getNodeDelegate().Visit(T);
0203       if (T.isNull())
0204         return;
0205       TypeLocVisitor<Derived>::Visit(T);
0206       if (auto Inner = T.getNextTypeLoc())
0207         Visit(Inner);
0208     });
0209   }
0210 
0211   void Visit(const Attr *A) {
0212     getNodeDelegate().AddChild([=] {
0213       getNodeDelegate().Visit(A);
0214       ConstAttrVisitor<Derived>::Visit(A);
0215     });
0216   }
0217 
0218   void Visit(const CXXCtorInitializer *Init) {
0219     if (Traversal == TK_IgnoreUnlessSpelledInSource && !Init->isWritten())
0220       return;
0221     getNodeDelegate().AddChild([=] {
0222       getNodeDelegate().Visit(Init);
0223       Visit(Init->getInit());
0224     });
0225   }
0226 
0227   void Visit(const TemplateArgument &A, SourceRange R = {},
0228              const Decl *From = nullptr, const char *Label = nullptr) {
0229     getNodeDelegate().AddChild([=] {
0230       getNodeDelegate().Visit(A, R, From, Label);
0231       ConstTemplateArgumentVisitor<Derived>::Visit(A);
0232     });
0233   }
0234 
0235   void Visit(const BlockDecl::Capture &C) {
0236     getNodeDelegate().AddChild([=] {
0237       getNodeDelegate().Visit(C);
0238       if (C.hasCopyExpr())
0239         Visit(C.getCopyExpr());
0240     });
0241   }
0242 
0243   void Visit(const OpenACCClause *C) {
0244     getNodeDelegate().AddChild([=] {
0245       getNodeDelegate().Visit(C);
0246       for (const auto *S : C->children())
0247         Visit(S);
0248     });
0249   }
0250 
0251   void Visit(const OMPClause *C) {
0252     getNodeDelegate().AddChild([=] {
0253       getNodeDelegate().Visit(C);
0254       for (const auto *S : C->children())
0255         Visit(S);
0256     });
0257   }
0258 
0259   void Visit(const GenericSelectionExpr::ConstAssociation &A) {
0260     getNodeDelegate().AddChild([=] {
0261       getNodeDelegate().Visit(A);
0262       if (const TypeSourceInfo *TSI = A.getTypeSourceInfo())
0263         Visit(TSI->getType());
0264       Visit(A.getAssociationExpr());
0265     });
0266   }
0267 
0268   void Visit(const concepts::Requirement *R) {
0269     getNodeDelegate().AddChild([=] {
0270       getNodeDelegate().Visit(R);
0271       if (!R)
0272         return;
0273       if (auto *TR = dyn_cast<concepts::TypeRequirement>(R)) {
0274         if (!TR->isSubstitutionFailure())
0275           Visit(TR->getType()->getType().getTypePtr());
0276       } else if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
0277         if (!ER->isExprSubstitutionFailure())
0278           Visit(ER->getExpr());
0279         if (!ER->getReturnTypeRequirement().isEmpty())
0280           Visit(ER->getReturnTypeRequirement()
0281                     .getTypeConstraint()
0282                     ->getImmediatelyDeclaredConstraint());
0283       } else if (auto *NR = dyn_cast<concepts::NestedRequirement>(R)) {
0284         if (!NR->hasInvalidConstraint())
0285           Visit(NR->getConstraintExpr());
0286       }
0287     });
0288   }
0289 
0290   void Visit(const ConceptReference *R) {
0291     getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(R); });
0292   }
0293 
0294   void Visit(const APValue &Value, QualType Ty) {
0295     getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); });
0296   }
0297 
0298   void Visit(const comments::Comment *C, const comments::FullComment *FC) {
0299     getNodeDelegate().AddChild([=] {
0300       getNodeDelegate().Visit(C, FC);
0301       if (!C) {
0302         return;
0303       }
0304       comments::ConstCommentVisitor<Derived, void,
0305                                     const comments::FullComment *>::visit(C,
0306                                                                           FC);
0307       for (comments::Comment::child_iterator I = C->child_begin(),
0308                                              E = C->child_end();
0309            I != E; ++I)
0310         Visit(*I, FC);
0311     });
0312   }
0313 
0314   void Visit(const DynTypedNode &N) {
0315     // FIXME: Improve this with a switch or a visitor pattern.
0316     if (const auto *D = N.get<Decl>())
0317       Visit(D);
0318     else if (const auto *S = N.get<Stmt>())
0319       Visit(S);
0320     else if (const auto *QT = N.get<QualType>())
0321       Visit(*QT);
0322     else if (const auto *T = N.get<Type>())
0323       Visit(T);
0324     else if (const auto *TL = N.get<TypeLoc>())
0325       Visit(*TL);
0326     else if (const auto *C = N.get<CXXCtorInitializer>())
0327       Visit(C);
0328     else if (const auto *C = N.get<OMPClause>())
0329       Visit(C);
0330     else if (const auto *T = N.get<TemplateArgument>())
0331       Visit(*T);
0332     else if (const auto *CR = N.get<ConceptReference>())
0333       Visit(CR);
0334   }
0335 
0336   void dumpDeclContext(const DeclContext *DC) {
0337     if (!DC)
0338       return;
0339 
0340     for (const auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
0341       Visit(D);
0342   }
0343 
0344   void dumpTemplateParameters(const TemplateParameterList *TPL) {
0345     if (!TPL)
0346       return;
0347 
0348     for (const auto &TP : *TPL)
0349       Visit(TP);
0350 
0351     if (const Expr *RC = TPL->getRequiresClause())
0352       Visit(RC);
0353   }
0354 
0355   void
0356   dumpASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *TALI) {
0357     if (!TALI)
0358       return;
0359 
0360     for (const auto &TA : TALI->arguments())
0361       dumpTemplateArgumentLoc(TA);
0362   }
0363 
0364   void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
0365                                const Decl *From = nullptr,
0366                                const char *Label = nullptr) {
0367     Visit(A.getArgument(), A.getSourceRange(), From, Label);
0368   }
0369 
0370   void dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
0371     for (unsigned i = 0, e = TAL.size(); i < e; ++i)
0372       Visit(TAL[i]);
0373   }
0374 
0375   void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
0376     if (!typeParams)
0377       return;
0378 
0379     for (const auto &typeParam : *typeParams) {
0380       Visit(typeParam);
0381     }
0382   }
0383 
0384   void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); }
0385   void VisitLocInfoType(const LocInfoType *T) {
0386     Visit(T->getTypeSourceInfo()->getTypeLoc());
0387   }
0388   void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); }
0389   void VisitBlockPointerType(const BlockPointerType *T) {
0390     Visit(T->getPointeeType());
0391   }
0392   void VisitReferenceType(const ReferenceType *T) {
0393     Visit(T->getPointeeType());
0394   }
0395   void VisitMemberPointerType(const MemberPointerType *T) {
0396     Visit(T->getClass());
0397     Visit(T->getPointeeType());
0398   }
0399   void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
0400   void VisitVariableArrayType(const VariableArrayType *T) {
0401     VisitArrayType(T);
0402     Visit(T->getSizeExpr());
0403   }
0404   void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
0405     Visit(T->getElementType());
0406     Visit(T->getSizeExpr());
0407   }
0408   void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
0409     Visit(T->getElementType());
0410     Visit(T->getSizeExpr());
0411   }
0412   void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); }
0413   void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); }
0414   void VisitFunctionProtoType(const FunctionProtoType *T) {
0415     VisitFunctionType(T);
0416     for (const QualType &PT : T->getParamTypes())
0417       Visit(PT);
0418   }
0419   void VisitTypeOfExprType(const TypeOfExprType *T) {
0420     Visit(T->getUnderlyingExpr());
0421   }
0422   void VisitDecltypeType(const DecltypeType *T) {
0423     Visit(T->getUnderlyingExpr());
0424   }
0425 
0426   void VisitPackIndexingType(const PackIndexingType *T) {
0427     Visit(T->getPattern());
0428     Visit(T->getIndexExpr());
0429   }
0430 
0431   void VisitUnaryTransformType(const UnaryTransformType *T) {
0432     Visit(T->getBaseType());
0433   }
0434   void VisitAttributedType(const AttributedType *T) {
0435     // FIXME: AttrKind
0436     if (T->getModifiedType() != T->getEquivalentType())
0437       Visit(T->getModifiedType());
0438   }
0439   void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
0440     Visit(T->getWrappedType());
0441   }
0442   void VisitHLSLAttributedResourceType(const HLSLAttributedResourceType *T) {
0443     QualType Contained = T->getContainedType();
0444     if (!Contained.isNull())
0445       Visit(Contained);
0446   }
0447   void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {}
0448   void
0449   VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
0450     Visit(T->getArgumentPack());
0451   }
0452   void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
0453     for (const auto &Arg : T->template_arguments())
0454       Visit(Arg);
0455   }
0456   void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
0457     Visit(T->getPointeeType());
0458   }
0459   void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); }
0460   void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); }
0461   void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); }
0462   void VisitPackExpansionType(const PackExpansionType *T) {
0463     if (!T->isSugared())
0464       Visit(T->getPattern());
0465   }
0466   void VisitAutoType(const AutoType *T) {
0467     for (const auto &Arg : T->getTypeConstraintArguments())
0468       Visit(Arg);
0469   }
0470   // FIXME: ElaboratedType, DependentNameType,
0471   // DependentTemplateSpecializationType, ObjCObjectType
0472 
0473   // For TypeLocs, we automatically visit the inner type loc (pointee type etc).
0474   // We must explicitly visit other lexically-nested nodes.
0475   void VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
0476     TypeLocVisitor<Derived>::VisitFunctionTypeLoc(TL);
0477     for (const auto *Param : TL.getParams())
0478       Visit(Param, /*VisitTypeLocs=*/true);
0479   }
0480   void VisitAutoTypeLoc(AutoTypeLoc TL) {
0481     if (const auto *CR = TL.getConceptReference()) {
0482       if (auto *Args = CR->getTemplateArgsAsWritten())
0483         for (const auto &Arg : Args->arguments())
0484           dumpTemplateArgumentLoc(Arg);
0485     }
0486   }
0487   void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
0488     Visit(TL.getClassTInfo()->getTypeLoc());
0489   }
0490   void VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
0491     Visit(TL.getSizeExpr());
0492   }
0493   void VisitDependentSizedArrayTypeLoc(DependentSizedArrayTypeLoc TL) {
0494     Visit(TL.getSizeExpr());
0495   }
0496   void VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) {
0497     Visit(cast<DependentSizedExtVectorType>(TL.getType())->getSizeExpr());
0498   }
0499   void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
0500     Visit(TL.getUnderlyingExpr());
0501   }
0502   void VisitDecltypeType(DecltypeType TL) {
0503     Visit(TL.getUnderlyingExpr());
0504   }
0505   void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
0506     for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
0507       dumpTemplateArgumentLoc(TL.getArgLoc(I));
0508   }
0509   void VisitDependentTemplateSpecializationTypeLoc(
0510       DependentTemplateSpecializationTypeLoc TL) {
0511     for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I)
0512       dumpTemplateArgumentLoc(TL.getArgLoc(I));
0513   }
0514 
0515   void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }
0516 
0517   void VisitEnumConstantDecl(const EnumConstantDecl *D) {
0518     if (const Expr *Init = D->getInitExpr())
0519       Visit(Init);
0520   }
0521 
0522   void VisitFunctionDecl(const FunctionDecl *D) {
0523     if (FunctionTemplateSpecializationInfo *FTSI =
0524             D->getTemplateSpecializationInfo())
0525       dumpTemplateArgumentList(*FTSI->TemplateArguments);
0526     else if (DependentFunctionTemplateSpecializationInfo *DFTSI =
0527                  D->getDependentSpecializationInfo())
0528       dumpASTTemplateArgumentListInfo(DFTSI->TemplateArgumentsAsWritten);
0529 
0530     if (D->param_begin())
0531       for (const auto *Parameter : D->parameters())
0532         Visit(Parameter);
0533 
0534     if (const Expr *TRC = D->getTrailingRequiresClause())
0535       Visit(TRC);
0536 
0537     if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isDefaulted())
0538       return;
0539 
0540     if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
0541       for (const auto *I : C->inits())
0542         Visit(I);
0543 
0544     if (D->doesThisDeclarationHaveABody())
0545       Visit(D->getBody());
0546   }
0547 
0548   void VisitFieldDecl(const FieldDecl *D) {
0549     if (D->isBitField())
0550       Visit(D->getBitWidth());
0551     if (Expr *Init = D->getInClassInitializer())
0552       Visit(Init);
0553   }
0554 
0555   void VisitVarDecl(const VarDecl *D) {
0556     if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isCXXForRangeDecl())
0557       return;
0558 
0559     if (const auto *TSI = D->getTypeSourceInfo(); VisitLocs && TSI)
0560       Visit(TSI->getTypeLoc());
0561     if (D->hasInit())
0562       Visit(D->getInit());
0563   }
0564 
0565   void VisitDecompositionDecl(const DecompositionDecl *D) {
0566     VisitVarDecl(D);
0567     for (const auto *B : D->bindings())
0568       Visit(B);
0569   }
0570 
0571   void VisitBindingDecl(const BindingDecl *D) {
0572     if (Traversal == TK_IgnoreUnlessSpelledInSource)
0573       return;
0574 
0575     if (const auto *V = D->getHoldingVar())
0576       Visit(V);
0577 
0578     if (const auto *E = D->getBinding())
0579       Visit(E);
0580   }
0581 
0582   void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
0583     Visit(D->getAsmString());
0584   }
0585 
0586   void VisitTopLevelStmtDecl(const TopLevelStmtDecl *D) { Visit(D->getStmt()); }
0587 
0588   void VisitOutlinedFunctionDecl(const OutlinedFunctionDecl *D) {
0589     for (const ImplicitParamDecl *Parameter : D->parameters())
0590       Visit(Parameter);
0591     Visit(D->getBody());
0592   }
0593 
0594   void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }
0595 
0596   void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
0597     for (const auto *E : D->varlist())
0598       Visit(E);
0599   }
0600 
0601   void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
0602     Visit(D->getCombiner());
0603     if (const auto *Initializer = D->getInitializer())
0604       Visit(Initializer);
0605   }
0606 
0607   void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {
0608     for (const auto *C : D->clauselists())
0609       Visit(C);
0610   }
0611 
0612   void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
0613     Visit(D->getInit());
0614   }
0615 
0616   void VisitOMPAllocateDecl(const OMPAllocateDecl *D) {
0617     for (const auto *E : D->varlist())
0618       Visit(E);
0619     for (const auto *C : D->clauselists())
0620       Visit(C);
0621   }
0622 
0623   template <typename SpecializationDecl>
0624   void dumpTemplateDeclSpecialization(const SpecializationDecl *D) {
0625     for (const auto *RedeclWithBadType : D->redecls()) {
0626       // FIXME: The redecls() range sometimes has elements of a less-specific
0627       // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
0628       // us TagDecls, and should give CXXRecordDecls).
0629       auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
0630       if (!Redecl) {
0631         // Found the injected-class-name for a class template. This will be
0632         // dumped as part of its surrounding class so we don't need to dump it
0633         // here.
0634         assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
0635                "expected an injected-class-name");
0636         continue;
0637       }
0638       Visit(Redecl);
0639     }
0640   }
0641 
0642   template <typename TemplateDecl>
0643   void dumpTemplateDecl(const TemplateDecl *D) {
0644     dumpTemplateParameters(D->getTemplateParameters());
0645 
0646     Visit(D->getTemplatedDecl());
0647 
0648     if (Traversal == TK_AsIs) {
0649       for (const auto *Child : D->specializations())
0650         dumpTemplateDeclSpecialization(Child);
0651     }
0652   }
0653 
0654   void VisitTypeAliasDecl(const TypeAliasDecl *D) {
0655     Visit(D->getUnderlyingType());
0656   }
0657 
0658   void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
0659     dumpTemplateParameters(D->getTemplateParameters());
0660     Visit(D->getTemplatedDecl());
0661   }
0662 
0663   void VisitStaticAssertDecl(const StaticAssertDecl *D) {
0664     Visit(D->getAssertExpr());
0665     Visit(D->getMessage());
0666   }
0667 
0668   void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
0669     dumpTemplateDecl(D);
0670   }
0671 
0672   void VisitClassTemplateDecl(const ClassTemplateDecl *D) {
0673     dumpTemplateDecl(D);
0674   }
0675 
0676   void VisitClassTemplateSpecializationDecl(
0677       const ClassTemplateSpecializationDecl *D) {
0678     dumpTemplateArgumentList(D->getTemplateArgs());
0679   }
0680 
0681   void VisitClassTemplatePartialSpecializationDecl(
0682       const ClassTemplatePartialSpecializationDecl *D) {
0683     VisitClassTemplateSpecializationDecl(D);
0684     dumpTemplateParameters(D->getTemplateParameters());
0685   }
0686 
0687   void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); }
0688 
0689   void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
0690     dumpTemplateParameters(D->getTemplateParameters());
0691   }
0692 
0693   void
0694   VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) {
0695     dumpTemplateArgumentList(D->getTemplateArgs());
0696     VisitVarDecl(D);
0697   }
0698 
0699   void VisitVarTemplatePartialSpecializationDecl(
0700       const VarTemplatePartialSpecializationDecl *D) {
0701     dumpTemplateParameters(D->getTemplateParameters());
0702     VisitVarTemplateSpecializationDecl(D);
0703   }
0704 
0705   void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
0706     if (const auto *TC = D->getTypeConstraint())
0707       Visit(TC->getImmediatelyDeclaredConstraint());
0708     if (D->hasDefaultArgument())
0709       Visit(D->getDefaultArgument().getArgument(), SourceRange(),
0710             D->getDefaultArgStorage().getInheritedFrom(),
0711             D->defaultArgumentWasInherited() ? "inherited from" : "previous");
0712   }
0713 
0714   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
0715     if (const auto *E = D->getPlaceholderTypeConstraint())
0716       Visit(E);
0717     if (D->hasDefaultArgument())
0718       dumpTemplateArgumentLoc(
0719           D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
0720           D->defaultArgumentWasInherited() ? "inherited from" : "previous");
0721   }
0722 
0723   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
0724     dumpTemplateParameters(D->getTemplateParameters());
0725     if (D->hasDefaultArgument())
0726       dumpTemplateArgumentLoc(
0727           D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
0728           D->defaultArgumentWasInherited() ? "inherited from" : "previous");
0729   }
0730 
0731   void VisitConceptDecl(const ConceptDecl *D) {
0732     dumpTemplateParameters(D->getTemplateParameters());
0733     Visit(D->getConstraintExpr());
0734   }
0735 
0736   void VisitImplicitConceptSpecializationDecl(
0737       const ImplicitConceptSpecializationDecl *CSD) {
0738     for (const TemplateArgument &Arg : CSD->getTemplateArguments())
0739       Visit(Arg);
0740   }
0741 
0742   void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) {
0743     Visit(CSE->getSpecializationDecl());
0744     if (CSE->hasExplicitTemplateArgs())
0745       for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments())
0746         dumpTemplateArgumentLoc(ArgLoc);
0747   }
0748 
0749   void VisitUsingShadowDecl(const UsingShadowDecl *D) {
0750     if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
0751       Visit(TD->getTypeForDecl());
0752   }
0753 
0754   void VisitFriendDecl(const FriendDecl *D) {
0755     if (D->getFriendType()) {
0756       // Traverse any CXXRecordDecl owned by this type, since
0757       // it will not be in the parent context:
0758       if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
0759         if (auto *TD = ET->getOwnedTagDecl())
0760           Visit(TD);
0761     } else {
0762       Visit(D->getFriendDecl());
0763     }
0764   }
0765 
0766   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
0767     if (D->isThisDeclarationADefinition())
0768       dumpDeclContext(D);
0769     else
0770       for (const ParmVarDecl *Parameter : D->parameters())
0771         Visit(Parameter);
0772 
0773     if (D->hasBody())
0774       Visit(D->getBody());
0775   }
0776 
0777   void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
0778     dumpObjCTypeParamList(D->getTypeParamList());
0779   }
0780 
0781   void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
0782     dumpObjCTypeParamList(D->getTypeParamListAsWritten());
0783   }
0784 
0785   void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
0786     for (const auto &I : D->inits())
0787       Visit(I);
0788   }
0789 
0790   void VisitBlockDecl(const BlockDecl *D) {
0791     for (const auto &I : D->parameters())
0792       Visit(I);
0793 
0794     for (const auto &I : D->captures())
0795       Visit(I);
0796     Visit(D->getBody());
0797   }
0798 
0799   void VisitDeclStmt(const DeclStmt *Node) {
0800     for (const auto &D : Node->decls())
0801       Visit(D);
0802   }
0803 
0804   void VisitAttributedStmt(const AttributedStmt *Node) {
0805     for (const auto *A : Node->getAttrs())
0806       Visit(A);
0807   }
0808 
0809   void VisitLabelStmt(const LabelStmt *Node) {
0810     if (Node->getDecl()->hasAttrs()) {
0811       for (const auto *A : Node->getDecl()->getAttrs())
0812         Visit(A);
0813     }
0814   }
0815 
0816   void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
0817     Visit(Node->getExceptionDecl());
0818   }
0819 
0820   void VisitCapturedStmt(const CapturedStmt *Node) {
0821     Visit(Node->getCapturedDecl());
0822   }
0823 
0824   void VisitSYCLKernelCallStmt(const SYCLKernelCallStmt *Node) {
0825     Visit(Node->getOriginalStmt());
0826     if (Traversal != TK_IgnoreUnlessSpelledInSource)
0827       Visit(Node->getOutlinedFunctionDecl());
0828   }
0829 
0830   void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) {
0831     for (const auto *C : Node->clauses())
0832       Visit(C);
0833   }
0834 
0835   void VisitOpenACCConstructStmt(const OpenACCConstructStmt *Node) {
0836     for (const auto *C : Node->clauses())
0837       Visit(C);
0838   }
0839 
0840   void VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *Node) {
0841     // Needs custom child checking to put clauses AFTER the children, which are
0842     // the expressions in the 'wait' construct. Others likely need this as well,
0843     // and might need to do the associated statement after it.
0844     for (const Stmt *S : Node->children())
0845       Visit(S);
0846     for (const auto *C : Node->clauses())
0847       Visit(C);
0848   }
0849 
0850   void VisitInitListExpr(const InitListExpr *ILE) {
0851     if (auto *Filler = ILE->getArrayFiller()) {
0852       Visit(Filler, "array_filler");
0853     }
0854   }
0855 
0856   void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
0857     if (auto *Filler = PLIE->getArrayFiller()) {
0858       Visit(Filler, "array_filler");
0859     }
0860   }
0861 
0862   void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
0863 
0864   void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
0865     if (Expr *Source = Node->getSourceExpr())
0866       Visit(Source);
0867   }
0868 
0869   void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
0870     if (E->isExprPredicate()) {
0871       Visit(E->getControllingExpr());
0872       Visit(E->getControllingExpr()->getType()); // FIXME: remove
0873     } else
0874       Visit(E->getControllingType()->getType());
0875 
0876     for (const auto Assoc : E->associations()) {
0877       Visit(Assoc);
0878     }
0879   }
0880 
0881   void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *E) {
0882     if (E->hasExplicitTemplateArgs())
0883       for (auto Arg : E->template_arguments())
0884         Visit(Arg.getArgument());
0885   }
0886 
0887   void VisitRequiresExpr(const RequiresExpr *E) {
0888     for (auto *D : E->getLocalParameters())
0889       Visit(D);
0890     for (auto *R : E->getRequirements())
0891       Visit(R);
0892   }
0893 
0894   void VisitTypeTraitExpr(const TypeTraitExpr *E) {
0895     // Argument types are not children of the TypeTraitExpr.
0896     for (auto *A : E->getArgs())
0897       Visit(A->getType());
0898   }
0899 
0900   void VisitLambdaExpr(const LambdaExpr *Node) {
0901     if (Traversal == TK_IgnoreUnlessSpelledInSource) {
0902       for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) {
0903         const auto *C = Node->capture_begin() + I;
0904         if (!C->isExplicit())
0905           continue;
0906         if (Node->isInitCapture(C))
0907           Visit(C->getCapturedVar());
0908         else
0909           Visit(Node->capture_init_begin()[I]);
0910       }
0911       dumpTemplateParameters(Node->getTemplateParameterList());
0912       for (const auto *P : Node->getCallOperator()->parameters())
0913         Visit(P);
0914       Visit(Node->getBody());
0915     } else {
0916       return Visit(Node->getLambdaClass());
0917     }
0918   }
0919 
0920   void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
0921     if (Node->isPartiallySubstituted())
0922       for (const auto &A : Node->getPartialArguments())
0923         Visit(A);
0924   }
0925 
0926   void VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) {
0927     Visit(E->getParameter());
0928   }
0929   void VisitSubstNonTypeTemplateParmPackExpr(
0930       const SubstNonTypeTemplateParmPackExpr *E) {
0931     Visit(E->getParameterPack());
0932     Visit(E->getArgumentPack());
0933   }
0934 
0935   void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
0936     if (const VarDecl *CatchParam = Node->getCatchParamDecl())
0937       Visit(CatchParam);
0938   }
0939 
0940   void VisitCXXForRangeStmt(const CXXForRangeStmt *Node) {
0941     if (Traversal == TK_IgnoreUnlessSpelledInSource) {
0942       Visit(Node->getInit());
0943       Visit(Node->getLoopVariable());
0944       Visit(Node->getRangeInit());
0945       Visit(Node->getBody());
0946     }
0947   }
0948 
0949   void VisitCallExpr(const CallExpr *Node) {
0950     for (const auto *Child :
0951          make_filter_range(Node->children(), [this](const Stmt *Child) {
0952            if (Traversal != TK_IgnoreUnlessSpelledInSource)
0953              return false;
0954            return !isa<CXXDefaultArgExpr>(Child);
0955          })) {
0956       Visit(Child);
0957     }
0958   }
0959 
0960   void VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *Node) {
0961     if (Traversal == TK_IgnoreUnlessSpelledInSource) {
0962       Visit(Node->getLHS());
0963       Visit(Node->getRHS());
0964     } else {
0965       ConstStmtVisitor<Derived>::VisitCXXRewrittenBinaryOperator(Node);
0966     }
0967   }
0968 
0969   void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
0970     Visit(TA.getAsExpr());
0971   }
0972 
0973   void VisitTypeTemplateArgument(const TemplateArgument &TA) {
0974     Visit(TA.getAsType());
0975   }
0976 
0977   void VisitPackTemplateArgument(const TemplateArgument &TA) {
0978     for (const auto &TArg : TA.pack_elements())
0979       Visit(TArg);
0980   }
0981 
0982   void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) {
0983     Visit(Node->getExpr());
0984   }
0985 
0986   void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {
0987     Visit(Node->getExpr());
0988   }
0989 
0990   // Implements Visit methods for Attrs.
0991 #include "clang/AST/AttrNodeTraverse.inc"
0992 };
0993 
0994 } // namespace clang
0995 
0996 #endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H