//===--- ASTNodeTraverser.h - Traversal of AST nodes ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the AST traversal facilities.  Other users
// of this class may make use of the same traversal logic by inheriting it,
// similar to RecursiveASTVisitor.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H
#define LLVM_CLANG_AST_ASTNODETRAVERSER_H

#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/AttrVisitor.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/LocInfoType.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TemplateArgumentVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeVisitor.h"

namespace clang {

class APValue;

/**

ASTNodeTraverser traverses the Clang AST for dumping purposes.

The `Derived::doGetNodeDelegate()` method is required to be an accessible member
which returns a reference of type `NodeDelegateType &` which implements the
following interface:

struct {
  template <typename Fn> void AddChild(Fn DoAddChild);
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild);

  void Visit(const comments::Comment *C, const comments::FullComment *FC);
  void Visit(const Attr *A);
  void Visit(const TemplateArgument &TA, SourceRange R = {},
             const Decl *From = nullptr, StringRef Label = {});
  void Visit(const Stmt *Node);
  void Visit(const Type *T);
  void Visit(QualType T);
  void Visit(const Decl *D);
  void Visit(const CXXCtorInitializer *Init);
  void Visit(const OMPClause *C);
  void Visit(const BlockDecl::Capture &C);
  void Visit(const GenericSelectionExpr::ConstAssociation &A);
  void Visit(const concepts::Requirement *R);
  void Visit(const APValue &Value, QualType Ty);
};
*/
template <typename Derived, typename NodeDelegateType>
class ASTNodeTraverser
    : public ConstDeclVisitor<Derived>,
      public ConstStmtVisitor<Derived>,
      public comments::ConstCommentVisitor<Derived, void,
                                           const comments::FullComment *>,
      public TypeVisitor<Derived>,
      public ConstAttrVisitor<Derived>,
      public ConstTemplateArgumentVisitor<Derived> {

  /// Indicates whether we should trigger deserialization of nodes that had
  /// not already been loaded.
  bool Deserialize = false;

  TraversalKind Traversal = TraversalKind::TK_AsIs;

  NodeDelegateType &getNodeDelegate() {
    return getDerived().doGetNodeDelegate();
  }
  Derived &getDerived() { return *static_cast<Derived *>(this); }

public:
  void setDeserialize(bool D) { Deserialize = D; }
  bool getDeserialize() const { return Deserialize; }

  void SetTraversalKind(TraversalKind TK) { Traversal = TK; }
  TraversalKind GetTraversalKind() const { return Traversal; }

  void Visit(const Decl *D) {
    if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isImplicit())
      return;

    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(D);
      if (!D)
        return;

      ConstDeclVisitor<Derived>::Visit(D);

      for (const auto &A : D->attrs())
        Visit(A);

      if (const comments::FullComment *Comment =
              D->getASTContext().getLocalCommentForDeclUncached(D))
        Visit(Comment, Comment);

      // Decls within functions are visited by the body.
      if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
        if (Traversal != TK_AsIs) {
          if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
            auto SK = CTSD->getSpecializationKind();
            if (SK == TSK_ExplicitInstantiationDeclaration ||
                SK == TSK_ExplicitInstantiationDefinition)
              return;
          }
        }
        if (const auto *DC = dyn_cast<DeclContext>(D))
          dumpDeclContext(DC);
      }
    });
  }

  void Visit(const Stmt *Node, StringRef Label = {}) {
    getNodeDelegate().AddChild(Label, [=] {
      const Stmt *S = Node;

      if (auto *E = dyn_cast_or_null<Expr>(S)) {
        switch (Traversal) {
        case TK_AsIs:
          break;
        case TK_IgnoreUnlessSpelledInSource:
          S = E->IgnoreUnlessSpelledInSource();
          break;
        }
      }

      getNodeDelegate().Visit(S);

      if (!S) {
        return;
      }

      ConstStmtVisitor<Derived>::Visit(S);

      // Some statements have custom mechanisms for dumping their children.
      if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S) ||
          isa<RequiresExpr>(S))
        return;

      if (Traversal == TK_IgnoreUnlessSpelledInSource &&
          isa<LambdaExpr, CXXForRangeStmt, CallExpr,
              CXXRewrittenBinaryOperator>(S))
        return;

      for (const Stmt *SubStmt : S->children())
        Visit(SubStmt);
    });
  }

  void Visit(QualType T) {
    SplitQualType SQT = T.split();
    if (!SQT.Quals.hasQualifiers())
      return Visit(SQT.Ty);

    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(T);
      Visit(T.split().Ty);
    });
  }

  void Visit(const Type *T) {
    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(T);
      if (!T)
        return;
      TypeVisitor<Derived>::Visit(T);

      QualType SingleStepDesugar =
          T->getLocallyUnqualifiedSingleStepDesugaredType();
      if (SingleStepDesugar != QualType(T, 0))
        Visit(SingleStepDesugar);
    });
  }

  void Visit(const Attr *A) {
    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(A);
      ConstAttrVisitor<Derived>::Visit(A);
    });
  }

  void Visit(const CXXCtorInitializer *Init) {
    if (Traversal == TK_IgnoreUnlessSpelledInSource && !Init->isWritten())
      return;
    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(Init);
      Visit(Init->getInit());
    });
  }

  void Visit(const TemplateArgument &A, SourceRange R = {},
             const Decl *From = nullptr, const char *Label = nullptr) {
    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(A, R, From, Label);
      ConstTemplateArgumentVisitor<Derived>::Visit(A);
    });
  }

  void Visit(const BlockDecl::Capture &C) {
    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(C);
      if (C.hasCopyExpr())
        Visit(C.getCopyExpr());
    });
  }

  void Visit(const OMPClause *C) {
    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(C);
      for (const auto *S : C->children())
        Visit(S);
    });
  }

  void Visit(const GenericSelectionExpr::ConstAssociation &A) {
    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(A);
      if (const TypeSourceInfo *TSI = A.getTypeSourceInfo())
        Visit(TSI->getType());
      Visit(A.getAssociationExpr());
    });
  }

  void Visit(const concepts::Requirement *R) {
    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(R);
      if (!R)
        return;
      if (auto *TR = dyn_cast<concepts::TypeRequirement>(R)) {
        if (!TR->isSubstitutionFailure())
          Visit(TR->getType()->getType().getTypePtr());
      } else if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
        if (!ER->isExprSubstitutionFailure())
          Visit(ER->getExpr());
        if (!ER->getReturnTypeRequirement().isEmpty())
          Visit(ER->getReturnTypeRequirement()
                    .getTypeConstraint()
                    ->getImmediatelyDeclaredConstraint());
      } else if (auto *NR = dyn_cast<concepts::NestedRequirement>(R)) {
        if (!NR->hasInvalidConstraint())
          Visit(NR->getConstraintExpr());
      }
    });
  }

  void Visit(const APValue &Value, QualType Ty) {
    getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); });
  }

  void Visit(const comments::Comment *C, const comments::FullComment *FC) {
    getNodeDelegate().AddChild([=] {
      getNodeDelegate().Visit(C, FC);
      if (!C) {
        return;
      }
      comments::ConstCommentVisitor<Derived, void,
                                    const comments::FullComment *>::visit(C,
                                                                          FC);
      for (comments::Comment::child_iterator I = C->child_begin(),
                                             E = C->child_end();
           I != E; ++I)
        Visit(*I, FC);
    });
  }

  void Visit(const DynTypedNode &N) {
    // FIXME: Improve this with a switch or a visitor pattern.
    if (const auto *D = N.get<Decl>())
      Visit(D);
    else if (const auto *S = N.get<Stmt>())
      Visit(S);
    else if (const auto *QT = N.get<QualType>())
      Visit(*QT);
    else if (const auto *T = N.get<Type>())
      Visit(T);
    else if (const auto *C = N.get<CXXCtorInitializer>())
      Visit(C);
    else if (const auto *C = N.get<OMPClause>())
      Visit(C);
    else if (const auto *T = N.get<TemplateArgument>())
      Visit(*T);
  }

  void dumpDeclContext(const DeclContext *DC) {
    if (!DC)
      return;

    for (const auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
      Visit(D);
  }

  void dumpTemplateParameters(const TemplateParameterList *TPL) {
    if (!TPL)
      return;

    for (const auto &TP : *TPL)
      Visit(TP);

    if (const Expr *RC = TPL->getRequiresClause())
      Visit(RC);
  }

  void
  dumpASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *TALI) {
    if (!TALI)
      return;

    for (const auto &TA : TALI->arguments())
      dumpTemplateArgumentLoc(TA);
  }

  void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
                               const Decl *From = nullptr,
                               const char *Label = nullptr) {
    Visit(A.getArgument(), A.getSourceRange(), From, Label);
  }

  void dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
    for (unsigned i = 0, e = TAL.size(); i < e; ++i)
      Visit(TAL[i]);
  }

  void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
    if (!typeParams)
      return;

    for (const auto &typeParam : *typeParams) {
      Visit(typeParam);
    }
  }

  void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); }
  void VisitLocInfoType(const LocInfoType *T) {
    Visit(T->getTypeSourceInfo()->getType());
  }
  void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); }
  void VisitBlockPointerType(const BlockPointerType *T) {
    Visit(T->getPointeeType());
  }
  void VisitReferenceType(const ReferenceType *T) {
    Visit(T->getPointeeType());
  }
  void VisitMemberPointerType(const MemberPointerType *T) {
    Visit(T->getClass());
    Visit(T->getPointeeType());
  }
  void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
  void VisitVariableArrayType(const VariableArrayType *T) {
    VisitArrayType(T);
    Visit(T->getSizeExpr());
  }
  void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
    Visit(T->getElementType());
    Visit(T->getSizeExpr());
  }
  void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
    Visit(T->getElementType());
    Visit(T->getSizeExpr());
  }
  void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); }
  void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); }
  void VisitFunctionProtoType(const FunctionProtoType *T) {
    VisitFunctionType(T);
    for (const QualType &PT : T->getParamTypes())
      Visit(PT);
  }
  void VisitTypeOfExprType(const TypeOfExprType *T) {
    Visit(T->getUnderlyingExpr());
  }
  void VisitDecltypeType(const DecltypeType *T) {
    Visit(T->getUnderlyingExpr());
  }
  void VisitUnaryTransformType(const UnaryTransformType *T) {
    Visit(T->getBaseType());
  }
  void VisitAttributedType(const AttributedType *T) {
    // FIXME: AttrKind
    if (T->getModifiedType() != T->getEquivalentType())
      Visit(T->getModifiedType());
  }
  void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
    Visit(T->getWrappedType());
  }
  void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {}
  void
  VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
    Visit(T->getArgumentPack());
  }
  void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
    for (const auto &Arg : T->template_arguments())
      Visit(Arg);
  }
  void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
    Visit(T->getPointeeType());
  }
  void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); }
  void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); }
  void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); }
  void VisitPackExpansionType(const PackExpansionType *T) {
    if (!T->isSugared())
      Visit(T->getPattern());
  }
  // FIXME: ElaboratedType, DependentNameType,
  // DependentTemplateSpecializationType, ObjCObjectType

  void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }

  void VisitEnumConstantDecl(const EnumConstantDecl *D) {
    if (const Expr *Init = D->getInitExpr())
      Visit(Init);
  }

  void VisitFunctionDecl(const FunctionDecl *D) {
    if (const auto *FTSI = D->getTemplateSpecializationInfo())
      dumpTemplateArgumentList(*FTSI->TemplateArguments);

    if (D->param_begin())
      for (const auto *Parameter : D->parameters())
        Visit(Parameter);

    if (const Expr *TRC = D->getTrailingRequiresClause())
      Visit(TRC);

    if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isDefaulted())
      return;

    if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
      for (const auto *I : C->inits())
        Visit(I);

    if (D->doesThisDeclarationHaveABody())
      Visit(D->getBody());
  }

  void VisitFieldDecl(const FieldDecl *D) {
    if (D->isBitField())
      Visit(D->getBitWidth());
    if (Expr *Init = D->getInClassInitializer())
      Visit(Init);
  }

  void VisitVarDecl(const VarDecl *D) {
    if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isCXXForRangeDecl())
      return;

    if (D->hasInit())
      Visit(D->getInit());
  }

  void VisitDecompositionDecl(const DecompositionDecl *D) {
    VisitVarDecl(D);
    for (const auto *B : D->bindings())
      Visit(B);
  }

  void VisitBindingDecl(const BindingDecl *D) {
    if (Traversal == TK_IgnoreUnlessSpelledInSource)
      return;

    if (const auto *V = D->getHoldingVar())
      Visit(V);

    if (const auto *E = D->getBinding())
      Visit(E);
  }

  void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
    Visit(D->getAsmString());
  }

  void VisitTopLevelStmtDecl(const TopLevelStmtDecl *D) { Visit(D->getStmt()); }

  void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }

  void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
    for (const auto *E : D->varlists())
      Visit(E);
  }

  void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
    Visit(D->getCombiner());
    if (const auto *Initializer = D->getInitializer())
      Visit(Initializer);
  }

  void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {
    for (const auto *C : D->clauselists())
      Visit(C);
  }

  void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
    Visit(D->getInit());
  }

  void VisitOMPAllocateDecl(const OMPAllocateDecl *D) {
    for (const auto *E : D->varlists())
      Visit(E);
    for (const auto *C : D->clauselists())
      Visit(C);
  }

  template <typename SpecializationDecl>
  void dumpTemplateDeclSpecialization(const SpecializationDecl *D) {
    for (const auto *RedeclWithBadType : D->redecls()) {
      // FIXME: The redecls() range sometimes has elements of a less-specific
      // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
      // us TagDecls, and should give CXXRecordDecls).
      auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
      if (!Redecl) {
        // Found the injected-class-name for a class template. This will be
        // dumped as part of its surrounding class so we don't need to dump it
        // here.
        assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
               "expected an injected-class-name");
        continue;
      }
      Visit(Redecl);
    }
  }

  template <typename TemplateDecl>
  void dumpTemplateDecl(const TemplateDecl *D) {
    dumpTemplateParameters(D->getTemplateParameters());

    Visit(D->getTemplatedDecl());

    if (Traversal == TK_AsIs) {
      for (const auto *Child : D->specializations())
        dumpTemplateDeclSpecialization(Child);
    }
  }

  void VisitTypeAliasDecl(const TypeAliasDecl *D) {
    Visit(D->getUnderlyingType());
  }

  void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
    dumpTemplateParameters(D->getTemplateParameters());
    Visit(D->getTemplatedDecl());
  }

  void VisitStaticAssertDecl(const StaticAssertDecl *D) {
    Visit(D->getAssertExpr());
    Visit(D->getMessage());
  }

  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
    dumpTemplateDecl(D);
  }

  void VisitClassTemplateDecl(const ClassTemplateDecl *D) {
    dumpTemplateDecl(D);
  }

  void VisitClassTemplateSpecializationDecl(
      const ClassTemplateSpecializationDecl *D) {
    dumpTemplateArgumentList(D->getTemplateArgs());
  }

  void VisitClassTemplatePartialSpecializationDecl(
      const ClassTemplatePartialSpecializationDecl *D) {
    VisitClassTemplateSpecializationDecl(D);
    dumpTemplateParameters(D->getTemplateParameters());
  }

  void VisitClassScopeFunctionSpecializationDecl(
      const ClassScopeFunctionSpecializationDecl *D) {
    Visit(D->getSpecialization());
    dumpASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
  }
  void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); }

  void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
    dumpTemplateParameters(D->getTemplateParameters());
  }

  void
  VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) {
    dumpTemplateArgumentList(D->getTemplateArgs());
    VisitVarDecl(D);
  }

  void VisitVarTemplatePartialSpecializationDecl(
      const VarTemplatePartialSpecializationDecl *D) {
    dumpTemplateParameters(D->getTemplateParameters());
    VisitVarTemplateSpecializationDecl(D);
  }

  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
    if (const auto *TC = D->getTypeConstraint())
      Visit(TC->getImmediatelyDeclaredConstraint());
    if (D->hasDefaultArgument())
      Visit(D->getDefaultArgument(), SourceRange(),
            D->getDefaultArgStorage().getInheritedFrom(),
            D->defaultArgumentWasInherited() ? "inherited from" : "previous");
  }

  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
    if (const auto *E = D->getPlaceholderTypeConstraint())
      Visit(E);
    if (D->hasDefaultArgument())
      Visit(D->getDefaultArgument(), SourceRange(),
            D->getDefaultArgStorage().getInheritedFrom(),
            D->defaultArgumentWasInherited() ? "inherited from" : "previous");
  }

  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
    dumpTemplateParameters(D->getTemplateParameters());
    if (D->hasDefaultArgument())
      dumpTemplateArgumentLoc(
          D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
          D->defaultArgumentWasInherited() ? "inherited from" : "previous");
  }

  void VisitConceptDecl(const ConceptDecl *D) {
    dumpTemplateParameters(D->getTemplateParameters());
    Visit(D->getConstraintExpr());
  }

  void VisitImplicitConceptSpecializationDecl(
      const ImplicitConceptSpecializationDecl *CSD) {
    for (const TemplateArgument &Arg : CSD->getTemplateArguments())
      Visit(Arg);
  }

  void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) {
    Visit(CSE->getSpecializationDecl());
    if (CSE->hasExplicitTemplateArgs())
      for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments())
        dumpTemplateArgumentLoc(ArgLoc);
  }

  void VisitUsingShadowDecl(const UsingShadowDecl *D) {
    if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
      Visit(TD->getTypeForDecl());
  }

  void VisitFriendDecl(const FriendDecl *D) {
    if (D->getFriendType()) {
      // Traverse any CXXRecordDecl owned by this type, since
      // it will not be in the parent context:
      if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
        if (auto *TD = ET->getOwnedTagDecl())
          Visit(TD);
    } else {
      Visit(D->getFriendDecl());
    }
  }

  void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
    if (D->isThisDeclarationADefinition())
      dumpDeclContext(D);
    else
      for (const ParmVarDecl *Parameter : D->parameters())
        Visit(Parameter);

    if (D->hasBody())
      Visit(D->getBody());
  }

  void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
    dumpObjCTypeParamList(D->getTypeParamList());
  }

  void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
    dumpObjCTypeParamList(D->getTypeParamListAsWritten());
  }

  void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
    for (const auto &I : D->inits())
      Visit(I);
  }

  void VisitBlockDecl(const BlockDecl *D) {
    for (const auto &I : D->parameters())
      Visit(I);

    for (const auto &I : D->captures())
      Visit(I);
    Visit(D->getBody());
  }

  void VisitDeclStmt(const DeclStmt *Node) {
    for (const auto &D : Node->decls())
      Visit(D);
  }

  void VisitAttributedStmt(const AttributedStmt *Node) {
    for (const auto *A : Node->getAttrs())
      Visit(A);
  }

  void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
    Visit(Node->getExceptionDecl());
  }

  void VisitCapturedStmt(const CapturedStmt *Node) {
    Visit(Node->getCapturedDecl());
  }

  void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) {
    for (const auto *C : Node->clauses())
      Visit(C);
  }

  void VisitInitListExpr(const InitListExpr *ILE) {
    if (auto *Filler = ILE->getArrayFiller()) {
      Visit(Filler, "array_filler");
    }
  }

  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
    if (auto *Filler = PLIE->getArrayFiller()) {
      Visit(Filler, "array_filler");
    }
  }

  void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }

  void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
    if (Expr *Source = Node->getSourceExpr())
      Visit(Source);
  }

  void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
    Visit(E->getControllingExpr());
    Visit(E->getControllingExpr()->getType()); // FIXME: remove

    for (const auto Assoc : E->associations()) {
      Visit(Assoc);
    }
  }

  void VisitRequiresExpr(const RequiresExpr *E) {
    for (auto *D : E->getLocalParameters())
      Visit(D);
    for (auto *R : E->getRequirements())
      Visit(R);
  }

  void VisitLambdaExpr(const LambdaExpr *Node) {
    if (Traversal == TK_IgnoreUnlessSpelledInSource) {
      for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) {
        const auto *C = Node->capture_begin() + I;
        if (!C->isExplicit())
          continue;
        if (Node->isInitCapture(C))
          Visit(C->getCapturedVar());
        else
          Visit(Node->capture_init_begin()[I]);
      }
      dumpTemplateParameters(Node->getTemplateParameterList());
      for (const auto *P : Node->getCallOperator()->parameters())
        Visit(P);
      Visit(Node->getBody());
    } else {
      return Visit(Node->getLambdaClass());
    }
  }

  void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
    if (Node->isPartiallySubstituted())
      for (const auto &A : Node->getPartialArguments())
        Visit(A);
  }

  void VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) {
    Visit(E->getParameter());
  }
  void VisitSubstNonTypeTemplateParmPackExpr(
      const SubstNonTypeTemplateParmPackExpr *E) {
    Visit(E->getParameterPack());
    Visit(E->getArgumentPack());
  }

  void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
    if (const VarDecl *CatchParam = Node->getCatchParamDecl())
      Visit(CatchParam);
  }

  void VisitCXXForRangeStmt(const CXXForRangeStmt *Node) {
    if (Traversal == TK_IgnoreUnlessSpelledInSource) {
      Visit(Node->getInit());
      Visit(Node->getLoopVariable());
      Visit(Node->getRangeInit());
      Visit(Node->getBody());
    }
  }

  void VisitCallExpr(const CallExpr *Node) {
    for (const auto *Child :
         make_filter_range(Node->children(), [this](const Stmt *Child) {
           if (Traversal != TK_IgnoreUnlessSpelledInSource)
             return false;
           return !isa<CXXDefaultArgExpr>(Child);
         })) {
      Visit(Child);
    }
  }

  void VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *Node) {
    if (Traversal == TK_IgnoreUnlessSpelledInSource) {
      Visit(Node->getLHS());
      Visit(Node->getRHS());
    } else {
      ConstStmtVisitor<Derived>::VisitCXXRewrittenBinaryOperator(Node);
    }
  }

  void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
    Visit(TA.getAsExpr());
  }

  void VisitTypeTemplateArgument(const TemplateArgument &TA) {
    Visit(TA.getAsType());
  }

  void VisitPackTemplateArgument(const TemplateArgument &TA) {
    for (const auto &TArg : TA.pack_elements())
      Visit(TArg);
  }

  // Implements Visit methods for Attrs.
#include "clang/AST/AttrNodeTraverse.inc"
};

} // namespace clang

#endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H
