Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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