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 getNodeDelegate()89 NodeDelegateType &getNodeDelegate() { 90 return getDerived().doGetNodeDelegate(); 91 } getDerived()92 Derived &getDerived() { return *static_cast<Derived *>(this); } 93 94 public: setDeserialize(bool D)95 void setDeserialize(bool D) { Deserialize = D; } getDeserialize()96 bool getDeserialize() const { return Deserialize; } 97 SetTraversalKind(TraversalKind TK)98 void SetTraversalKind(TraversalKind TK) { Traversal = TK; } GetTraversalKind()99 TraversalKind GetTraversalKind() const { return Traversal; } 100 101 void Visit(const Decl *D, bool VisitLocs = false) { 102 if (Traversal == TK_IgnoreUnlessSpelledInSource && D && 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 Visit(QualType T)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 Visit(const Type * T)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 Visit(TypeLoc T)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 Visit(const Attr * A)211 void Visit(const Attr *A) { 212 getNodeDelegate().AddChild([=] { 213 getNodeDelegate().Visit(A); 214 ConstAttrVisitor<Derived>::Visit(A); 215 }); 216 } 217 Visit(const CXXCtorInitializer * Init)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 Visit(const BlockDecl::Capture & C)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 Visit(const OpenACCClause * C)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 Visit(const OMPClause * C)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 Visit(const GenericSelectionExpr::ConstAssociation & A)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 Visit(const concepts::Requirement * R)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 Visit(const ConceptReference * R)290 void Visit(const ConceptReference *R) { 291 getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(R); }); 292 } 293 Visit(const APValue & Value,QualType Ty)294 void Visit(const APValue &Value, QualType Ty) { 295 getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); }); 296 } 297 Visit(const comments::Comment * C,const comments::FullComment * FC)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 Visit(const DynTypedNode & N)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 dumpDeclContext(const DeclContext * DC)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 dumpTemplateParameters(const TemplateParameterList * TPL)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 dumpASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo * TALI)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 dumpTemplateArgumentList(const TemplateArgumentList & TAL)370 void dumpTemplateArgumentList(const TemplateArgumentList &TAL) { 371 for (unsigned i = 0, e = TAL.size(); i < e; ++i) 372 Visit(TAL[i]); 373 } 374 dumpObjCTypeParamList(const ObjCTypeParamList * typeParams)375 void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) { 376 if (!typeParams) 377 return; 378 379 for (const auto &typeParam : *typeParams) { 380 Visit(typeParam); 381 } 382 } 383 VisitComplexType(const ComplexType * T)384 void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); } VisitLocInfoType(const LocInfoType * T)385 void VisitLocInfoType(const LocInfoType *T) { 386 Visit(T->getTypeSourceInfo()->getTypeLoc()); 387 } VisitPointerType(const PointerType * T)388 void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); } VisitBlockPointerType(const BlockPointerType * T)389 void VisitBlockPointerType(const BlockPointerType *T) { 390 Visit(T->getPointeeType()); 391 } VisitReferenceType(const ReferenceType * T)392 void VisitReferenceType(const ReferenceType *T) { 393 Visit(T->getPointeeType()); 394 } VisitMemberPointerType(const MemberPointerType * T)395 void VisitMemberPointerType(const MemberPointerType *T) { 396 // FIXME: Provide a NestedNameSpecifier visitor. 397 NestedNameSpecifier *Qualifier = T->getQualifier(); 398 if (NestedNameSpecifier::SpecifierKind K = Qualifier->getKind(); 399 K == NestedNameSpecifier::TypeSpec) 400 Visit(Qualifier->getAsType()); 401 if (T->isSugared()) 402 Visit(T->getMostRecentCXXRecordDecl()->getTypeForDecl()); 403 Visit(T->getPointeeType()); 404 } VisitArrayType(const ArrayType * T)405 void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); } VisitVariableArrayType(const VariableArrayType * T)406 void VisitVariableArrayType(const VariableArrayType *T) { 407 VisitArrayType(T); 408 Visit(T->getSizeExpr()); 409 } VisitDependentSizedArrayType(const DependentSizedArrayType * T)410 void VisitDependentSizedArrayType(const DependentSizedArrayType *T) { 411 Visit(T->getElementType()); 412 Visit(T->getSizeExpr()); 413 } VisitDependentSizedExtVectorType(const DependentSizedExtVectorType * T)414 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) { 415 Visit(T->getElementType()); 416 Visit(T->getSizeExpr()); 417 } VisitVectorType(const VectorType * T)418 void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); } VisitFunctionType(const FunctionType * T)419 void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); } VisitFunctionProtoType(const FunctionProtoType * T)420 void VisitFunctionProtoType(const FunctionProtoType *T) { 421 VisitFunctionType(T); 422 for (const QualType &PT : T->getParamTypes()) 423 Visit(PT); 424 } VisitTypeOfExprType(const TypeOfExprType * T)425 void VisitTypeOfExprType(const TypeOfExprType *T) { 426 Visit(T->getUnderlyingExpr()); 427 } VisitDecltypeType(const DecltypeType * T)428 void VisitDecltypeType(const DecltypeType *T) { 429 Visit(T->getUnderlyingExpr()); 430 } 431 VisitPackIndexingType(const PackIndexingType * T)432 void VisitPackIndexingType(const PackIndexingType *T) { 433 Visit(T->getPattern()); 434 Visit(T->getIndexExpr()); 435 } 436 VisitUnaryTransformType(const UnaryTransformType * T)437 void VisitUnaryTransformType(const UnaryTransformType *T) { 438 Visit(T->getBaseType()); 439 } VisitAttributedType(const AttributedType * T)440 void VisitAttributedType(const AttributedType *T) { 441 // FIXME: AttrKind 442 if (T->getModifiedType() != T->getEquivalentType()) 443 Visit(T->getModifiedType()); 444 } VisitBTFTagAttributedType(const BTFTagAttributedType * T)445 void VisitBTFTagAttributedType(const BTFTagAttributedType *T) { 446 Visit(T->getWrappedType()); 447 } VisitHLSLAttributedResourceType(const HLSLAttributedResourceType * T)448 void VisitHLSLAttributedResourceType(const HLSLAttributedResourceType *T) { 449 QualType Contained = T->getContainedType(); 450 if (!Contained.isNull()) 451 Visit(Contained); 452 } VisitHLSLInlineSpirvType(const HLSLInlineSpirvType * T)453 void VisitHLSLInlineSpirvType(const HLSLInlineSpirvType *T) { 454 for (auto &Operand : T->getOperands()) { 455 using SpirvOperandKind = SpirvOperand::SpirvOperandKind; 456 457 switch (Operand.getKind()) { 458 case SpirvOperandKind::ConstantId: 459 case SpirvOperandKind::Literal: 460 break; 461 462 case SpirvOperandKind::TypeId: 463 Visit(Operand.getResultType()); 464 break; 465 466 default: 467 llvm_unreachable("Invalid SpirvOperand kind!"); 468 } 469 } 470 } VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *)471 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {} 472 void VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType * T)473 VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) { 474 Visit(T->getArgumentPack()); 475 } VisitTemplateSpecializationType(const TemplateSpecializationType * T)476 void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { 477 for (const auto &Arg : T->template_arguments()) 478 Visit(Arg); 479 } VisitObjCObjectPointerType(const ObjCObjectPointerType * T)480 void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { 481 Visit(T->getPointeeType()); 482 } VisitAtomicType(const AtomicType * T)483 void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); } VisitPipeType(const PipeType * T)484 void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); } VisitAdjustedType(const AdjustedType * T)485 void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); } VisitPackExpansionType(const PackExpansionType * T)486 void VisitPackExpansionType(const PackExpansionType *T) { 487 if (!T->isSugared()) 488 Visit(T->getPattern()); 489 } VisitAutoType(const AutoType * T)490 void VisitAutoType(const AutoType *T) { 491 for (const auto &Arg : T->getTypeConstraintArguments()) 492 Visit(Arg); 493 } 494 // FIXME: ElaboratedType, DependentNameType, 495 // DependentTemplateSpecializationType, ObjCObjectType 496 497 // For TypeLocs, we automatically visit the inner type loc (pointee type etc). 498 // We must explicitly visit other lexically-nested nodes. VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL)499 void VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { 500 TypeLocVisitor<Derived>::VisitFunctionTypeLoc(TL); 501 for (const auto *Param : TL.getParams()) 502 Visit(Param, /*VisitTypeLocs=*/true); 503 } VisitAutoTypeLoc(AutoTypeLoc TL)504 void VisitAutoTypeLoc(AutoTypeLoc TL) { 505 if (const auto *CR = TL.getConceptReference()) { 506 if (auto *Args = CR->getTemplateArgsAsWritten()) 507 for (const auto &Arg : Args->arguments()) 508 dumpTemplateArgumentLoc(Arg); 509 } 510 } VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL)511 void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 512 // FIXME: Provide NestedNamespecifierLoc visitor. 513 Visit(TL.getQualifierLoc().getTypeLoc()); 514 } VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL)515 void VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { 516 Visit(TL.getSizeExpr()); 517 } VisitDependentSizedArrayTypeLoc(DependentSizedArrayTypeLoc TL)518 void VisitDependentSizedArrayTypeLoc(DependentSizedArrayTypeLoc TL) { 519 Visit(TL.getSizeExpr()); 520 } VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL)521 void VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) { 522 Visit(cast<DependentSizedExtVectorType>(TL.getType())->getSizeExpr()); 523 } VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL)524 void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 525 Visit(TL.getUnderlyingExpr()); 526 } VisitDecltypeType(DecltypeType TL)527 void VisitDecltypeType(DecltypeType TL) { 528 Visit(TL.getUnderlyingExpr()); 529 } VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)530 void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { 531 for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I) 532 dumpTemplateArgumentLoc(TL.getArgLoc(I)); 533 } VisitDependentTemplateSpecializationTypeLoc(DependentTemplateSpecializationTypeLoc TL)534 void VisitDependentTemplateSpecializationTypeLoc( 535 DependentTemplateSpecializationTypeLoc TL) { 536 for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I) 537 dumpTemplateArgumentLoc(TL.getArgLoc(I)); 538 } 539 VisitTypedefDecl(const TypedefDecl * D)540 void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); } 541 VisitEnumConstantDecl(const EnumConstantDecl * D)542 void VisitEnumConstantDecl(const EnumConstantDecl *D) { 543 if (const Expr *Init = D->getInitExpr()) 544 Visit(Init); 545 } 546 VisitFunctionDecl(const FunctionDecl * D)547 void VisitFunctionDecl(const FunctionDecl *D) { 548 if (FunctionTemplateSpecializationInfo *FTSI = 549 D->getTemplateSpecializationInfo()) 550 dumpTemplateArgumentList(*FTSI->TemplateArguments); 551 else if (DependentFunctionTemplateSpecializationInfo *DFTSI = 552 D->getDependentSpecializationInfo()) 553 dumpASTTemplateArgumentListInfo(DFTSI->TemplateArgumentsAsWritten); 554 555 if (D->param_begin()) 556 for (const auto *Parameter : D->parameters()) 557 Visit(Parameter); 558 559 if (const AssociatedConstraint &TRC = D->getTrailingRequiresClause()) 560 Visit(TRC.ConstraintExpr); 561 562 if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isDefaulted()) 563 return; 564 565 if (const auto *C = dyn_cast<CXXConstructorDecl>(D)) 566 for (const auto *I : C->inits()) 567 Visit(I); 568 569 if (D->doesThisDeclarationHaveABody()) 570 Visit(D->getBody()); 571 } 572 VisitFieldDecl(const FieldDecl * D)573 void VisitFieldDecl(const FieldDecl *D) { 574 if (D->isBitField()) 575 Visit(D->getBitWidth()); 576 if (Expr *Init = D->getInClassInitializer()) 577 Visit(Init); 578 } 579 VisitVarDecl(const VarDecl * D)580 void VisitVarDecl(const VarDecl *D) { 581 if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isCXXForRangeDecl()) 582 return; 583 584 if (const auto *TSI = D->getTypeSourceInfo(); VisitLocs && TSI) 585 Visit(TSI->getTypeLoc()); 586 if (D->hasInit()) 587 Visit(D->getInit()); 588 } 589 VisitDecompositionDecl(const DecompositionDecl * D)590 void VisitDecompositionDecl(const DecompositionDecl *D) { 591 VisitVarDecl(D); 592 for (const auto *B : D->bindings()) 593 Visit(B); 594 } 595 VisitBindingDecl(const BindingDecl * D)596 void VisitBindingDecl(const BindingDecl *D) { 597 if (Traversal == TK_IgnoreUnlessSpelledInSource) 598 return; 599 600 if (const auto *V = D->getHoldingVar()) 601 Visit(V); 602 603 if (const auto *E = D->getBinding()) 604 Visit(E); 605 } 606 VisitFileScopeAsmDecl(const FileScopeAsmDecl * D)607 void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 608 Visit(D->getAsmStringExpr()); 609 } 610 VisitTopLevelStmtDecl(const TopLevelStmtDecl * D)611 void VisitTopLevelStmtDecl(const TopLevelStmtDecl *D) { Visit(D->getStmt()); } 612 VisitOutlinedFunctionDecl(const OutlinedFunctionDecl * D)613 void VisitOutlinedFunctionDecl(const OutlinedFunctionDecl *D) { 614 for (const ImplicitParamDecl *Parameter : D->parameters()) 615 Visit(Parameter); 616 Visit(D->getBody()); 617 } 618 VisitCapturedDecl(const CapturedDecl * D)619 void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); } 620 VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl * D)621 void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { 622 for (const auto *E : D->varlist()) 623 Visit(E); 624 } 625 VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl * D)626 void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) { 627 Visit(D->getCombiner()); 628 if (const auto *Initializer = D->getInitializer()) 629 Visit(Initializer); 630 } 631 VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl * D)632 void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) { 633 for (const auto *C : D->clauselists()) 634 Visit(C); 635 } 636 VisitOMPCapturedExprDecl(const OMPCapturedExprDecl * D)637 void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { 638 Visit(D->getInit()); 639 } 640 VisitOMPAllocateDecl(const OMPAllocateDecl * D)641 void VisitOMPAllocateDecl(const OMPAllocateDecl *D) { 642 for (const auto *E : D->varlist()) 643 Visit(E); 644 for (const auto *C : D->clauselists()) 645 Visit(C); 646 } 647 648 template <typename SpecializationDecl> dumpTemplateDeclSpecialization(const SpecializationDecl * D)649 void dumpTemplateDeclSpecialization(const SpecializationDecl *D) { 650 for (const auto *RedeclWithBadType : D->redecls()) { 651 // FIXME: The redecls() range sometimes has elements of a less-specific 652 // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives 653 // us TagDecls, and should give CXXRecordDecls). 654 auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType); 655 if (!Redecl) { 656 // Found the injected-class-name for a class template. This will be 657 // dumped as part of its surrounding class so we don't need to dump it 658 // here. 659 assert(isa<CXXRecordDecl>(RedeclWithBadType) && 660 "expected an injected-class-name"); 661 continue; 662 } 663 Visit(Redecl); 664 } 665 } 666 667 template <typename TemplateDecl> dumpTemplateDecl(const TemplateDecl * D)668 void dumpTemplateDecl(const TemplateDecl *D) { 669 dumpTemplateParameters(D->getTemplateParameters()); 670 671 Visit(D->getTemplatedDecl()); 672 673 if (Traversal == TK_AsIs) { 674 for (const auto *Child : D->specializations()) 675 dumpTemplateDeclSpecialization(Child); 676 } 677 } 678 VisitTypeAliasDecl(const TypeAliasDecl * D)679 void VisitTypeAliasDecl(const TypeAliasDecl *D) { 680 Visit(D->getUnderlyingType()); 681 } 682 VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl * D)683 void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 684 dumpTemplateParameters(D->getTemplateParameters()); 685 Visit(D->getTemplatedDecl()); 686 } 687 VisitStaticAssertDecl(const StaticAssertDecl * D)688 void VisitStaticAssertDecl(const StaticAssertDecl *D) { 689 Visit(D->getAssertExpr()); 690 Visit(D->getMessage()); 691 } 692 VisitFunctionTemplateDecl(const FunctionTemplateDecl * D)693 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 694 dumpTemplateDecl(D); 695 } 696 VisitClassTemplateDecl(const ClassTemplateDecl * D)697 void VisitClassTemplateDecl(const ClassTemplateDecl *D) { 698 dumpTemplateDecl(D); 699 } 700 VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl * D)701 void VisitClassTemplateSpecializationDecl( 702 const ClassTemplateSpecializationDecl *D) { 703 dumpTemplateArgumentList(D->getTemplateArgs()); 704 } 705 VisitClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl * D)706 void VisitClassTemplatePartialSpecializationDecl( 707 const ClassTemplatePartialSpecializationDecl *D) { 708 VisitClassTemplateSpecializationDecl(D); 709 dumpTemplateParameters(D->getTemplateParameters()); 710 } 711 VisitVarTemplateDecl(const VarTemplateDecl * D)712 void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); } 713 VisitBuiltinTemplateDecl(const BuiltinTemplateDecl * D)714 void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { 715 dumpTemplateParameters(D->getTemplateParameters()); 716 } 717 718 void VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl * D)719 VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) { 720 dumpTemplateArgumentList(D->getTemplateArgs()); 721 VisitVarDecl(D); 722 } 723 VisitVarTemplatePartialSpecializationDecl(const VarTemplatePartialSpecializationDecl * D)724 void VisitVarTemplatePartialSpecializationDecl( 725 const VarTemplatePartialSpecializationDecl *D) { 726 dumpTemplateParameters(D->getTemplateParameters()); 727 VisitVarTemplateSpecializationDecl(D); 728 } 729 VisitTemplateTypeParmDecl(const TemplateTypeParmDecl * D)730 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 731 if (const auto *TC = D->getTypeConstraint()) 732 Visit(TC->getImmediatelyDeclaredConstraint()); 733 if (D->hasDefaultArgument()) 734 Visit(D->getDefaultArgument().getArgument(), SourceRange(), 735 D->getDefaultArgStorage().getInheritedFrom(), 736 D->defaultArgumentWasInherited() ? "inherited from" : "previous"); 737 } 738 VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl * D)739 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 740 if (const auto *E = D->getPlaceholderTypeConstraint()) 741 Visit(E); 742 if (D->hasDefaultArgument()) 743 dumpTemplateArgumentLoc( 744 D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(), 745 D->defaultArgumentWasInherited() ? "inherited from" : "previous"); 746 } 747 VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl * D)748 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) { 749 dumpTemplateParameters(D->getTemplateParameters()); 750 if (D->hasDefaultArgument()) 751 dumpTemplateArgumentLoc( 752 D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(), 753 D->defaultArgumentWasInherited() ? "inherited from" : "previous"); 754 } 755 VisitConceptDecl(const ConceptDecl * D)756 void VisitConceptDecl(const ConceptDecl *D) { 757 dumpTemplateParameters(D->getTemplateParameters()); 758 Visit(D->getConstraintExpr()); 759 } 760 VisitImplicitConceptSpecializationDecl(const ImplicitConceptSpecializationDecl * CSD)761 void VisitImplicitConceptSpecializationDecl( 762 const ImplicitConceptSpecializationDecl *CSD) { 763 for (const TemplateArgument &Arg : CSD->getTemplateArguments()) 764 Visit(Arg); 765 } 766 VisitConceptSpecializationExpr(const ConceptSpecializationExpr * CSE)767 void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) { 768 Visit(CSE->getSpecializationDecl()); 769 if (CSE->hasExplicitTemplateArgs()) 770 for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments()) 771 dumpTemplateArgumentLoc(ArgLoc); 772 } 773 VisitUsingShadowDecl(const UsingShadowDecl * D)774 void VisitUsingShadowDecl(const UsingShadowDecl *D) { 775 if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl())) 776 Visit(TD->getTypeForDecl()); 777 } 778 VisitFriendDecl(const FriendDecl * D)779 void VisitFriendDecl(const FriendDecl *D) { 780 if (D->getFriendType()) { 781 // Traverse any CXXRecordDecl owned by this type, since 782 // it will not be in the parent context: 783 if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>()) 784 if (auto *TD = ET->getOwnedTagDecl()) 785 Visit(TD); 786 } else { 787 Visit(D->getFriendDecl()); 788 } 789 } 790 VisitObjCMethodDecl(const ObjCMethodDecl * D)791 void VisitObjCMethodDecl(const ObjCMethodDecl *D) { 792 if (D->isThisDeclarationADefinition()) 793 dumpDeclContext(D); 794 else 795 for (const ParmVarDecl *Parameter : D->parameters()) 796 Visit(Parameter); 797 798 if (D->hasBody()) 799 Visit(D->getBody()); 800 } 801 VisitObjCCategoryDecl(const ObjCCategoryDecl * D)802 void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 803 dumpObjCTypeParamList(D->getTypeParamList()); 804 } 805 VisitObjCInterfaceDecl(const ObjCInterfaceDecl * D)806 void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 807 dumpObjCTypeParamList(D->getTypeParamListAsWritten()); 808 } 809 VisitObjCImplementationDecl(const ObjCImplementationDecl * D)810 void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 811 for (const auto &I : D->inits()) 812 Visit(I); 813 } 814 VisitBlockDecl(const BlockDecl * D)815 void VisitBlockDecl(const BlockDecl *D) { 816 for (const auto &I : D->parameters()) 817 Visit(I); 818 819 for (const auto &I : D->captures()) 820 Visit(I); 821 Visit(D->getBody()); 822 } 823 VisitDeclStmt(const DeclStmt * Node)824 void VisitDeclStmt(const DeclStmt *Node) { 825 for (const auto &D : Node->decls()) 826 Visit(D); 827 } 828 VisitAttributedStmt(const AttributedStmt * Node)829 void VisitAttributedStmt(const AttributedStmt *Node) { 830 for (const auto *A : Node->getAttrs()) 831 Visit(A); 832 } 833 VisitLabelStmt(const LabelStmt * Node)834 void VisitLabelStmt(const LabelStmt *Node) { 835 if (Node->getDecl()->hasAttrs()) { 836 for (const auto *A : Node->getDecl()->getAttrs()) 837 Visit(A); 838 } 839 } 840 VisitCXXCatchStmt(const CXXCatchStmt * Node)841 void VisitCXXCatchStmt(const CXXCatchStmt *Node) { 842 Visit(Node->getExceptionDecl()); 843 } 844 VisitCapturedStmt(const CapturedStmt * Node)845 void VisitCapturedStmt(const CapturedStmt *Node) { 846 Visit(Node->getCapturedDecl()); 847 } 848 VisitSYCLKernelCallStmt(const SYCLKernelCallStmt * Node)849 void VisitSYCLKernelCallStmt(const SYCLKernelCallStmt *Node) { 850 Visit(Node->getOriginalStmt()); 851 if (Traversal != TK_IgnoreUnlessSpelledInSource) 852 Visit(Node->getOutlinedFunctionDecl()); 853 } 854 VisitOMPExecutableDirective(const OMPExecutableDirective * Node)855 void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) { 856 for (const auto *C : Node->clauses()) 857 Visit(C); 858 } 859 VisitOpenACCConstructStmt(const OpenACCConstructStmt * Node)860 void VisitOpenACCConstructStmt(const OpenACCConstructStmt *Node) { 861 for (const auto *C : Node->clauses()) 862 Visit(C); 863 } 864 VisitOpenACCWaitConstruct(const OpenACCWaitConstruct * Node)865 void VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *Node) { 866 // Needs custom child checking to put clauses AFTER the children, which are 867 // the expressions in the 'wait' construct. Others likely need this as well, 868 // and might need to do the associated statement after it. 869 for (const Stmt *S : Node->children()) 870 Visit(S); 871 for (const auto *C : Node->clauses()) 872 Visit(C); 873 } 874 VisitInitListExpr(const InitListExpr * ILE)875 void VisitInitListExpr(const InitListExpr *ILE) { 876 if (auto *Filler = ILE->getArrayFiller()) { 877 Visit(Filler, "array_filler"); 878 } 879 } 880 VisitCXXParenListInitExpr(const CXXParenListInitExpr * PLIE)881 void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) { 882 if (auto *Filler = PLIE->getArrayFiller()) { 883 Visit(Filler, "array_filler"); 884 } 885 } 886 VisitBlockExpr(const BlockExpr * Node)887 void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); } 888 VisitOpaqueValueExpr(const OpaqueValueExpr * Node)889 void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { 890 if (Expr *Source = Node->getSourceExpr()) 891 Visit(Source); 892 } 893 VisitGenericSelectionExpr(const GenericSelectionExpr * E)894 void VisitGenericSelectionExpr(const GenericSelectionExpr *E) { 895 if (E->isExprPredicate()) { 896 Visit(E->getControllingExpr()); 897 Visit(E->getControllingExpr()->getType()); // FIXME: remove 898 } else 899 Visit(E->getControllingType()->getType()); 900 901 for (const auto Assoc : E->associations()) { 902 Visit(Assoc); 903 } 904 } 905 VisitUnresolvedLookupExpr(const UnresolvedLookupExpr * E)906 void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *E) { 907 if (E->hasExplicitTemplateArgs()) 908 for (auto Arg : E->template_arguments()) 909 Visit(Arg.getArgument()); 910 } 911 VisitRequiresExpr(const RequiresExpr * E)912 void VisitRequiresExpr(const RequiresExpr *E) { 913 for (auto *D : E->getLocalParameters()) 914 Visit(D); 915 for (auto *R : E->getRequirements()) 916 Visit(R); 917 } 918 VisitTypeTraitExpr(const TypeTraitExpr * E)919 void VisitTypeTraitExpr(const TypeTraitExpr *E) { 920 // Argument types are not children of the TypeTraitExpr. 921 for (auto *A : E->getArgs()) 922 Visit(A->getType()); 923 } 924 VisitLambdaExpr(const LambdaExpr * Node)925 void VisitLambdaExpr(const LambdaExpr *Node) { 926 if (Traversal == TK_IgnoreUnlessSpelledInSource) { 927 for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { 928 const auto *C = Node->capture_begin() + I; 929 if (!C->isExplicit()) 930 continue; 931 if (Node->isInitCapture(C)) 932 Visit(C->getCapturedVar()); 933 else 934 Visit(Node->capture_init_begin()[I]); 935 } 936 dumpTemplateParameters(Node->getTemplateParameterList()); 937 for (const auto *P : Node->getCallOperator()->parameters()) 938 Visit(P); 939 Visit(Node->getBody()); 940 } else { 941 return Visit(Node->getLambdaClass()); 942 } 943 } 944 VisitSizeOfPackExpr(const SizeOfPackExpr * Node)945 void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { 946 if (Node->isPartiallySubstituted()) 947 for (const auto &A : Node->getPartialArguments()) 948 Visit(A); 949 } 950 VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr * E)951 void VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) { 952 Visit(E->getParameter()); 953 } VisitSubstNonTypeTemplateParmPackExpr(const SubstNonTypeTemplateParmPackExpr * E)954 void VisitSubstNonTypeTemplateParmPackExpr( 955 const SubstNonTypeTemplateParmPackExpr *E) { 956 Visit(E->getParameterPack()); 957 Visit(E->getArgumentPack()); 958 } 959 VisitObjCAtCatchStmt(const ObjCAtCatchStmt * Node)960 void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 961 if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 962 Visit(CatchParam); 963 } 964 VisitCXXForRangeStmt(const CXXForRangeStmt * Node)965 void VisitCXXForRangeStmt(const CXXForRangeStmt *Node) { 966 if (Traversal == TK_IgnoreUnlessSpelledInSource) { 967 Visit(Node->getInit()); 968 Visit(Node->getLoopVariable()); 969 Visit(Node->getRangeInit()); 970 Visit(Node->getBody()); 971 } 972 } 973 VisitCallExpr(const CallExpr * Node)974 void VisitCallExpr(const CallExpr *Node) { 975 for (const auto *Child : 976 make_filter_range(Node->children(), [this](const Stmt *Child) { 977 if (Traversal != TK_IgnoreUnlessSpelledInSource) 978 return false; 979 return !isa<CXXDefaultArgExpr>(Child); 980 })) { 981 Visit(Child); 982 } 983 } 984 VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator * Node)985 void VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *Node) { 986 if (Traversal == TK_IgnoreUnlessSpelledInSource) { 987 Visit(Node->getLHS()); 988 Visit(Node->getRHS()); 989 } else { 990 ConstStmtVisitor<Derived>::VisitCXXRewrittenBinaryOperator(Node); 991 } 992 } 993 VisitExpressionTemplateArgument(const TemplateArgument & TA)994 void VisitExpressionTemplateArgument(const TemplateArgument &TA) { 995 Visit(TA.getAsExpr()); 996 } 997 VisitTypeTemplateArgument(const TemplateArgument & TA)998 void VisitTypeTemplateArgument(const TemplateArgument &TA) { 999 Visit(TA.getAsType()); 1000 } 1001 VisitPackTemplateArgument(const TemplateArgument & TA)1002 void VisitPackTemplateArgument(const TemplateArgument &TA) { 1003 for (const auto &TArg : TA.pack_elements()) 1004 Visit(TArg); 1005 } 1006 VisitCXXDefaultArgExpr(const CXXDefaultArgExpr * Node)1007 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) { 1008 Visit(Node->getExpr()); 1009 } 1010 VisitCXXDefaultInitExpr(const CXXDefaultInitExpr * Node)1011 void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) { 1012 Visit(Node->getExpr()); 1013 } 1014 1015 // Implements Visit methods for Attrs. 1016 #include "clang/AST/AttrNodeTraverse.inc" 1017 }; 1018 1019 } // namespace clang 1020 1021 #endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H 1022