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