ASTNodeTraverser.h 25 KB

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