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