1208600Srdivacky//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===// 2208600Srdivacky// 3208600Srdivacky// The LLVM Compiler Infrastructure 4208600Srdivacky// 5208600Srdivacky// This file is distributed under the University of Illinois Open Source 6208600Srdivacky// License. See LICENSE.TXT for details. 7208600Srdivacky// 8208600Srdivacky//===----------------------------------------------------------------------===// 9208600Srdivacky// 10208600Srdivacky// This file defines the RecursiveASTVisitor interface, which recursively 11208600Srdivacky// traverses the entire AST. 12208600Srdivacky// 13208600Srdivacky//===----------------------------------------------------------------------===// 14208600Srdivacky#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H 15208600Srdivacky#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H 16208600Srdivacky 17208600Srdivacky#include "clang/AST/Decl.h" 18208600Srdivacky#include "clang/AST/DeclCXX.h" 19208600Srdivacky#include "clang/AST/DeclFriend.h" 20208600Srdivacky#include "clang/AST/DeclObjC.h" 21249423Sdim#include "clang/AST/DeclOpenMP.h" 22208600Srdivacky#include "clang/AST/DeclTemplate.h" 23208600Srdivacky#include "clang/AST/Expr.h" 24208600Srdivacky#include "clang/AST/ExprCXX.h" 25208600Srdivacky#include "clang/AST/ExprObjC.h" 26208600Srdivacky#include "clang/AST/NestedNameSpecifier.h" 27208600Srdivacky#include "clang/AST/Stmt.h" 28208600Srdivacky#include "clang/AST/StmtCXX.h" 29208600Srdivacky#include "clang/AST/StmtObjC.h" 30263508Sdim#include "clang/AST/StmtOpenMP.h" 31208600Srdivacky#include "clang/AST/TemplateBase.h" 32208600Srdivacky#include "clang/AST/TemplateName.h" 33208600Srdivacky#include "clang/AST/Type.h" 34210299Sed#include "clang/AST/TypeLoc.h" 35208600Srdivacky 36210299Sed// The following three macros are used for meta programming. The code 37210299Sed// using them is responsible for defining macro OPERATOR(). 38210299Sed 39210299Sed// All unary operators. 40210299Sed#define UNARYOP_LIST() \ 41210299Sed OPERATOR(PostInc) OPERATOR(PostDec) \ 42210299Sed OPERATOR(PreInc) OPERATOR(PreDec) \ 43210299Sed OPERATOR(AddrOf) OPERATOR(Deref) \ 44210299Sed OPERATOR(Plus) OPERATOR(Minus) \ 45210299Sed OPERATOR(Not) OPERATOR(LNot) \ 46210299Sed OPERATOR(Real) OPERATOR(Imag) \ 47212904Sdim OPERATOR(Extension) 48210299Sed 49210299Sed// All binary operators (excluding compound assign operators). 50210299Sed#define BINOP_LIST() \ 51210299Sed OPERATOR(PtrMemD) OPERATOR(PtrMemI) \ 52210299Sed OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) \ 53210299Sed OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) \ 54210299Sed OPERATOR(Shr) \ 55210299Sed \ 56210299Sed OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) \ 57210299Sed OPERATOR(GE) OPERATOR(EQ) OPERATOR(NE) \ 58210299Sed OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \ 59210299Sed OPERATOR(LAnd) OPERATOR(LOr) \ 60210299Sed \ 61210299Sed OPERATOR(Assign) \ 62210299Sed OPERATOR(Comma) 63210299Sed 64210299Sed// All compound assign operators. 65210299Sed#define CAO_LIST() \ 66210299Sed OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \ 67210299Sed OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor) 68210299Sed 69208600Srdivackynamespace clang { 70208600Srdivacky 71210299Sed// A helper macro to implement short-circuiting when recursing. It 72210299Sed// invokes CALL_EXPR, which must be a method call, on the derived 73210299Sed// object (s.t. a user of RecursiveASTVisitor can override the method 74210299Sed// in CALL_EXPR). 75210299Sed#define TRY_TO(CALL_EXPR) \ 76210299Sed do { if (!getDerived().CALL_EXPR) return false; } while (0) 77208600Srdivacky 78210299Sed/// \brief A class that does preorder depth-first traversal on the 79210299Sed/// entire Clang AST and visits each node. 80210299Sed/// 81210299Sed/// This class performs three distinct tasks: 82210299Sed/// 1. traverse the AST (i.e. go to each node); 83210299Sed/// 2. at a given node, walk up the class hierarchy, starting from 84210299Sed/// the node's dynamic type, until the top-most class (e.g. Stmt, 85210299Sed/// Decl, or Type) is reached. 86210299Sed/// 3. given a (node, class) combination, where 'class' is some base 87210299Sed/// class of the dynamic type of 'node', call a user-overridable 88210299Sed/// function to actually visit the node. 89210299Sed/// 90210299Sed/// These tasks are done by three groups of methods, respectively: 91210299Sed/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point 92210299Sed/// for traversing an AST rooted at x. This method simply 93210299Sed/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo 94210299Sed/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and 95210299Sed/// then recursively visits the child nodes of x. 96210299Sed/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work 97210299Sed/// similarly. 98210299Sed/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit 99210299Sed/// any child node of x. Instead, it first calls WalkUpFromBar(x) 100210299Sed/// where Bar is the direct parent class of Foo (unless Foo has 101210299Sed/// no parent), and then calls VisitFoo(x) (see the next list item). 102210299Sed/// 3. VisitFoo(Foo *x) does task #3. 103210299Sed/// 104210299Sed/// These three method groups are tiered (Traverse* > WalkUpFrom* > 105210299Sed/// Visit*). A method (e.g. Traverse*) may call methods from the same 106210299Sed/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*). 107210299Sed/// It may not call methods from a higher tier. 108210299Sed/// 109210299Sed/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar 110210299Sed/// is Foo's super class) before calling VisitFoo(), the result is 111210299Sed/// that the Visit*() methods for a given node are called in the 112263508Sdim/// top-down order (e.g. for a node of type NamespaceDecl, the order will 113210299Sed/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()). 114210299Sed/// 115210299Sed/// This scheme guarantees that all Visit*() calls for the same AST 116210299Sed/// node are grouped together. In other words, Visit*() methods for 117210299Sed/// different nodes are never interleaved. 118210299Sed/// 119210299Sed/// Clients of this visitor should subclass the visitor (providing 120210299Sed/// themselves as the template argument, using the curiously recurring 121210299Sed/// template pattern) and override any of the Traverse*, WalkUpFrom*, 122210299Sed/// and Visit* methods for declarations, types, statements, 123210299Sed/// expressions, or other AST nodes where the visitor should customize 124210299Sed/// behavior. Most users only need to override Visit*. Advanced 125210299Sed/// users may override Traverse* and WalkUpFrom* to implement custom 126210299Sed/// traversal strategies. Returning false from one of these overridden 127210299Sed/// functions will abort the entire traversal. 128212904Sdim/// 129212904Sdim/// By default, this visitor tries to visit every part of the explicit 130212904Sdim/// source code exactly once. The default policy towards templates 131212904Sdim/// is to descend into the 'pattern' class or function body, not any 132212904Sdim/// explicit or implicit instantiations. Explicit specializations 133212904Sdim/// are still visited, and the patterns of partial specializations 134212904Sdim/// are visited separately. This behavior can be changed by 135212904Sdim/// overriding shouldVisitTemplateInstantiations() in the derived class 136212904Sdim/// to return true, in which case all known implicit and explicit 137212904Sdim/// instantiations will be visited at the same time as the pattern 138212904Sdim/// from which they were produced. 139208600Srdivackytemplate<typename Derived> 140210299Sedclass RecursiveASTVisitor { 141208600Srdivackypublic: 142208600Srdivacky /// \brief Return a reference to the derived class. 143208600Srdivacky Derived &getDerived() { return *static_cast<Derived*>(this); } 144208600Srdivacky 145212904Sdim /// \brief Return whether this visitor should recurse into 146212904Sdim /// template instantiations. 147212904Sdim bool shouldVisitTemplateInstantiations() const { return false; } 148218893Sdim 149218893Sdim /// \brief Return whether this visitor should recurse into the types of 150218893Sdim /// TypeLocs. 151218893Sdim bool shouldWalkTypesOfTypeLocs() const { return true; } 152234353Sdim 153239462Sdim /// \brief Return whether this visitor should recurse into implicit 154239462Sdim /// code, e.g., implicit constructors and destructors. 155239462Sdim bool shouldVisitImplicitCode() const { return false; } 156239462Sdim 157234353Sdim /// \brief Return whether \param S should be traversed using data recursion 158234353Sdim /// to avoid a stack overflow with extreme cases. 159234353Sdim bool shouldUseDataRecursionFor(Stmt *S) const { 160239462Sdim return isa<BinaryOperator>(S) || isa<UnaryOperator>(S) || 161239462Sdim isa<CaseStmt>(S) || isa<CXXOperatorCallExpr>(S); 162234353Sdim } 163234353Sdim 164208600Srdivacky /// \brief Recursively visit a statement or expression, by 165210299Sed /// dispatching to Traverse*() based on the argument's dynamic type. 166208600Srdivacky /// 167210299Sed /// \returns false if the visitation was terminated early, true 168208600Srdivacky /// otherwise (including when the argument is NULL). 169210299Sed bool TraverseStmt(Stmt *S); 170208600Srdivacky 171208600Srdivacky /// \brief Recursively visit a type, by dispatching to 172210299Sed /// Traverse*Type() based on the argument's getTypeClass() property. 173208600Srdivacky /// 174210299Sed /// \returns false if the visitation was terminated early, true 175208600Srdivacky /// otherwise (including when the argument is a Null type). 176210299Sed bool TraverseType(QualType T); 177208600Srdivacky 178210299Sed /// \brief Recursively visit a type with location, by dispatching to 179210299Sed /// Traverse*TypeLoc() based on the argument type's getTypeClass() property. 180210299Sed /// 181210299Sed /// \returns false if the visitation was terminated early, true 182210299Sed /// otherwise (including when the argument is a Null type location). 183210299Sed bool TraverseTypeLoc(TypeLoc TL); 184210299Sed 185208600Srdivacky /// \brief Recursively visit a declaration, by dispatching to 186210299Sed /// Traverse*Decl() based on the argument's dynamic type. 187208600Srdivacky /// 188210299Sed /// \returns false if the visitation was terminated early, true 189208600Srdivacky /// otherwise (including when the argument is NULL). 190210299Sed bool TraverseDecl(Decl *D); 191208600Srdivacky 192208600Srdivacky /// \brief Recursively visit a C++ nested-name-specifier. 193208600Srdivacky /// 194210299Sed /// \returns false if the visitation was terminated early, true otherwise. 195210299Sed bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); 196208600Srdivacky 197234353Sdim /// \brief Recursively visit a C++ nested-name-specifier with location 198219077Sdim /// information. 199219077Sdim /// 200219077Sdim /// \returns false if the visitation was terminated early, true otherwise. 201219077Sdim bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 202219077Sdim 203234353Sdim /// \brief Recursively visit a name with its location information. 204234353Sdim /// 205234353Sdim /// \returns false if the visitation was terminated early, true otherwise. 206234353Sdim bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo); 207234353Sdim 208210299Sed /// \brief Recursively visit a template name and dispatch to the 209210299Sed /// appropriate method. 210208600Srdivacky /// 211210299Sed /// \returns false if the visitation was terminated early, true otherwise. 212210299Sed bool TraverseTemplateName(TemplateName Template); 213208600Srdivacky 214210299Sed /// \brief Recursively visit a template argument and dispatch to the 215210299Sed /// appropriate method for the argument type. 216208600Srdivacky /// 217210299Sed /// \returns false if the visitation was terminated early, true otherwise. 218210299Sed // FIXME: migrate callers to TemplateArgumentLoc instead. 219210299Sed bool TraverseTemplateArgument(const TemplateArgument &Arg); 220208600Srdivacky 221210299Sed /// \brief Recursively visit a template argument location and dispatch to the 222210299Sed /// appropriate method for the argument type. 223210299Sed /// 224210299Sed /// \returns false if the visitation was terminated early, true otherwise. 225210299Sed bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc); 226210299Sed 227208600Srdivacky /// \brief Recursively visit a set of template arguments. 228210299Sed /// This can be overridden by a subclass, but it's not expected that 229210299Sed /// will be needed -- this visitor always dispatches to another. 230208600Srdivacky /// 231210299Sed /// \returns false if the visitation was terminated early, true otherwise. 232210299Sed // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead. 233210299Sed bool TraverseTemplateArguments(const TemplateArgument *Args, 234210299Sed unsigned NumArgs); 235208600Srdivacky 236210299Sed /// \brief Recursively visit a constructor initializer. This 237210299Sed /// automatically dispatches to another visitor for the initializer 238210299Sed /// expression, but not for the name of the initializer, so may 239210299Sed /// be overridden for clients that need access to the name. 240210299Sed /// 241210299Sed /// \returns false if the visitation was terminated early, true otherwise. 242218893Sdim bool TraverseConstructorInitializer(CXXCtorInitializer *Init); 243210299Sed 244234353Sdim /// \brief Recursively visit a lambda capture. 245234353Sdim /// 246234353Sdim /// \returns false if the visitation was terminated early, true otherwise. 247263508Sdim bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaExpr::Capture *C); 248263508Sdim 249263508Sdim /// \brief Recursively visit the body of a lambda expression. 250263508Sdim /// 251263508Sdim /// This provides a hook for visitors that need more context when visiting 252263508Sdim /// \c LE->getBody(). 253263508Sdim /// 254263508Sdim /// \returns false if the visitation was terminated early, true otherwise. 255263508Sdim bool TraverseLambdaBody(LambdaExpr *LE); 256263508Sdim 257210299Sed // ---- Methods on Stmts ---- 258210299Sed 259210299Sed // Declare Traverse*() for all concrete Stmt classes. 260210299Sed#define ABSTRACT_STMT(STMT) 261210299Sed#define STMT(CLASS, PARENT) \ 262210299Sed bool Traverse##CLASS(CLASS *S); 263208600Srdivacky#include "clang/AST/StmtNodes.inc" 264210299Sed // The above header #undefs ABSTRACT_STMT and STMT upon exit. 265208600Srdivacky 266210299Sed // Define WalkUpFrom*() and empty Visit*() for all Stmt classes. 267210299Sed bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); } 268210299Sed bool VisitStmt(Stmt *S) { return true; } 269210299Sed#define STMT(CLASS, PARENT) \ 270210299Sed bool WalkUpFrom##CLASS(CLASS *S) { \ 271210299Sed TRY_TO(WalkUpFrom##PARENT(S)); \ 272210299Sed TRY_TO(Visit##CLASS(S)); \ 273210299Sed return true; \ 274210299Sed } \ 275210299Sed bool Visit##CLASS(CLASS *S) { return true; } 276210299Sed#include "clang/AST/StmtNodes.inc" 277208600Srdivacky 278210299Sed // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary 279210299Sed // operator methods. Unary operators are not classes in themselves 280210299Sed // (they're all opcodes in UnaryOperator) but do have visitors. 281210299Sed#define OPERATOR(NAME) \ 282210299Sed bool TraverseUnary##NAME(UnaryOperator *S) { \ 283210299Sed TRY_TO(WalkUpFromUnary##NAME(S)); \ 284210299Sed TRY_TO(TraverseStmt(S->getSubExpr())); \ 285210299Sed return true; \ 286210299Sed } \ 287210299Sed bool WalkUpFromUnary##NAME(UnaryOperator *S) { \ 288210299Sed TRY_TO(WalkUpFromUnaryOperator(S)); \ 289210299Sed TRY_TO(VisitUnary##NAME(S)); \ 290210299Sed return true; \ 291210299Sed } \ 292210299Sed bool VisitUnary##NAME(UnaryOperator *S) { return true; } 293208600Srdivacky 294210299Sed UNARYOP_LIST() 295210299Sed#undef OPERATOR 296208600Srdivacky 297210299Sed // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary 298210299Sed // operator methods. Binary operators are not classes in themselves 299210299Sed // (they're all opcodes in BinaryOperator) but do have visitors. 300210299Sed#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \ 301210299Sed bool TraverseBin##NAME(BINOP_TYPE *S) { \ 302210299Sed TRY_TO(WalkUpFromBin##NAME(S)); \ 303210299Sed TRY_TO(TraverseStmt(S->getLHS())); \ 304210299Sed TRY_TO(TraverseStmt(S->getRHS())); \ 305210299Sed return true; \ 306210299Sed } \ 307210299Sed bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \ 308210299Sed TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \ 309210299Sed TRY_TO(VisitBin##NAME(S)); \ 310210299Sed return true; \ 311210299Sed } \ 312210299Sed bool VisitBin##NAME(BINOP_TYPE *S) { return true; } 313208600Srdivacky 314210299Sed#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator) 315210299Sed BINOP_LIST() 316210299Sed#undef OPERATOR 317208600Srdivacky 318210299Sed // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound 319210299Sed // assignment methods. Compound assignment operators are not 320210299Sed // classes in themselves (they're all opcodes in 321210299Sed // CompoundAssignOperator) but do have visitors. 322210299Sed#define OPERATOR(NAME) \ 323210299Sed GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator) 324208600Srdivacky 325210299Sed CAO_LIST() 326210299Sed#undef OPERATOR 327210299Sed#undef GENERAL_BINOP_FALLBACK 328208600Srdivacky 329210299Sed // ---- Methods on Types ---- 330210299Sed // FIXME: revamp to take TypeLoc's rather than Types. 331208600Srdivacky 332210299Sed // Declare Traverse*() for all concrete Type classes. 333210299Sed#define ABSTRACT_TYPE(CLASS, BASE) 334210299Sed#define TYPE(CLASS, BASE) \ 335210299Sed bool Traverse##CLASS##Type(CLASS##Type *T); 336208600Srdivacky#include "clang/AST/TypeNodes.def" 337210299Sed // The above header #undefs ABSTRACT_TYPE and TYPE upon exit. 338208600Srdivacky 339210299Sed // Define WalkUpFrom*() and empty Visit*() for all Type classes. 340210299Sed bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); } 341210299Sed bool VisitType(Type *T) { return true; } 342210299Sed#define TYPE(CLASS, BASE) \ 343210299Sed bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \ 344210299Sed TRY_TO(WalkUpFrom##BASE(T)); \ 345210299Sed TRY_TO(Visit##CLASS##Type(T)); \ 346210299Sed return true; \ 347210299Sed } \ 348210299Sed bool Visit##CLASS##Type(CLASS##Type *T) { return true; } 349210299Sed#include "clang/AST/TypeNodes.def" 350208600Srdivacky 351210299Sed // ---- Methods on TypeLocs ---- 352210299Sed // FIXME: this currently just calls the matching Type methods 353210299Sed 354263508Sdim // Declare Traverse*() for all concrete TypeLoc classes. 355210299Sed#define ABSTRACT_TYPELOC(CLASS, BASE) 356210299Sed#define TYPELOC(CLASS, BASE) \ 357210299Sed bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL); 358210299Sed#include "clang/AST/TypeLocNodes.def" 359210299Sed // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit. 360210299Sed 361210299Sed // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes. 362210299Sed bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); } 363210299Sed bool VisitTypeLoc(TypeLoc TL) { return true; } 364210299Sed 365210299Sed // QualifiedTypeLoc and UnqualTypeLoc are not declared in 366210299Sed // TypeNodes.def and thus need to be handled specially. 367210299Sed bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) { 368210299Sed return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc()); 369208600Srdivacky } 370210299Sed bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; } 371210299Sed bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) { 372210299Sed return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc()); 373210299Sed } 374210299Sed bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; } 375210299Sed 376210299Sed // Note that BASE includes trailing 'Type' which CLASS doesn't. 377210299Sed#define TYPE(CLASS, BASE) \ 378210299Sed bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \ 379210299Sed TRY_TO(WalkUpFrom##BASE##Loc(TL)); \ 380210299Sed TRY_TO(Visit##CLASS##TypeLoc(TL)); \ 381210299Sed return true; \ 382210299Sed } \ 383210299Sed bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; } 384210299Sed#include "clang/AST/TypeNodes.def" 385210299Sed 386210299Sed // ---- Methods on Decls ---- 387210299Sed 388210299Sed // Declare Traverse*() for all concrete Decl classes. 389210299Sed#define ABSTRACT_DECL(DECL) 390210299Sed#define DECL(CLASS, BASE) \ 391210299Sed bool Traverse##CLASS##Decl(CLASS##Decl *D); 392210299Sed#include "clang/AST/DeclNodes.inc" 393210299Sed // The above header #undefs ABSTRACT_DECL and DECL upon exit. 394210299Sed 395210299Sed // Define WalkUpFrom*() and empty Visit*() for all Decl classes. 396210299Sed bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); } 397210299Sed bool VisitDecl(Decl *D) { return true; } 398210299Sed#define DECL(CLASS, BASE) \ 399210299Sed bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \ 400210299Sed TRY_TO(WalkUpFrom##BASE(D)); \ 401210299Sed TRY_TO(Visit##CLASS##Decl(D)); \ 402210299Sed return true; \ 403210299Sed } \ 404210299Sed bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; } 405210299Sed#include "clang/AST/DeclNodes.inc" 406210299Sed 407210299Sedprivate: 408210299Sed // These are helper methods used by more than one Traverse* method. 409210299Sed bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); 410263508Sdim#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \ 411263508Sdim bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D); 412263508Sdim DEF_TRAVERSE_TMPL_INST(Class) 413263508Sdim DEF_TRAVERSE_TMPL_INST(Var) 414263508Sdim DEF_TRAVERSE_TMPL_INST(Function) 415263508Sdim#undef DEF_TRAVERSE_TMPL_INST 416218893Sdim bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL, 417210299Sed unsigned Count); 418212904Sdim bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL); 419210299Sed bool TraverseRecordHelper(RecordDecl *D); 420210299Sed bool TraverseCXXRecordHelper(CXXRecordDecl *D); 421210299Sed bool TraverseDeclaratorHelper(DeclaratorDecl *D); 422210299Sed bool TraverseDeclContextHelper(DeclContext *DC); 423210299Sed bool TraverseFunctionHelper(FunctionDecl *D); 424210299Sed bool TraverseVarHelper(VarDecl *D); 425263508Sdim bool TraverseOMPClause(OMPClause *C); 426263508Sdim#define OPENMP_CLAUSE(Name, Class) \ 427263508Sdim bool Visit##Class(Class *C); 428263508Sdim#include "clang/Basic/OpenMPKinds.def" 429263508Sdim /// \brief Process clauses with list of variables. 430263508Sdim template <typename T> 431263508Sdim void VisitOMPClauseList(T *Node); 432234353Sdim 433234353Sdim struct EnqueueJob { 434234353Sdim Stmt *S; 435234353Sdim Stmt::child_iterator StmtIt; 436234353Sdim 437239462Sdim EnqueueJob(Stmt *S) : S(S), StmtIt() {} 438234353Sdim }; 439234353Sdim bool dataTraverse(Stmt *S); 440239462Sdim bool dataTraverseNode(Stmt *S, bool &EnqueueChildren); 441208600Srdivacky}; 442208600Srdivacky 443234353Sdimtemplate<typename Derived> 444234353Sdimbool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) { 445234353Sdim 446234353Sdim SmallVector<EnqueueJob, 16> Queue; 447234353Sdim Queue.push_back(S); 448234353Sdim 449234353Sdim while (!Queue.empty()) { 450234353Sdim EnqueueJob &job = Queue.back(); 451234353Sdim Stmt *CurrS = job.S; 452234353Sdim if (!CurrS) { 453234353Sdim Queue.pop_back(); 454234353Sdim continue; 455234353Sdim } 456234353Sdim 457234353Sdim if (getDerived().shouldUseDataRecursionFor(CurrS)) { 458234353Sdim if (job.StmtIt == Stmt::child_iterator()) { 459239462Sdim bool EnqueueChildren = true; 460239462Sdim if (!dataTraverseNode(CurrS, EnqueueChildren)) return false; 461239462Sdim if (!EnqueueChildren) { 462239462Sdim Queue.pop_back(); 463239462Sdim continue; 464239462Sdim } 465234353Sdim job.StmtIt = CurrS->child_begin(); 466234353Sdim } else { 467234353Sdim ++job.StmtIt; 468234353Sdim } 469234353Sdim 470234353Sdim if (job.StmtIt != CurrS->child_end()) 471234353Sdim Queue.push_back(*job.StmtIt); 472234353Sdim else 473234353Sdim Queue.pop_back(); 474234353Sdim continue; 475234353Sdim } 476234353Sdim 477234353Sdim Queue.pop_back(); 478234353Sdim TRY_TO(TraverseStmt(CurrS)); 479234353Sdim } 480234353Sdim 481234353Sdim return true; 482234353Sdim} 483234353Sdim 484234353Sdimtemplate<typename Derived> 485239462Sdimbool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, 486239462Sdim bool &EnqueueChildren) { 487234353Sdim 488239462Sdim // Dispatch to the corresponding WalkUpFrom* function only if the derived 489239462Sdim // class didn't override Traverse* (and thus the traversal is trivial). 490234353Sdim#define DISPATCH_WALK(NAME, CLASS, VAR) \ 491249423Sdim { \ 492249423Sdim bool (Derived::*DerivedFn)(CLASS*) = &Derived::Traverse##NAME; \ 493249423Sdim bool (Derived::*BaseFn)(CLASS*) = &RecursiveASTVisitor::Traverse##NAME; \ 494249423Sdim if (DerivedFn == BaseFn) \ 495249423Sdim return getDerived().WalkUpFrom##NAME(static_cast<CLASS*>(VAR)); \ 496249423Sdim } \ 497239462Sdim EnqueueChildren = false; \ 498239462Sdim return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR)); 499234353Sdim 500234353Sdim if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) { 501234353Sdim switch (BinOp->getOpcode()) { 502234353Sdim#define OPERATOR(NAME) \ 503234353Sdim case BO_##NAME: DISPATCH_WALK(Bin##NAME, BinaryOperator, S); 504234353Sdim 505234353Sdim BINOP_LIST() 506234353Sdim#undef OPERATOR 507234353Sdim 508234353Sdim#define OPERATOR(NAME) \ 509234353Sdim case BO_##NAME##Assign: \ 510234353Sdim DISPATCH_WALK(Bin##NAME##Assign, CompoundAssignOperator, S); 511234353Sdim 512234353Sdim CAO_LIST() 513234353Sdim#undef OPERATOR 514234353Sdim } 515234353Sdim } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) { 516234353Sdim switch (UnOp->getOpcode()) { 517234353Sdim#define OPERATOR(NAME) \ 518234353Sdim case UO_##NAME: DISPATCH_WALK(Unary##NAME, UnaryOperator, S); 519234353Sdim 520234353Sdim UNARYOP_LIST() 521234353Sdim#undef OPERATOR 522234353Sdim } 523234353Sdim } 524234353Sdim 525234353Sdim // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt. 526234353Sdim switch (S->getStmtClass()) { 527234353Sdim case Stmt::NoStmtClass: break; 528234353Sdim#define ABSTRACT_STMT(STMT) 529234353Sdim#define STMT(CLASS, PARENT) \ 530234353Sdim case Stmt::CLASS##Class: DISPATCH_WALK(CLASS, CLASS, S); 531234353Sdim#include "clang/AST/StmtNodes.inc" 532234353Sdim } 533234353Sdim 534234353Sdim#undef DISPATCH_WALK 535234353Sdim 536234353Sdim return true; 537234353Sdim} 538234353Sdim 539210299Sed#define DISPATCH(NAME, CLASS, VAR) \ 540210299Sed return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR)) 541210299Sed 542208600Srdivackytemplate<typename Derived> 543210299Sedbool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) { 544208600Srdivacky if (!S) 545210299Sed return true; 546208600Srdivacky 547234353Sdim if (getDerived().shouldUseDataRecursionFor(S)) 548234353Sdim return dataTraverse(S); 549234353Sdim 550208600Srdivacky // If we have a binary expr, dispatch to the subcode of the binop. A smart 551208600Srdivacky // optimizer (e.g. LLVM) will fold this comparison into the switch stmt 552208600Srdivacky // below. 553208600Srdivacky if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) { 554208600Srdivacky switch (BinOp->getOpcode()) { 555210299Sed#define OPERATOR(NAME) \ 556218893Sdim case BO_##NAME: DISPATCH(Bin##NAME, BinaryOperator, S); 557208600Srdivacky 558210299Sed BINOP_LIST() 559210299Sed#undef OPERATOR 560210299Sed#undef BINOP_LIST 561208600Srdivacky 562210299Sed#define OPERATOR(NAME) \ 563212904Sdim case BO_##NAME##Assign: \ 564210299Sed DISPATCH(Bin##NAME##Assign, CompoundAssignOperator, S); 565210299Sed 566210299Sed CAO_LIST() 567210299Sed#undef OPERATOR 568210299Sed#undef CAO_LIST 569208600Srdivacky } 570208600Srdivacky } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) { 571208600Srdivacky switch (UnOp->getOpcode()) { 572210299Sed#define OPERATOR(NAME) \ 573212904Sdim case UO_##NAME: DISPATCH(Unary##NAME, UnaryOperator, S); 574210299Sed 575210299Sed UNARYOP_LIST() 576210299Sed#undef OPERATOR 577210299Sed#undef UNARYOP_LIST 578208600Srdivacky } 579208600Srdivacky } 580208600Srdivacky 581210299Sed // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt. 582208600Srdivacky switch (S->getStmtClass()) { 583208600Srdivacky case Stmt::NoStmtClass: break; 584208600Srdivacky#define ABSTRACT_STMT(STMT) 585210299Sed#define STMT(CLASS, PARENT) \ 586210299Sed case Stmt::CLASS##Class: DISPATCH(CLASS, CLASS, S); 587208600Srdivacky#include "clang/AST/StmtNodes.inc" 588208600Srdivacky } 589208600Srdivacky 590210299Sed return true; 591208600Srdivacky} 592208600Srdivacky 593208600Srdivackytemplate<typename Derived> 594210299Sedbool RecursiveASTVisitor<Derived>::TraverseType(QualType T) { 595208600Srdivacky if (T.isNull()) 596210299Sed return true; 597208600Srdivacky 598208600Srdivacky switch (T->getTypeClass()) { 599210299Sed#define ABSTRACT_TYPE(CLASS, BASE) 600210299Sed#define TYPE(CLASS, BASE) \ 601218893Sdim case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, \ 602218893Sdim const_cast<Type*>(T.getTypePtr())); 603208600Srdivacky#include "clang/AST/TypeNodes.def" 604208600Srdivacky } 605208600Srdivacky 606210299Sed return true; 607208600Srdivacky} 608208600Srdivacky 609208600Srdivackytemplate<typename Derived> 610210299Sedbool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) { 611210299Sed if (TL.isNull()) 612210299Sed return true; 613210299Sed 614210299Sed switch (TL.getTypeLocClass()) { 615210299Sed#define ABSTRACT_TYPELOC(CLASS, BASE) 616210299Sed#define TYPELOC(CLASS, BASE) \ 617210299Sed case TypeLoc::CLASS: \ 618249423Sdim return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>()); 619210299Sed#include "clang/AST/TypeLocNodes.def" 620210299Sed } 621210299Sed 622210299Sed return true; 623210299Sed} 624210299Sed 625210299Sed 626210299Sedtemplate<typename Derived> 627210299Sedbool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) { 628208600Srdivacky if (!D) 629210299Sed return true; 630208600Srdivacky 631239462Sdim // As a syntax visitor, by default we want to ignore declarations for 632239462Sdim // implicit declarations (ones not typed explicitly by the user). 633239462Sdim if (!getDerived().shouldVisitImplicitCode() && D->isImplicit()) 634210299Sed return true; 635210299Sed 636208600Srdivacky switch (D->getKind()) { 637210299Sed#define ABSTRACT_DECL(DECL) 638210299Sed#define DECL(CLASS, BASE) \ 639210299Sed case Decl::CLASS: DISPATCH(CLASS##Decl, CLASS##Decl, D); 640210299Sed#include "clang/AST/DeclNodes.inc" 641210299Sed } 642208600Srdivacky 643210299Sed return true; 644208600Srdivacky} 645208600Srdivacky 646210299Sed#undef DISPATCH 647210299Sed 648208600Srdivackytemplate<typename Derived> 649210299Sedbool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier( 650208600Srdivacky NestedNameSpecifier *NNS) { 651210299Sed if (!NNS) 652208600Srdivacky return true; 653208600Srdivacky 654210299Sed if (NNS->getPrefix()) 655210299Sed TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix())); 656210299Sed 657208600Srdivacky switch (NNS->getKind()) { 658208600Srdivacky case NestedNameSpecifier::Identifier: 659208600Srdivacky case NestedNameSpecifier::Namespace: 660219077Sdim case NestedNameSpecifier::NamespaceAlias: 661208600Srdivacky case NestedNameSpecifier::Global: 662210299Sed return true; 663208600Srdivacky 664208600Srdivacky case NestedNameSpecifier::TypeSpec: 665208600Srdivacky case NestedNameSpecifier::TypeSpecWithTemplate: 666210299Sed TRY_TO(TraverseType(QualType(NNS->getAsType(), 0))); 667208600Srdivacky } 668208600Srdivacky 669210299Sed return true; 670208600Srdivacky} 671208600Srdivacky 672208600Srdivackytemplate<typename Derived> 673219077Sdimbool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc( 674219077Sdim NestedNameSpecifierLoc NNS) { 675219077Sdim if (!NNS) 676219077Sdim return true; 677234353Sdim 678219077Sdim if (NestedNameSpecifierLoc Prefix = NNS.getPrefix()) 679219077Sdim TRY_TO(TraverseNestedNameSpecifierLoc(Prefix)); 680234353Sdim 681219077Sdim switch (NNS.getNestedNameSpecifier()->getKind()) { 682219077Sdim case NestedNameSpecifier::Identifier: 683219077Sdim case NestedNameSpecifier::Namespace: 684219077Sdim case NestedNameSpecifier::NamespaceAlias: 685219077Sdim case NestedNameSpecifier::Global: 686219077Sdim return true; 687234353Sdim 688219077Sdim case NestedNameSpecifier::TypeSpec: 689219077Sdim case NestedNameSpecifier::TypeSpecWithTemplate: 690219077Sdim TRY_TO(TraverseTypeLoc(NNS.getTypeLoc())); 691219077Sdim break; 692219077Sdim } 693234353Sdim 694219077Sdim return true; 695219077Sdim} 696219077Sdim 697219077Sdimtemplate<typename Derived> 698234353Sdimbool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo( 699234353Sdim DeclarationNameInfo NameInfo) { 700234353Sdim switch (NameInfo.getName().getNameKind()) { 701234353Sdim case DeclarationName::CXXConstructorName: 702234353Sdim case DeclarationName::CXXDestructorName: 703234353Sdim case DeclarationName::CXXConversionFunctionName: 704234353Sdim if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) 705234353Sdim TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc())); 706234353Sdim 707234353Sdim break; 708234353Sdim 709234353Sdim case DeclarationName::Identifier: 710234353Sdim case DeclarationName::ObjCZeroArgSelector: 711234353Sdim case DeclarationName::ObjCOneArgSelector: 712234353Sdim case DeclarationName::ObjCMultiArgSelector: 713234353Sdim case DeclarationName::CXXOperatorName: 714234353Sdim case DeclarationName::CXXLiteralOperatorName: 715234353Sdim case DeclarationName::CXXUsingDirective: 716234353Sdim break; 717234353Sdim } 718234353Sdim 719234353Sdim return true; 720234353Sdim} 721234353Sdim 722234353Sdimtemplate<typename Derived> 723210299Sedbool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) { 724208600Srdivacky if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) 725210299Sed TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier())); 726210299Sed else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) 727210299Sed TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier())); 728208600Srdivacky 729210299Sed return true; 730208600Srdivacky} 731208600Srdivacky 732208600Srdivackytemplate<typename Derived> 733210299Sedbool RecursiveASTVisitor<Derived>::TraverseTemplateArgument( 734208600Srdivacky const TemplateArgument &Arg) { 735208600Srdivacky switch (Arg.getKind()) { 736208600Srdivacky case TemplateArgument::Null: 737208600Srdivacky case TemplateArgument::Declaration: 738208600Srdivacky case TemplateArgument::Integral: 739243830Sdim case TemplateArgument::NullPtr: 740210299Sed return true; 741208600Srdivacky 742208600Srdivacky case TemplateArgument::Type: 743210299Sed return getDerived().TraverseType(Arg.getAsType()); 744208600Srdivacky 745208600Srdivacky case TemplateArgument::Template: 746218893Sdim case TemplateArgument::TemplateExpansion: 747218893Sdim return getDerived().TraverseTemplateName( 748218893Sdim Arg.getAsTemplateOrTemplatePattern()); 749208600Srdivacky 750208600Srdivacky case TemplateArgument::Expression: 751210299Sed return getDerived().TraverseStmt(Arg.getAsExpr()); 752208600Srdivacky 753208600Srdivacky case TemplateArgument::Pack: 754210299Sed return getDerived().TraverseTemplateArguments(Arg.pack_begin(), 755210299Sed Arg.pack_size()); 756208600Srdivacky } 757208600Srdivacky 758210299Sed return true; 759208600Srdivacky} 760208600Srdivacky 761210299Sed// FIXME: no template name location? 762210299Sed// FIXME: no source locations for a template argument pack? 763208600Srdivackytemplate<typename Derived> 764210299Sedbool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc( 765210299Sed const TemplateArgumentLoc &ArgLoc) { 766210299Sed const TemplateArgument &Arg = ArgLoc.getArgument(); 767208600Srdivacky 768210299Sed switch (Arg.getKind()) { 769210299Sed case TemplateArgument::Null: 770210299Sed case TemplateArgument::Declaration: 771210299Sed case TemplateArgument::Integral: 772243830Sdim case TemplateArgument::NullPtr: 773210299Sed return true; 774208600Srdivacky 775210299Sed case TemplateArgument::Type: { 776212904Sdim // FIXME: how can TSI ever be NULL? 777212904Sdim if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo()) 778212904Sdim return getDerived().TraverseTypeLoc(TSI->getTypeLoc()); 779234353Sdim else 780221345Sdim return getDerived().TraverseType(Arg.getAsType()); 781208600Srdivacky } 782208600Srdivacky 783210299Sed case TemplateArgument::Template: 784218893Sdim case TemplateArgument::TemplateExpansion: 785221345Sdim if (ArgLoc.getTemplateQualifierLoc()) 786221345Sdim TRY_TO(getDerived().TraverseNestedNameSpecifierLoc( 787221345Sdim ArgLoc.getTemplateQualifierLoc())); 788218893Sdim return getDerived().TraverseTemplateName( 789218893Sdim Arg.getAsTemplateOrTemplatePattern()); 790210299Sed 791210299Sed case TemplateArgument::Expression: 792210299Sed return getDerived().TraverseStmt(ArgLoc.getSourceExpression()); 793210299Sed 794210299Sed case TemplateArgument::Pack: 795210299Sed return getDerived().TraverseTemplateArguments(Arg.pack_begin(), 796210299Sed Arg.pack_size()); 797210299Sed } 798210299Sed 799210299Sed return true; 800208600Srdivacky} 801208600Srdivacky 802208600Srdivackytemplate<typename Derived> 803210299Sedbool RecursiveASTVisitor<Derived>::TraverseTemplateArguments( 804210299Sed const TemplateArgument *Args, 805210299Sed unsigned NumArgs) { 806210299Sed for (unsigned I = 0; I != NumArgs; ++I) { 807210299Sed TRY_TO(TraverseTemplateArgument(Args[I])); 808210299Sed } 809210299Sed 810210299Sed return true; 811208600Srdivacky} 812208600Srdivacky 813208600Srdivackytemplate<typename Derived> 814210299Sedbool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer( 815218893Sdim CXXCtorInitializer *Init) { 816234353Sdim if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) 817234353Sdim TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); 818234353Sdim 819243830Sdim if (Init->isWritten() || getDerived().shouldVisitImplicitCode()) 820210299Sed TRY_TO(TraverseStmt(Init->getInit())); 821210299Sed return true; 822208600Srdivacky} 823208600Srdivacky 824234353Sdimtemplate<typename Derived> 825263508Sdimbool RecursiveASTVisitor<Derived>::TraverseLambdaCapture( 826263508Sdim LambdaExpr *LE, const LambdaExpr::Capture *C) { 827263508Sdim if (C->isInitCapture()) 828263508Sdim TRY_TO(TraverseDecl(C->getCapturedVar())); 829234353Sdim return true; 830234353Sdim} 831208600Srdivacky 832263508Sdimtemplate<typename Derived> 833263508Sdimbool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) { 834263508Sdim TRY_TO(TraverseStmt(LE->getBody())); 835263508Sdim return true; 836263508Sdim} 837263508Sdim 838263508Sdim 839210299Sed// ----------------- Type traversal ----------------- 840208600Srdivacky 841210299Sed// This macro makes available a variable T, the passed-in type. 842210299Sed#define DEF_TRAVERSE_TYPE(TYPE, CODE) \ 843210299Sed template<typename Derived> \ 844210299Sed bool RecursiveASTVisitor<Derived>::Traverse##TYPE (TYPE *T) { \ 845210299Sed TRY_TO(WalkUpFrom##TYPE (T)); \ 846210299Sed { CODE; } \ 847210299Sed return true; \ 848210299Sed } 849208600Srdivacky 850210299SedDEF_TRAVERSE_TYPE(BuiltinType, { }) 851208600Srdivacky 852210299SedDEF_TRAVERSE_TYPE(ComplexType, { 853210299Sed TRY_TO(TraverseType(T->getElementType())); 854210299Sed }) 855208600Srdivacky 856210299SedDEF_TRAVERSE_TYPE(PointerType, { 857210299Sed TRY_TO(TraverseType(T->getPointeeType())); 858210299Sed }) 859208600Srdivacky 860210299SedDEF_TRAVERSE_TYPE(BlockPointerType, { 861210299Sed TRY_TO(TraverseType(T->getPointeeType())); 862210299Sed }) 863208600Srdivacky 864210299SedDEF_TRAVERSE_TYPE(LValueReferenceType, { 865210299Sed TRY_TO(TraverseType(T->getPointeeType())); 866210299Sed }) 867208600Srdivacky 868210299SedDEF_TRAVERSE_TYPE(RValueReferenceType, { 869210299Sed TRY_TO(TraverseType(T->getPointeeType())); 870210299Sed }) 871208600Srdivacky 872210299SedDEF_TRAVERSE_TYPE(MemberPointerType, { 873210299Sed TRY_TO(TraverseType(QualType(T->getClass(), 0))); 874210299Sed TRY_TO(TraverseType(T->getPointeeType())); 875210299Sed }) 876208600Srdivacky 877263508SdimDEF_TRAVERSE_TYPE(DecayedType, { 878263508Sdim TRY_TO(TraverseType(T->getOriginalType())); 879263508Sdim }) 880263508Sdim 881210299SedDEF_TRAVERSE_TYPE(ConstantArrayType, { 882210299Sed TRY_TO(TraverseType(T->getElementType())); 883210299Sed }) 884208600Srdivacky 885210299SedDEF_TRAVERSE_TYPE(IncompleteArrayType, { 886210299Sed TRY_TO(TraverseType(T->getElementType())); 887210299Sed }) 888208600Srdivacky 889210299SedDEF_TRAVERSE_TYPE(VariableArrayType, { 890210299Sed TRY_TO(TraverseType(T->getElementType())); 891210299Sed TRY_TO(TraverseStmt(T->getSizeExpr())); 892210299Sed }) 893208600Srdivacky 894210299SedDEF_TRAVERSE_TYPE(DependentSizedArrayType, { 895210299Sed TRY_TO(TraverseType(T->getElementType())); 896210299Sed if (T->getSizeExpr()) 897210299Sed TRY_TO(TraverseStmt(T->getSizeExpr())); 898210299Sed }) 899208600Srdivacky 900210299SedDEF_TRAVERSE_TYPE(DependentSizedExtVectorType, { 901210299Sed if (T->getSizeExpr()) 902210299Sed TRY_TO(TraverseStmt(T->getSizeExpr())); 903210299Sed TRY_TO(TraverseType(T->getElementType())); 904210299Sed }) 905208600Srdivacky 906210299SedDEF_TRAVERSE_TYPE(VectorType, { 907210299Sed TRY_TO(TraverseType(T->getElementType())); 908210299Sed }) 909208600Srdivacky 910210299SedDEF_TRAVERSE_TYPE(ExtVectorType, { 911210299Sed TRY_TO(TraverseType(T->getElementType())); 912210299Sed }) 913208600Srdivacky 914210299SedDEF_TRAVERSE_TYPE(FunctionNoProtoType, { 915210299Sed TRY_TO(TraverseType(T->getResultType())); 916210299Sed }) 917208600Srdivacky 918210299SedDEF_TRAVERSE_TYPE(FunctionProtoType, { 919210299Sed TRY_TO(TraverseType(T->getResultType())); 920208600Srdivacky 921210299Sed for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(), 922210299Sed AEnd = T->arg_type_end(); 923210299Sed A != AEnd; ++A) { 924210299Sed TRY_TO(TraverseType(*A)); 925210299Sed } 926208600Srdivacky 927210299Sed for (FunctionProtoType::exception_iterator E = T->exception_begin(), 928210299Sed EEnd = T->exception_end(); 929210299Sed E != EEnd; ++E) { 930210299Sed TRY_TO(TraverseType(*E)); 931210299Sed } 932210299Sed }) 933208600Srdivacky 934210299SedDEF_TRAVERSE_TYPE(UnresolvedUsingType, { }) 935210299SedDEF_TRAVERSE_TYPE(TypedefType, { }) 936208600Srdivacky 937210299SedDEF_TRAVERSE_TYPE(TypeOfExprType, { 938210299Sed TRY_TO(TraverseStmt(T->getUnderlyingExpr())); 939210299Sed }) 940208600Srdivacky 941210299SedDEF_TRAVERSE_TYPE(TypeOfType, { 942210299Sed TRY_TO(TraverseType(T->getUnderlyingType())); 943210299Sed }) 944208600Srdivacky 945210299SedDEF_TRAVERSE_TYPE(DecltypeType, { 946210299Sed TRY_TO(TraverseStmt(T->getUnderlyingExpr())); 947210299Sed }) 948208600Srdivacky 949223017SdimDEF_TRAVERSE_TYPE(UnaryTransformType, { 950223017Sdim TRY_TO(TraverseType(T->getBaseType())); 951223017Sdim TRY_TO(TraverseType(T->getUnderlyingType())); 952223017Sdim }) 953223017Sdim 954218893SdimDEF_TRAVERSE_TYPE(AutoType, { 955218893Sdim TRY_TO(TraverseType(T->getDeducedType())); 956218893Sdim }) 957218893Sdim 958210299SedDEF_TRAVERSE_TYPE(RecordType, { }) 959210299SedDEF_TRAVERSE_TYPE(EnumType, { }) 960210299SedDEF_TRAVERSE_TYPE(TemplateTypeParmType, { }) 961210299SedDEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { }) 962218893SdimDEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { }) 963208600Srdivacky 964210299SedDEF_TRAVERSE_TYPE(TemplateSpecializationType, { 965210299Sed TRY_TO(TraverseTemplateName(T->getTemplateName())); 966210299Sed TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); 967210299Sed }) 968208600Srdivacky 969210299SedDEF_TRAVERSE_TYPE(InjectedClassNameType, { }) 970210299Sed 971218893SdimDEF_TRAVERSE_TYPE(AttributedType, { 972218893Sdim TRY_TO(TraverseType(T->getModifiedType())); 973218893Sdim }) 974218893Sdim 975218893SdimDEF_TRAVERSE_TYPE(ParenType, { 976218893Sdim TRY_TO(TraverseType(T->getInnerType())); 977218893Sdim }) 978218893Sdim 979210299SedDEF_TRAVERSE_TYPE(ElaboratedType, { 980210299Sed if (T->getQualifier()) { 981210299Sed TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); 982210299Sed } 983210299Sed TRY_TO(TraverseType(T->getNamedType())); 984210299Sed }) 985210299Sed 986210299SedDEF_TRAVERSE_TYPE(DependentNameType, { 987210299Sed TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); 988210299Sed }) 989210299Sed 990210299SedDEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, { 991210299Sed TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); 992210299Sed TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); 993210299Sed }) 994210299Sed 995218893SdimDEF_TRAVERSE_TYPE(PackExpansionType, { 996218893Sdim TRY_TO(TraverseType(T->getPattern())); 997218893Sdim }) 998218893Sdim 999210299SedDEF_TRAVERSE_TYPE(ObjCInterfaceType, { }) 1000210299Sed 1001210299SedDEF_TRAVERSE_TYPE(ObjCObjectType, { 1002210299Sed // We have to watch out here because an ObjCInterfaceType's base 1003210299Sed // type is itself. 1004210299Sed if (T->getBaseType().getTypePtr() != T) 1005210299Sed TRY_TO(TraverseType(T->getBaseType())); 1006210299Sed }) 1007210299Sed 1008210299SedDEF_TRAVERSE_TYPE(ObjCObjectPointerType, { 1009210299Sed TRY_TO(TraverseType(T->getPointeeType())); 1010210299Sed }) 1011210299Sed 1012226633SdimDEF_TRAVERSE_TYPE(AtomicType, { 1013226633Sdim TRY_TO(TraverseType(T->getValueType())); 1014226633Sdim }) 1015226633Sdim 1016210299Sed#undef DEF_TRAVERSE_TYPE 1017210299Sed 1018210299Sed// ----------------- TypeLoc traversal ----------------- 1019210299Sed 1020210299Sed// This macro makes available a variable TL, the passed-in TypeLoc. 1021234353Sdim// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc, 1022234353Sdim// in addition to WalkUpFrom* for the TypeLoc itself, such that existing 1023218893Sdim// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods 1024210299Sed// continue to work. 1025210299Sed#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \ 1026210299Sed template<typename Derived> \ 1027210299Sed bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \ 1028218893Sdim if (getDerived().shouldWalkTypesOfTypeLocs()) \ 1029218893Sdim TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE*>(TL.getTypePtr()))); \ 1030210299Sed TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ 1031210299Sed { CODE; } \ 1032210299Sed return true; \ 1033210299Sed } 1034210299Sed 1035208600Srdivackytemplate<typename Derived> 1036210299Sedbool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc( 1037210299Sed QualifiedTypeLoc TL) { 1038210299Sed // Move this over to the 'main' typeloc tree. Note that this is a 1039210299Sed // move -- we pretend that we were really looking at the unqualified 1040210299Sed // typeloc all along -- rather than a recursion, so we don't follow 1041210299Sed // the normal CRTP plan of going through 1042210299Sed // getDerived().TraverseTypeLoc. If we did, we'd be traversing 1043210299Sed // twice for the same type (once as a QualifiedTypeLoc version of 1044210299Sed // the type, once as an UnqualifiedTypeLoc version of the type), 1045210299Sed // which in effect means we'd call VisitTypeLoc twice with the 1046210299Sed // 'same' type. This solves that problem, at the cost of never 1047210299Sed // seeing the qualified version of the type (unless the client 1048210299Sed // subclasses TraverseQualifiedTypeLoc themselves). It's not a 1049210299Sed // perfect solution. A perfect solution probably requires making 1050210299Sed // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a 1051210299Sed // wrapper around Type* -- rather than being its own class in the 1052210299Sed // type hierarchy. 1053210299Sed return TraverseTypeLoc(TL.getUnqualifiedLoc()); 1054208600Srdivacky} 1055208600Srdivacky 1056210299SedDEF_TRAVERSE_TYPELOC(BuiltinType, { }) 1057210299Sed 1058210299Sed// FIXME: ComplexTypeLoc is unfinished 1059210299SedDEF_TRAVERSE_TYPELOC(ComplexType, { 1060210299Sed TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); 1061210299Sed }) 1062210299Sed 1063210299SedDEF_TRAVERSE_TYPELOC(PointerType, { 1064210299Sed TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); 1065210299Sed }) 1066210299Sed 1067210299SedDEF_TRAVERSE_TYPELOC(BlockPointerType, { 1068210299Sed TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); 1069210299Sed }) 1070210299Sed 1071210299SedDEF_TRAVERSE_TYPELOC(LValueReferenceType, { 1072210299Sed TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); 1073210299Sed }) 1074210299Sed 1075210299SedDEF_TRAVERSE_TYPELOC(RValueReferenceType, { 1076210299Sed TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); 1077210299Sed }) 1078210299Sed 1079210299Sed// FIXME: location of base class? 1080210299Sed// We traverse this in the type case as well, but how is it not reached through 1081210299Sed// the pointee type? 1082210299SedDEF_TRAVERSE_TYPELOC(MemberPointerType, { 1083210299Sed TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0))); 1084210299Sed TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); 1085210299Sed }) 1086210299Sed 1087263508SdimDEF_TRAVERSE_TYPELOC(DecayedType, { 1088263508Sdim TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); 1089263508Sdim }) 1090263508Sdim 1091212904Sdimtemplate<typename Derived> 1092212904Sdimbool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) { 1093212904Sdim // This isn't available for ArrayType, but is for the ArrayTypeLoc. 1094212904Sdim TRY_TO(TraverseStmt(TL.getSizeExpr())); 1095212904Sdim return true; 1096212904Sdim} 1097212904Sdim 1098210299SedDEF_TRAVERSE_TYPELOC(ConstantArrayType, { 1099210299Sed TRY_TO(TraverseTypeLoc(TL.getElementLoc())); 1100212904Sdim return TraverseArrayTypeLocHelper(TL); 1101210299Sed }) 1102210299Sed 1103210299SedDEF_TRAVERSE_TYPELOC(IncompleteArrayType, { 1104210299Sed TRY_TO(TraverseTypeLoc(TL.getElementLoc())); 1105212904Sdim return TraverseArrayTypeLocHelper(TL); 1106210299Sed }) 1107210299Sed 1108210299SedDEF_TRAVERSE_TYPELOC(VariableArrayType, { 1109210299Sed TRY_TO(TraverseTypeLoc(TL.getElementLoc())); 1110212904Sdim return TraverseArrayTypeLocHelper(TL); 1111210299Sed }) 1112210299Sed 1113210299SedDEF_TRAVERSE_TYPELOC(DependentSizedArrayType, { 1114210299Sed TRY_TO(TraverseTypeLoc(TL.getElementLoc())); 1115212904Sdim return TraverseArrayTypeLocHelper(TL); 1116210299Sed }) 1117210299Sed 1118210299Sed// FIXME: order? why not size expr first? 1119210299Sed// FIXME: base VectorTypeLoc is unfinished 1120210299SedDEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, { 1121210299Sed if (TL.getTypePtr()->getSizeExpr()) 1122210299Sed TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr())); 1123210299Sed TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); 1124210299Sed }) 1125210299Sed 1126210299Sed// FIXME: VectorTypeLoc is unfinished 1127210299SedDEF_TRAVERSE_TYPELOC(VectorType, { 1128210299Sed TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); 1129210299Sed }) 1130210299Sed 1131210299Sed// FIXME: size and attributes 1132210299Sed// FIXME: base VectorTypeLoc is unfinished 1133210299SedDEF_TRAVERSE_TYPELOC(ExtVectorType, { 1134210299Sed TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); 1135210299Sed }) 1136210299Sed 1137210299SedDEF_TRAVERSE_TYPELOC(FunctionNoProtoType, { 1138210299Sed TRY_TO(TraverseTypeLoc(TL.getResultLoc())); 1139210299Sed }) 1140210299Sed 1141218893Sdim// FIXME: location of exception specifications (attributes?) 1142210299SedDEF_TRAVERSE_TYPELOC(FunctionProtoType, { 1143210299Sed TRY_TO(TraverseTypeLoc(TL.getResultLoc())); 1144210299Sed 1145218893Sdim const FunctionProtoType *T = TL.getTypePtr(); 1146218893Sdim 1147210299Sed for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { 1148221345Sdim if (TL.getArg(I)) { 1149221345Sdim TRY_TO(TraverseDecl(TL.getArg(I))); 1150221345Sdim } else if (I < T->getNumArgs()) { 1151221345Sdim TRY_TO(TraverseType(T->getArgType(I))); 1152221345Sdim } 1153210299Sed } 1154218893Sdim 1155210299Sed for (FunctionProtoType::exception_iterator E = T->exception_begin(), 1156210299Sed EEnd = T->exception_end(); 1157210299Sed E != EEnd; ++E) { 1158210299Sed TRY_TO(TraverseType(*E)); 1159210299Sed } 1160210299Sed }) 1161210299Sed 1162210299SedDEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { }) 1163210299SedDEF_TRAVERSE_TYPELOC(TypedefType, { }) 1164210299Sed 1165210299SedDEF_TRAVERSE_TYPELOC(TypeOfExprType, { 1166210299Sed TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); 1167210299Sed }) 1168210299Sed 1169210299SedDEF_TRAVERSE_TYPELOC(TypeOfType, { 1170210299Sed TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); 1171210299Sed }) 1172210299Sed 1173210299Sed// FIXME: location of underlying expr 1174210299SedDEF_TRAVERSE_TYPELOC(DecltypeType, { 1175210299Sed TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr())); 1176210299Sed }) 1177210299Sed 1178223017SdimDEF_TRAVERSE_TYPELOC(UnaryTransformType, { 1179223017Sdim TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); 1180223017Sdim }) 1181223017Sdim 1182218893SdimDEF_TRAVERSE_TYPELOC(AutoType, { 1183218893Sdim TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); 1184218893Sdim }) 1185218893Sdim 1186210299SedDEF_TRAVERSE_TYPELOC(RecordType, { }) 1187210299SedDEF_TRAVERSE_TYPELOC(EnumType, { }) 1188210299SedDEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { }) 1189210299SedDEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { }) 1190218893SdimDEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { }) 1191210299Sed 1192210299Sed// FIXME: use the loc for the template name? 1193210299SedDEF_TRAVERSE_TYPELOC(TemplateSpecializationType, { 1194210299Sed TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName())); 1195210299Sed for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { 1196210299Sed TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); 1197210299Sed } 1198210299Sed }) 1199210299Sed 1200210299SedDEF_TRAVERSE_TYPELOC(InjectedClassNameType, { }) 1201210299Sed 1202218893SdimDEF_TRAVERSE_TYPELOC(ParenType, { 1203218893Sdim TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); 1204218893Sdim }) 1205218893Sdim 1206218893SdimDEF_TRAVERSE_TYPELOC(AttributedType, { 1207218893Sdim TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); 1208218893Sdim }) 1209218893Sdim 1210210299SedDEF_TRAVERSE_TYPELOC(ElaboratedType, { 1211221345Sdim if (TL.getQualifierLoc()) { 1212221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); 1213210299Sed } 1214210299Sed TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc())); 1215210299Sed }) 1216210299Sed 1217210299SedDEF_TRAVERSE_TYPELOC(DependentNameType, { 1218221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); 1219210299Sed }) 1220210299Sed 1221210299SedDEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, { 1222221345Sdim if (TL.getQualifierLoc()) { 1223221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); 1224221345Sdim } 1225234353Sdim 1226210299Sed for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { 1227210299Sed TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); 1228210299Sed } 1229210299Sed }) 1230210299Sed 1231218893SdimDEF_TRAVERSE_TYPELOC(PackExpansionType, { 1232218893Sdim TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); 1233218893Sdim }) 1234218893Sdim 1235210299SedDEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { }) 1236210299Sed 1237210299SedDEF_TRAVERSE_TYPELOC(ObjCObjectType, { 1238210299Sed // We have to watch out here because an ObjCInterfaceType's base 1239210299Sed // type is itself. 1240210299Sed if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr()) 1241210299Sed TRY_TO(TraverseTypeLoc(TL.getBaseLoc())); 1242210299Sed }) 1243210299Sed 1244210299SedDEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, { 1245210299Sed TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); 1246210299Sed }) 1247210299Sed 1248226633SdimDEF_TRAVERSE_TYPELOC(AtomicType, { 1249226633Sdim TRY_TO(TraverseTypeLoc(TL.getValueLoc())); 1250226633Sdim }) 1251226633Sdim 1252210299Sed#undef DEF_TRAVERSE_TYPELOC 1253210299Sed 1254210299Sed// ----------------- Decl traversal ----------------- 1255210299Sed// 1256210299Sed// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing 1257210299Sed// the children that come from the DeclContext associated with it. 1258210299Sed// Therefore each Traverse* only needs to worry about children other 1259210299Sed// than those. 1260210299Sed 1261208600Srdivackytemplate<typename Derived> 1262210299Sedbool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) { 1263210299Sed if (!DC) 1264210299Sed return true; 1265208600Srdivacky 1266210299Sed for (DeclContext::decl_iterator Child = DC->decls_begin(), 1267210299Sed ChildEnd = DC->decls_end(); 1268210299Sed Child != ChildEnd; ++Child) { 1269251662Sdim // BlockDecls and CapturedDecls are traversed through BlockExprs and 1270251662Sdim // CapturedStmts respectively. 1271251662Sdim if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child)) 1272221345Sdim TRY_TO(TraverseDecl(*Child)); 1273208600Srdivacky } 1274208600Srdivacky 1275210299Sed return true; 1276208600Srdivacky} 1277208600Srdivacky 1278210299Sed// This macro makes available a variable D, the passed-in decl. 1279210299Sed#define DEF_TRAVERSE_DECL(DECL, CODE) \ 1280210299Sedtemplate<typename Derived> \ 1281210299Sedbool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) { \ 1282210299Sed TRY_TO(WalkUpFrom##DECL (D)); \ 1283210299Sed { CODE; } \ 1284210299Sed TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \ 1285210299Sed return true; \ 1286208600Srdivacky} 1287208600Srdivacky 1288210299SedDEF_TRAVERSE_DECL(AccessSpecDecl, { }) 1289208600Srdivacky 1290210299SedDEF_TRAVERSE_DECL(BlockDecl, { 1291239462Sdim if (TypeSourceInfo *TInfo = D->getSignatureAsWritten()) 1292239462Sdim TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); 1293210299Sed TRY_TO(TraverseStmt(D->getBody())); 1294221345Sdim // This return statement makes sure the traversal of nodes in 1295221345Sdim // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) 1296221345Sdim // is skipped - don't remove it. 1297221345Sdim return true; 1298210299Sed }) 1299208600Srdivacky 1300251662SdimDEF_TRAVERSE_DECL(CapturedDecl, { 1301251662Sdim TRY_TO(TraverseStmt(D->getBody())); 1302251662Sdim // This return statement makes sure the traversal of nodes in 1303251662Sdim // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) 1304251662Sdim // is skipped - don't remove it. 1305251662Sdim return true; 1306251662Sdim }) 1307251662Sdim 1308249423SdimDEF_TRAVERSE_DECL(EmptyDecl, { }) 1309249423Sdim 1310210299SedDEF_TRAVERSE_DECL(FileScopeAsmDecl, { 1311210299Sed TRY_TO(TraverseStmt(D->getAsmString())); 1312210299Sed }) 1313208600Srdivacky 1314234353SdimDEF_TRAVERSE_DECL(ImportDecl, { }) 1315234353Sdim 1316210299SedDEF_TRAVERSE_DECL(FriendDecl, { 1317218893Sdim // Friend is either decl or a type. 1318218893Sdim if (D->getFriendType()) 1319218893Sdim TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); 1320218893Sdim else 1321218893Sdim TRY_TO(TraverseDecl(D->getFriendDecl())); 1322210299Sed }) 1323208600Srdivacky 1324210299SedDEF_TRAVERSE_DECL(FriendTemplateDecl, { 1325218893Sdim if (D->getFriendType()) 1326218893Sdim TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); 1327218893Sdim else 1328218893Sdim TRY_TO(TraverseDecl(D->getFriendDecl())); 1329210299Sed for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) { 1330210299Sed TemplateParameterList *TPL = D->getTemplateParameterList(I); 1331210299Sed for (TemplateParameterList::iterator ITPL = TPL->begin(), 1332210299Sed ETPL = TPL->end(); 1333210299Sed ITPL != ETPL; ++ITPL) { 1334210299Sed TRY_TO(TraverseDecl(*ITPL)); 1335210299Sed } 1336210299Sed } 1337210299Sed }) 1338208600Srdivacky 1339226633SdimDEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, { 1340239462Sdim TRY_TO(TraverseDecl(D->getSpecialization())); 1341239462Sdim 1342239462Sdim if (D->hasExplicitTemplateArgs()) { 1343239462Sdim const TemplateArgumentListInfo& args = D->templateArgs(); 1344239462Sdim TRY_TO(TraverseTemplateArgumentLocsHelper( 1345239462Sdim args.getArgumentArray(), args.size())); 1346239462Sdim } 1347226633Sdim }) 1348226633Sdim 1349210299SedDEF_TRAVERSE_DECL(LinkageSpecDecl, { }) 1350210299Sed 1351210299SedDEF_TRAVERSE_DECL(ObjCPropertyImplDecl, { 1352210299Sed // FIXME: implement this 1353210299Sed }) 1354210299Sed 1355210299SedDEF_TRAVERSE_DECL(StaticAssertDecl, { 1356210299Sed TRY_TO(TraverseStmt(D->getAssertExpr())); 1357210299Sed TRY_TO(TraverseStmt(D->getMessage())); 1358210299Sed }) 1359210299Sed 1360210299SedDEF_TRAVERSE_DECL(TranslationUnitDecl, { 1361210299Sed // Code in an unnamed namespace shows up automatically in 1362210299Sed // decls_begin()/decls_end(). Thus we don't need to recurse on 1363210299Sed // D->getAnonymousNamespace(). 1364210299Sed }) 1365210299Sed 1366210299SedDEF_TRAVERSE_DECL(NamespaceAliasDecl, { 1367210299Sed // We shouldn't traverse an aliased namespace, since it will be 1368210299Sed // defined (and, therefore, traversed) somewhere else. 1369210299Sed // 1370210299Sed // This return statement makes sure the traversal of nodes in 1371210299Sed // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) 1372210299Sed // is skipped - don't remove it. 1373208600Srdivacky return true; 1374210299Sed }) 1375208600Srdivacky 1376218893SdimDEF_TRAVERSE_DECL(LabelDecl, { 1377218893Sdim // There is no code in a LabelDecl. 1378218893Sdim}) 1379234353Sdim 1380234353Sdim 1381210299SedDEF_TRAVERSE_DECL(NamespaceDecl, { 1382210299Sed // Code in an unnamed namespace shows up automatically in 1383210299Sed // decls_begin()/decls_end(). Thus we don't need to recurse on 1384210299Sed // D->getAnonymousNamespace(). 1385210299Sed }) 1386208600Srdivacky 1387210299SedDEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, { 1388210299Sed // FIXME: implement 1389210299Sed }) 1390208600Srdivacky 1391210299SedDEF_TRAVERSE_DECL(ObjCCategoryDecl, { 1392210299Sed // FIXME: implement 1393210299Sed }) 1394208600Srdivacky 1395210299SedDEF_TRAVERSE_DECL(ObjCCategoryImplDecl, { 1396210299Sed // FIXME: implement 1397210299Sed }) 1398210299Sed 1399210299SedDEF_TRAVERSE_DECL(ObjCImplementationDecl, { 1400210299Sed // FIXME: implement 1401210299Sed }) 1402210299Sed 1403210299SedDEF_TRAVERSE_DECL(ObjCInterfaceDecl, { 1404210299Sed // FIXME: implement 1405210299Sed }) 1406210299Sed 1407210299SedDEF_TRAVERSE_DECL(ObjCProtocolDecl, { 1408210299Sed // FIXME: implement 1409210299Sed }) 1410210299Sed 1411210299SedDEF_TRAVERSE_DECL(ObjCMethodDecl, { 1412221345Sdim if (D->getResultTypeSourceInfo()) { 1413221345Sdim TRY_TO(TraverseTypeLoc(D->getResultTypeSourceInfo()->getTypeLoc())); 1414221345Sdim } 1415221345Sdim for (ObjCMethodDecl::param_iterator 1416221345Sdim I = D->param_begin(), E = D->param_end(); I != E; ++I) { 1417221345Sdim TRY_TO(TraverseDecl(*I)); 1418221345Sdim } 1419221345Sdim if (D->isThisDeclarationADefinition()) { 1420221345Sdim TRY_TO(TraverseStmt(D->getBody())); 1421221345Sdim } 1422221345Sdim return true; 1423210299Sed }) 1424210299Sed 1425210299SedDEF_TRAVERSE_DECL(ObjCPropertyDecl, { 1426210299Sed // FIXME: implement 1427210299Sed }) 1428210299Sed 1429210299SedDEF_TRAVERSE_DECL(UsingDecl, { 1430219077Sdim TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); 1431234353Sdim TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); 1432210299Sed }) 1433210299Sed 1434210299SedDEF_TRAVERSE_DECL(UsingDirectiveDecl, { 1435219077Sdim TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); 1436210299Sed }) 1437210299Sed 1438210299SedDEF_TRAVERSE_DECL(UsingShadowDecl, { }) 1439210299Sed 1440249423SdimDEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { 1441249423Sdim for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(), 1442249423Sdim E = D->varlist_end(); 1443249423Sdim I != E; ++I) { 1444249423Sdim TRY_TO(TraverseStmt(*I)); 1445249423Sdim } 1446249423Sdim }) 1447249423Sdim 1448210299Sed// A helper method for TemplateDecl's children. 1449208600Srdivackytemplate<typename Derived> 1450210299Sedbool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper( 1451210299Sed TemplateParameterList *TPL) { 1452210299Sed if (TPL) { 1453210299Sed for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); 1454210299Sed I != E; ++I) { 1455210299Sed TRY_TO(TraverseDecl(*I)); 1456210299Sed } 1457210299Sed } 1458210299Sed return true; 1459208600Srdivacky} 1460208600Srdivacky 1461263508Sdim#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \ 1462263508Sdim/* A helper method for traversing the implicit instantiations of a 1463263508Sdim class or variable template. */ \ 1464263508Sdimtemplate<typename Derived> \ 1465263508Sdimbool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations( \ 1466263508Sdim TMPLDECLKIND##TemplateDecl *D) { \ 1467263508Sdim TMPLDECLKIND##TemplateDecl::spec_iterator end = D->spec_end(); \ 1468263508Sdim for (TMPLDECLKIND##TemplateDecl::spec_iterator it = D->spec_begin(); \ 1469263508Sdim it != end; ++it) { \ 1470263508Sdim TMPLDECLKIND##TemplateSpecializationDecl* SD = *it; \ 1471263508Sdim \ 1472263508Sdim switch (SD->getSpecializationKind()) { \ 1473263508Sdim /* Visit the implicit instantiations with the requested pattern. */ \ 1474263508Sdim case TSK_Undeclared: \ 1475263508Sdim case TSK_ImplicitInstantiation: \ 1476263508Sdim TRY_TO(TraverseDecl(SD)); \ 1477263508Sdim break; \ 1478263508Sdim \ 1479263508Sdim /* We don't need to do anything on an explicit instantiation 1480263508Sdim or explicit specialization because there will be an explicit 1481263508Sdim node for it elsewhere. */ \ 1482263508Sdim case TSK_ExplicitInstantiationDeclaration: \ 1483263508Sdim case TSK_ExplicitInstantiationDefinition: \ 1484263508Sdim case TSK_ExplicitSpecialization: \ 1485263508Sdim break; \ 1486263508Sdim } \ 1487263508Sdim } \ 1488263508Sdim \ 1489263508Sdim return true; \ 1490212904Sdim} 1491263508Sdim 1492263508SdimDEF_TRAVERSE_TMPL_INST(Class) 1493263508SdimDEF_TRAVERSE_TMPL_INST(Var) 1494212904Sdim 1495212904Sdim// A helper method for traversing the instantiations of a 1496212904Sdim// function while skipping its specializations. 1497212904Sdimtemplate<typename Derived> 1498263508Sdimbool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations( 1499239462Sdim FunctionTemplateDecl *D) { 1500212904Sdim FunctionTemplateDecl::spec_iterator end = D->spec_end(); 1501234353Sdim for (FunctionTemplateDecl::spec_iterator it = D->spec_begin(); it != end; 1502234353Sdim ++it) { 1503212904Sdim FunctionDecl* FD = *it; 1504212904Sdim switch (FD->getTemplateSpecializationKind()) { 1505239462Sdim case TSK_Undeclared: 1506212904Sdim case TSK_ImplicitInstantiation: 1507212904Sdim // We don't know what kind of FunctionDecl this is. 1508212904Sdim TRY_TO(TraverseDecl(FD)); 1509212904Sdim break; 1510212904Sdim 1511239462Sdim // FIXME: For now traverse explicit instantiations here. Change that 1512239462Sdim // once they are represented as dedicated nodes in the AST. 1513212904Sdim case TSK_ExplicitInstantiationDeclaration: 1514212904Sdim case TSK_ExplicitInstantiationDefinition: 1515239462Sdim TRY_TO(TraverseDecl(FD)); 1516212904Sdim break; 1517212904Sdim 1518212904Sdim case TSK_ExplicitSpecialization: 1519212904Sdim break; 1520212904Sdim } 1521212904Sdim } 1522218893Sdim 1523212904Sdim return true; 1524212904Sdim} 1525218893Sdim 1526263508Sdim// This macro unifies the traversal of class, variable and function 1527263508Sdim// template declarations. 1528263508Sdim#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \ 1529263508SdimDEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \ 1530263508Sdim TRY_TO(TraverseDecl(D->getTemplatedDecl())); \ 1531263508Sdim TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \ 1532263508Sdim \ 1533263508Sdim /* By default, we do not traverse the instantiations of 1534263508Sdim class templates since they do not appear in the user code. The 1535263508Sdim following code optionally traverses them. 1536263508Sdim 1537263508Sdim We only traverse the class instantiations when we see the canonical 1538263508Sdim declaration of the template, to ensure we only visit them once. */ \ 1539263508Sdim if (getDerived().shouldVisitTemplateInstantiations() && \ 1540263508Sdim D == D->getCanonicalDecl()) \ 1541263508Sdim TRY_TO(TraverseTemplateInstantiations(D)); \ 1542263508Sdim \ 1543263508Sdim /* Note that getInstantiatedFromMemberTemplate() is just a link 1544263508Sdim from a template instantiation back to the template from which 1545263508Sdim it was instantiated, and thus should not be traversed. */ \ 1546210299Sed }) 1547210299Sed 1548263508SdimDEF_TRAVERSE_TMPL_DECL(Class) 1549263508SdimDEF_TRAVERSE_TMPL_DECL(Var) 1550263508SdimDEF_TRAVERSE_TMPL_DECL(Function) 1551263508Sdim 1552210299SedDEF_TRAVERSE_DECL(TemplateTemplateParmDecl, { 1553210299Sed // D is the "T" in something like 1554210299Sed // template <template <typename> class T> class container { }; 1555210299Sed TRY_TO(TraverseDecl(D->getTemplatedDecl())); 1556239462Sdim if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) { 1557210299Sed TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument())); 1558210299Sed } 1559210299Sed TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); 1560210299Sed }) 1561210299Sed 1562210299SedDEF_TRAVERSE_DECL(TemplateTypeParmDecl, { 1563210299Sed // D is the "T" in something like "template<typename T> class vector;" 1564212904Sdim if (D->getTypeForDecl()) 1565212904Sdim TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0))); 1566239462Sdim if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 1567210299Sed TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc())); 1568210299Sed }) 1569210299Sed 1570210299SedDEF_TRAVERSE_DECL(TypedefDecl, { 1571218893Sdim TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); 1572210299Sed // We shouldn't traverse D->getTypeForDecl(); it's a result of 1573210299Sed // declaring the typedef, not something that was written in the 1574210299Sed // source. 1575210299Sed }) 1576210299Sed 1577221345SdimDEF_TRAVERSE_DECL(TypeAliasDecl, { 1578221345Sdim TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); 1579221345Sdim // We shouldn't traverse D->getTypeForDecl(); it's a result of 1580221345Sdim // declaring the type alias, not something that was written in the 1581221345Sdim // source. 1582221345Sdim }) 1583221345Sdim 1584223017SdimDEF_TRAVERSE_DECL(TypeAliasTemplateDecl, { 1585223017Sdim TRY_TO(TraverseDecl(D->getTemplatedDecl())); 1586223017Sdim TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); 1587223017Sdim }) 1588223017Sdim 1589210299SedDEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, { 1590210299Sed // A dependent using declaration which was marked with 'typename'. 1591210299Sed // template<class T> class A : public B<T> { using typename B<T>::foo; }; 1592219077Sdim TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); 1593210299Sed // We shouldn't traverse D->getTypeForDecl(); it's a result of 1594210299Sed // declaring the type, not something that was written in the 1595210299Sed // source. 1596210299Sed }) 1597210299Sed 1598210299SedDEF_TRAVERSE_DECL(EnumDecl, { 1599210299Sed if (D->getTypeForDecl()) 1600210299Sed TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0))); 1601210299Sed 1602221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); 1603210299Sed // The enumerators are already traversed by 1604210299Sed // decls_begin()/decls_end(). 1605210299Sed }) 1606210299Sed 1607210299Sed 1608210299Sed// Helper methods for RecordDecl and its children. 1609208600Srdivackytemplate<typename Derived> 1610210299Sedbool RecursiveASTVisitor<Derived>::TraverseRecordHelper( 1611210299Sed RecordDecl *D) { 1612210299Sed // We shouldn't traverse D->getTypeForDecl(); it's a result of 1613210299Sed // declaring the type, not something that was written in the source. 1614218893Sdim 1615221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); 1616210299Sed return true; 1617208600Srdivacky} 1618208600Srdivacky 1619208600Srdivackytemplate<typename Derived> 1620210299Sedbool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper( 1621210299Sed CXXRecordDecl *D) { 1622210299Sed if (!TraverseRecordHelper(D)) 1623210299Sed return false; 1624239462Sdim if (D->isCompleteDefinition()) { 1625210299Sed for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), 1626210299Sed E = D->bases_end(); 1627210299Sed I != E; ++I) { 1628212904Sdim TRY_TO(TraverseTypeLoc(I->getTypeSourceInfo()->getTypeLoc())); 1629210299Sed } 1630210299Sed // We don't traverse the friends or the conversions, as they are 1631210299Sed // already in decls_begin()/decls_end(). 1632210299Sed } 1633210299Sed return true; 1634208600Srdivacky} 1635208600Srdivacky 1636210299SedDEF_TRAVERSE_DECL(RecordDecl, { 1637210299Sed TRY_TO(TraverseRecordHelper(D)); 1638210299Sed }) 1639210299Sed 1640210299SedDEF_TRAVERSE_DECL(CXXRecordDecl, { 1641210299Sed TRY_TO(TraverseCXXRecordHelper(D)); 1642210299Sed }) 1643210299Sed 1644263508Sdim#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \ 1645263508SdimDEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \ 1646263508Sdim /* For implicit instantiations ("set<int> x;"), we don't want to 1647263508Sdim recurse at all, since the instatiated template isn't written in 1648263508Sdim the source code anywhere. (Note the instatiated *type* -- 1649263508Sdim set<int> -- is written, and will still get a callback of 1650263508Sdim TemplateSpecializationType). For explicit instantiations 1651263508Sdim ("template set<int>;"), we do need a callback, since this 1652263508Sdim is the only callback that's made for this instantiation. 1653263508Sdim We use getTypeAsWritten() to distinguish. */ \ 1654263508Sdim if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \ 1655263508Sdim TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \ 1656263508Sdim \ 1657263508Sdim if (!getDerived().shouldVisitTemplateInstantiations() && \ 1658263508Sdim D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \ 1659263508Sdim /* Returning from here skips traversing the 1660263508Sdim declaration context of the *TemplateSpecializationDecl 1661263508Sdim (embedded in the DEF_TRAVERSE_DECL() macro) 1662263508Sdim which contains the instantiated members of the template. */ \ 1663263508Sdim return true; \ 1664210299Sed }) 1665208600Srdivacky 1666263508SdimDEF_TRAVERSE_TMPL_SPEC_DECL(Class) 1667263508SdimDEF_TRAVERSE_TMPL_SPEC_DECL(Var) 1668263508Sdim 1669210299Sedtemplate <typename Derived> 1670210299Sedbool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper( 1671210299Sed const TemplateArgumentLoc *TAL, unsigned Count) { 1672210299Sed for (unsigned I = 0; I < Count; ++I) { 1673210299Sed TRY_TO(TraverseTemplateArgumentLoc(TAL[I])); 1674210299Sed } 1675210299Sed return true; 1676208600Srdivacky} 1677208600Srdivacky 1678263508Sdim#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \ 1679263508SdimDEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \ 1680263508Sdim /* The partial specialization. */ \ 1681263508Sdim if (TemplateParameterList *TPL = D->getTemplateParameters()) { \ 1682263508Sdim for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \ 1683263508Sdim I != E; ++I) { \ 1684263508Sdim TRY_TO(TraverseDecl(*I)); \ 1685263508Sdim } \ 1686263508Sdim } \ 1687263508Sdim /* The args that remains unspecialized. */ \ 1688263508Sdim TRY_TO(TraverseTemplateArgumentLocsHelper( \ 1689263508Sdim D->getTemplateArgsAsWritten()->getTemplateArgs(), \ 1690263508Sdim D->getTemplateArgsAsWritten()->NumTemplateArgs)); \ 1691263508Sdim \ 1692263508Sdim /* Don't need the *TemplatePartialSpecializationHelper, even 1693263508Sdim though that's our parent class -- we already visit all the 1694263508Sdim template args here. */ \ 1695263508Sdim TRY_TO(Traverse##DECLKIND##Helper(D)); \ 1696263508Sdim \ 1697263508Sdim /* Instantiations will have been visited with the primary template. */ \ 1698263508Sdim }) 1699210299Sed 1700263508SdimDEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord) 1701263508SdimDEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var) 1702212904Sdim 1703210299SedDEF_TRAVERSE_DECL(EnumConstantDecl, { 1704210299Sed TRY_TO(TraverseStmt(D->getInitExpr())); 1705210299Sed }) 1706210299Sed 1707210299SedDEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, { 1708210299Sed // Like UnresolvedUsingTypenameDecl, but without the 'typename': 1709210299Sed // template <class T> Class A : public Base<T> { using Base<T>::foo; }; 1710219077Sdim TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); 1711234353Sdim TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); 1712210299Sed }) 1713210299Sed 1714218893SdimDEF_TRAVERSE_DECL(IndirectFieldDecl, {}) 1715218893Sdim 1716208600Srdivackytemplate<typename Derived> 1717210299Sedbool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) { 1718221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); 1719210299Sed if (D->getTypeSourceInfo()) 1720210299Sed TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); 1721221345Sdim else 1722221345Sdim TRY_TO(TraverseType(D->getType())); 1723210299Sed return true; 1724208600Srdivacky} 1725208600Srdivacky 1726251662SdimDEF_TRAVERSE_DECL(MSPropertyDecl, { 1727251662Sdim TRY_TO(TraverseDeclaratorHelper(D)); 1728251662Sdim }) 1729251662Sdim 1730210299SedDEF_TRAVERSE_DECL(FieldDecl, { 1731210299Sed TRY_TO(TraverseDeclaratorHelper(D)); 1732210299Sed if (D->isBitField()) 1733210299Sed TRY_TO(TraverseStmt(D->getBitWidth())); 1734234353Sdim else if (D->hasInClassInitializer()) 1735234353Sdim TRY_TO(TraverseStmt(D->getInClassInitializer())); 1736210299Sed }) 1737208600Srdivacky 1738210299SedDEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, { 1739210299Sed TRY_TO(TraverseDeclaratorHelper(D)); 1740210299Sed if (D->isBitField()) 1741210299Sed TRY_TO(TraverseStmt(D->getBitWidth())); 1742210299Sed // FIXME: implement the rest. 1743210299Sed }) 1744208600Srdivacky 1745210299SedDEF_TRAVERSE_DECL(ObjCIvarDecl, { 1746210299Sed TRY_TO(TraverseDeclaratorHelper(D)); 1747210299Sed if (D->isBitField()) 1748210299Sed TRY_TO(TraverseStmt(D->getBitWidth())); 1749210299Sed // FIXME: implement the rest. 1750210299Sed }) 1751210299Sed 1752208600Srdivackytemplate<typename Derived> 1753210299Sedbool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { 1754221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); 1755234353Sdim TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); 1756208600Srdivacky 1757212904Sdim // If we're an explicit template specialization, iterate over the 1758218893Sdim // template args that were explicitly specified. If we were doing 1759218893Sdim // this in typing order, we'd do it between the return type and 1760218893Sdim // the function args, but both are handled by the FunctionTypeLoc 1761218893Sdim // above, so we have to choose one side. I've decided to do before. 1762212904Sdim if (const FunctionTemplateSpecializationInfo *FTSI = 1763212904Sdim D->getTemplateSpecializationInfo()) { 1764212904Sdim if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared && 1765212904Sdim FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) { 1766212904Sdim // A specialization might not have explicit template arguments if it has 1767212904Sdim // a templated return type and concrete arguments. 1768226633Sdim if (const ASTTemplateArgumentListInfo *TALI = 1769212904Sdim FTSI->TemplateArgumentsAsWritten) { 1770226633Sdim TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(), 1771226633Sdim TALI->NumTemplateArgs)); 1772212904Sdim } 1773212904Sdim } 1774212904Sdim } 1775212904Sdim 1776218893Sdim // Visit the function type itself, which can be either 1777218893Sdim // FunctionNoProtoType or FunctionProtoType, or a typedef. This 1778218893Sdim // also covers the return type and the function parameters, 1779218893Sdim // including exception specifications. 1780249423Sdim if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) { 1781239462Sdim TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); 1782263508Sdim } else if (getDerived().shouldVisitImplicitCode()) { 1783263508Sdim // Visit parameter variable declarations of the implicit function 1784263508Sdim // if the traverser is visiting implicit code. Parameter variable 1785263508Sdim // declarations do not have valid TypeSourceInfo, so to visit them 1786263508Sdim // we need to traverse the declarations explicitly. 1787263508Sdim for (FunctionDecl::param_const_iterator I = D->param_begin(), 1788263508Sdim E = D->param_end(); I != E; ++I) 1789263508Sdim TRY_TO(TraverseDecl(*I)); 1790239462Sdim } 1791212904Sdim 1792210299Sed if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) { 1793210299Sed // Constructor initializers. 1794210299Sed for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(), 1795210299Sed E = Ctor->init_end(); 1796210299Sed I != E; ++I) { 1797210299Sed TRY_TO(TraverseConstructorInitializer(*I)); 1798210299Sed } 1799210299Sed } 1800210299Sed 1801210299Sed if (D->isThisDeclarationADefinition()) { 1802210299Sed TRY_TO(TraverseStmt(D->getBody())); // Function body. 1803210299Sed } 1804210299Sed return true; 1805208600Srdivacky} 1806208600Srdivacky 1807210299SedDEF_TRAVERSE_DECL(FunctionDecl, { 1808210299Sed // We skip decls_begin/decls_end, which are already covered by 1809210299Sed // TraverseFunctionHelper(). 1810210299Sed return TraverseFunctionHelper(D); 1811210299Sed }) 1812210299Sed 1813210299SedDEF_TRAVERSE_DECL(CXXMethodDecl, { 1814210299Sed // We skip decls_begin/decls_end, which are already covered by 1815210299Sed // TraverseFunctionHelper(). 1816210299Sed return TraverseFunctionHelper(D); 1817210299Sed }) 1818210299Sed 1819210299SedDEF_TRAVERSE_DECL(CXXConstructorDecl, { 1820210299Sed // We skip decls_begin/decls_end, which are already covered by 1821210299Sed // TraverseFunctionHelper(). 1822210299Sed return TraverseFunctionHelper(D); 1823210299Sed }) 1824210299Sed 1825210299Sed// CXXConversionDecl is the declaration of a type conversion operator. 1826210299Sed// It's not a cast expression. 1827210299SedDEF_TRAVERSE_DECL(CXXConversionDecl, { 1828210299Sed // We skip decls_begin/decls_end, which are already covered by 1829210299Sed // TraverseFunctionHelper(). 1830210299Sed return TraverseFunctionHelper(D); 1831210299Sed }) 1832210299Sed 1833210299SedDEF_TRAVERSE_DECL(CXXDestructorDecl, { 1834210299Sed // We skip decls_begin/decls_end, which are already covered by 1835210299Sed // TraverseFunctionHelper(). 1836210299Sed return TraverseFunctionHelper(D); 1837210299Sed }) 1838210299Sed 1839208600Srdivackytemplate<typename Derived> 1840210299Sedbool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) { 1841210299Sed TRY_TO(TraverseDeclaratorHelper(D)); 1842234353Sdim // Default params are taken care of when we traverse the ParmVarDecl. 1843239462Sdim if (!isa<ParmVarDecl>(D) && 1844239462Sdim (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode())) 1845234353Sdim TRY_TO(TraverseStmt(D->getInit())); 1846210299Sed return true; 1847208600Srdivacky} 1848208600Srdivacky 1849210299SedDEF_TRAVERSE_DECL(VarDecl, { 1850210299Sed TRY_TO(TraverseVarHelper(D)); 1851210299Sed }) 1852208600Srdivacky 1853210299SedDEF_TRAVERSE_DECL(ImplicitParamDecl, { 1854210299Sed TRY_TO(TraverseVarHelper(D)); 1855210299Sed }) 1856208600Srdivacky 1857210299SedDEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, { 1858210299Sed // A non-type template parameter, e.g. "S" in template<int S> class Foo ... 1859218893Sdim TRY_TO(TraverseDeclaratorHelper(D)); 1860239462Sdim if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 1861239462Sdim TRY_TO(TraverseStmt(D->getDefaultArgument())); 1862210299Sed }) 1863208600Srdivacky 1864210299SedDEF_TRAVERSE_DECL(ParmVarDecl, { 1865212904Sdim TRY_TO(TraverseVarHelper(D)); 1866212904Sdim 1867210299Sed if (D->hasDefaultArg() && 1868210299Sed D->hasUninstantiatedDefaultArg() && 1869210299Sed !D->hasUnparsedDefaultArg()) 1870210299Sed TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg())); 1871208600Srdivacky 1872210299Sed if (D->hasDefaultArg() && 1873210299Sed !D->hasUninstantiatedDefaultArg() && 1874210299Sed !D->hasUnparsedDefaultArg()) 1875210299Sed TRY_TO(TraverseStmt(D->getDefaultArg())); 1876210299Sed }) 1877208600Srdivacky 1878210299Sed#undef DEF_TRAVERSE_DECL 1879210299Sed 1880210299Sed// ----------------- Stmt traversal ----------------- 1881210299Sed// 1882210299Sed// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating 1883218893Sdim// over the children defined in children() (every stmt defines these, 1884218893Sdim// though sometimes the range is empty). Each individual Traverse* 1885218893Sdim// method only needs to worry about children other than those. To see 1886218893Sdim// what children() does for a given class, see, e.g., 1887218893Sdim// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html 1888210299Sed 1889210299Sed// This macro makes available a variable S, the passed-in stmt. 1890210299Sed#define DEF_TRAVERSE_STMT(STMT, CODE) \ 1891210299Sedtemplate<typename Derived> \ 1892210299Sedbool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \ 1893210299Sed TRY_TO(WalkUpFrom##STMT(S)); \ 1894210299Sed { CODE; } \ 1895218893Sdim for (Stmt::child_range range = S->children(); range; ++range) { \ 1896218893Sdim TRY_TO(TraverseStmt(*range)); \ 1897210299Sed } \ 1898210299Sed return true; \ 1899208600Srdivacky} 1900208600Srdivacky 1901243830SdimDEF_TRAVERSE_STMT(GCCAsmStmt, { 1902210299Sed TRY_TO(TraverseStmt(S->getAsmString())); 1903210299Sed for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) { 1904210299Sed TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I))); 1905210299Sed } 1906210299Sed for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) { 1907210299Sed TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I))); 1908210299Sed } 1909210299Sed for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) { 1910243830Sdim TRY_TO(TraverseStmt(S->getClobberStringLiteral(I))); 1911210299Sed } 1912218893Sdim // children() iterates over inputExpr and outputExpr. 1913210299Sed }) 1914208600Srdivacky 1915239462SdimDEF_TRAVERSE_STMT(MSAsmStmt, { 1916239462Sdim // FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once 1917239462Sdim // added this needs to be implemented. 1918239462Sdim }) 1919239462Sdim 1920210299SedDEF_TRAVERSE_STMT(CXXCatchStmt, { 1921212904Sdim TRY_TO(TraverseDecl(S->getExceptionDecl())); 1922218893Sdim // children() iterates over the handler block. 1923210299Sed }) 1924208600Srdivacky 1925212904SdimDEF_TRAVERSE_STMT(DeclStmt, { 1926212904Sdim for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end(); 1927212904Sdim I != E; ++I) { 1928212904Sdim TRY_TO(TraverseDecl(*I)); 1929212904Sdim } 1930218893Sdim // Suppress the default iteration over children() by 1931212904Sdim // returning. Here's why: A DeclStmt looks like 'type var [= 1932212904Sdim // initializer]'. The decls above already traverse over the 1933212904Sdim // initializers, so we don't have to do it again (which 1934218893Sdim // children() would do). 1935212904Sdim return true; 1936210299Sed }) 1937208600Srdivacky 1938208600Srdivacky 1939210299Sed// These non-expr stmts (most of them), do not need any action except 1940210299Sed// iterating over the children. 1941210299SedDEF_TRAVERSE_STMT(BreakStmt, { }) 1942212904SdimDEF_TRAVERSE_STMT(CXXTryStmt, { }) 1943212904SdimDEF_TRAVERSE_STMT(CaseStmt, { }) 1944210299SedDEF_TRAVERSE_STMT(CompoundStmt, { }) 1945210299SedDEF_TRAVERSE_STMT(ContinueStmt, { }) 1946212904SdimDEF_TRAVERSE_STMT(DefaultStmt, { }) 1947210299SedDEF_TRAVERSE_STMT(DoStmt, { }) 1948212904SdimDEF_TRAVERSE_STMT(ForStmt, { }) 1949210299SedDEF_TRAVERSE_STMT(GotoStmt, { }) 1950212904SdimDEF_TRAVERSE_STMT(IfStmt, { }) 1951210299SedDEF_TRAVERSE_STMT(IndirectGotoStmt, { }) 1952210299SedDEF_TRAVERSE_STMT(LabelStmt, { }) 1953234982SdimDEF_TRAVERSE_STMT(AttributedStmt, { }) 1954210299SedDEF_TRAVERSE_STMT(NullStmt, { }) 1955210299SedDEF_TRAVERSE_STMT(ObjCAtCatchStmt, { }) 1956210299SedDEF_TRAVERSE_STMT(ObjCAtFinallyStmt, { }) 1957210299SedDEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { }) 1958210299SedDEF_TRAVERSE_STMT(ObjCAtThrowStmt, { }) 1959210299SedDEF_TRAVERSE_STMT(ObjCAtTryStmt, { }) 1960210299SedDEF_TRAVERSE_STMT(ObjCForCollectionStmt, { }) 1961224145SdimDEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { }) 1962239462SdimDEF_TRAVERSE_STMT(CXXForRangeStmt, { 1963239462Sdim if (!getDerived().shouldVisitImplicitCode()) { 1964239462Sdim TRY_TO(TraverseStmt(S->getLoopVarStmt())); 1965239462Sdim TRY_TO(TraverseStmt(S->getRangeInit())); 1966239462Sdim TRY_TO(TraverseStmt(S->getBody())); 1967239462Sdim // Visit everything else only if shouldVisitImplicitCode(). 1968239462Sdim return true; 1969239462Sdim } 1970239462Sdim}) 1971234353SdimDEF_TRAVERSE_STMT(MSDependentExistsStmt, { 1972234353Sdim TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); 1973234353Sdim TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); 1974234353Sdim}) 1975210299SedDEF_TRAVERSE_STMT(ReturnStmt, { }) 1976210299SedDEF_TRAVERSE_STMT(SwitchStmt, { }) 1977212904SdimDEF_TRAVERSE_STMT(WhileStmt, { }) 1978208600Srdivacky 1979212904Sdim 1980210299SedDEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, { 1981221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); 1982234353Sdim TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo())); 1983210299Sed if (S->hasExplicitTemplateArgs()) { 1984210299Sed TRY_TO(TraverseTemplateArgumentLocsHelper( 1985210299Sed S->getTemplateArgs(), S->getNumTemplateArgs())); 1986208600Srdivacky } 1987208600Srdivacky }) 1988208600Srdivacky 1989210299SedDEF_TRAVERSE_STMT(DeclRefExpr, { 1990221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); 1991234353Sdim TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); 1992210299Sed TRY_TO(TraverseTemplateArgumentLocsHelper( 1993210299Sed S->getTemplateArgs(), S->getNumTemplateArgs())); 1994210299Sed }) 1995208600Srdivacky 1996210299SedDEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, { 1997219077Sdim TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); 1998234353Sdim TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); 1999210299Sed if (S->hasExplicitTemplateArgs()) { 2000210299Sed TRY_TO(TraverseTemplateArgumentLocsHelper( 2001210299Sed S->getExplicitTemplateArgs().getTemplateArgs(), 2002210299Sed S->getNumTemplateArgs())); 2003208600Srdivacky } 2004208600Srdivacky }) 2005208600Srdivacky 2006210299SedDEF_TRAVERSE_STMT(MemberExpr, { 2007221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); 2008234353Sdim TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo())); 2009210299Sed TRY_TO(TraverseTemplateArgumentLocsHelper( 2010210299Sed S->getTemplateArgs(), S->getNumTemplateArgs())); 2011210299Sed }) 2012208600Srdivacky 2013210299SedDEF_TRAVERSE_STMT(ImplicitCastExpr, { 2014210299Sed // We don't traverse the cast type, as it's not written in the 2015210299Sed // source code. 2016210299Sed }) 2017208600Srdivacky 2018210299SedDEF_TRAVERSE_STMT(CStyleCastExpr, { 2019218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); 2020210299Sed }) 2021210299Sed 2022210299SedDEF_TRAVERSE_STMT(CXXFunctionalCastExpr, { 2023218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); 2024210299Sed }) 2025210299Sed 2026210299SedDEF_TRAVERSE_STMT(CXXConstCastExpr, { 2027218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); 2028210299Sed }) 2029210299Sed 2030210299SedDEF_TRAVERSE_STMT(CXXDynamicCastExpr, { 2031218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); 2032210299Sed }) 2033210299Sed 2034210299SedDEF_TRAVERSE_STMT(CXXReinterpretCastExpr, { 2035218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); 2036210299Sed }) 2037210299Sed 2038210299SedDEF_TRAVERSE_STMT(CXXStaticCastExpr, { 2039218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); 2040210299Sed }) 2041210299Sed 2042210299Sed// InitListExpr is a tricky one, because we want to do all our work on 2043210299Sed// the syntactic form of the listexpr, but this method takes the 2044210299Sed// semantic form by default. We can't use the macro helper because it 2045210299Sed// calls WalkUp*() on the semantic form, before our code can convert 2046210299Sed// to the syntactic form. 2047210299Sedtemplate<typename Derived> 2048210299Sedbool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) { 2049210299Sed if (InitListExpr *Syn = S->getSyntacticForm()) 2050210299Sed S = Syn; 2051210299Sed TRY_TO(WalkUpFromInitListExpr(S)); 2052210299Sed // All we need are the default actions. FIXME: use a helper function. 2053218893Sdim for (Stmt::child_range range = S->children(); range; ++range) { 2054218893Sdim TRY_TO(TraverseStmt(*range)); 2055210299Sed } 2056210299Sed return true; 2057210299Sed} 2058210299Sed 2059221345Sdim// GenericSelectionExpr is a special case because the types and expressions 2060221345Sdim// are interleaved. We also need to watch out for null types (default 2061221345Sdim// generic associations). 2062221345Sdimtemplate<typename Derived> 2063221345Sdimbool RecursiveASTVisitor<Derived>:: 2064221345SdimTraverseGenericSelectionExpr(GenericSelectionExpr *S) { 2065221345Sdim TRY_TO(WalkUpFromGenericSelectionExpr(S)); 2066221345Sdim TRY_TO(TraverseStmt(S->getControllingExpr())); 2067221345Sdim for (unsigned i = 0; i != S->getNumAssocs(); ++i) { 2068221345Sdim if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i)) 2069221345Sdim TRY_TO(TraverseTypeLoc(TS->getTypeLoc())); 2070221345Sdim TRY_TO(TraverseStmt(S->getAssocExpr(i))); 2071221345Sdim } 2072221345Sdim return true; 2073221345Sdim} 2074221345Sdim 2075234353Sdim// PseudoObjectExpr is a special case because of the wierdness with 2076234353Sdim// syntactic expressions and opaque values. 2077234353Sdimtemplate<typename Derived> 2078234353Sdimbool RecursiveASTVisitor<Derived>:: 2079234353SdimTraversePseudoObjectExpr(PseudoObjectExpr *S) { 2080234353Sdim TRY_TO(WalkUpFromPseudoObjectExpr(S)); 2081234353Sdim TRY_TO(TraverseStmt(S->getSyntacticForm())); 2082234353Sdim for (PseudoObjectExpr::semantics_iterator 2083234353Sdim i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i) { 2084234353Sdim Expr *sub = *i; 2085234353Sdim if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub)) 2086234353Sdim sub = OVE->getSourceExpr(); 2087234353Sdim TRY_TO(TraverseStmt(sub)); 2088234353Sdim } 2089234353Sdim return true; 2090234353Sdim} 2091234353Sdim 2092210299SedDEF_TRAVERSE_STMT(CXXScalarValueInitExpr, { 2093210299Sed // This is called for code like 'return T()' where T is a built-in 2094210299Sed // (i.e. non-class) type. 2095218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); 2096210299Sed }) 2097210299Sed 2098210299SedDEF_TRAVERSE_STMT(CXXNewExpr, { 2099218893Sdim // The child-iterator will pick up the other arguments. 2100218893Sdim TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc())); 2101210299Sed }) 2102210299Sed 2103212904SdimDEF_TRAVERSE_STMT(OffsetOfExpr, { 2104212904Sdim // The child-iterator will pick up the expression representing 2105212904Sdim // the field. 2106212904Sdim // FIMXE: for code like offsetof(Foo, a.b.c), should we get 2107212904Sdim // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c? 2108212904Sdim TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); 2109212904Sdim }) 2110212904Sdim 2111221345SdimDEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, { 2112212904Sdim // The child-iterator will pick up the arg if it's an expression, 2113212904Sdim // but not if it's a type. 2114212904Sdim if (S->isArgumentType()) 2115212904Sdim TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc())); 2116212904Sdim }) 2117212904Sdim 2118212904SdimDEF_TRAVERSE_STMT(CXXTypeidExpr, { 2119212904Sdim // The child-iterator will pick up the arg if it's an expression, 2120212904Sdim // but not if it's a type. 2121212904Sdim if (S->isTypeOperand()) 2122212904Sdim TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc())); 2123212904Sdim }) 2124212904Sdim 2125251662SdimDEF_TRAVERSE_STMT(MSPropertyRefExpr, { 2126251662Sdim TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); 2127251662Sdim}) 2128251662Sdim 2129218893SdimDEF_TRAVERSE_STMT(CXXUuidofExpr, { 2130218893Sdim // The child-iterator will pick up the arg if it's an expression, 2131218893Sdim // but not if it's a type. 2132218893Sdim if (S->isTypeOperand()) 2133218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc())); 2134212904Sdim }) 2135212904Sdim 2136212904SdimDEF_TRAVERSE_STMT(UnaryTypeTraitExpr, { 2137218893Sdim TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc())); 2138212904Sdim }) 2139212904Sdim 2140218893SdimDEF_TRAVERSE_STMT(BinaryTypeTraitExpr, { 2141218893Sdim TRY_TO(TraverseTypeLoc(S->getLhsTypeSourceInfo()->getTypeLoc())); 2142218893Sdim TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc())); 2143218893Sdim }) 2144218893Sdim 2145234353SdimDEF_TRAVERSE_STMT(TypeTraitExpr, { 2146234353Sdim for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I) 2147234353Sdim TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc())); 2148234353Sdim}) 2149234353Sdim 2150221345SdimDEF_TRAVERSE_STMT(ArrayTypeTraitExpr, { 2151221345Sdim TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc())); 2152221345Sdim }) 2153221345Sdim 2154221345SdimDEF_TRAVERSE_STMT(ExpressionTraitExpr, { 2155221345Sdim TRY_TO(TraverseStmt(S->getQueriedExpression())); 2156221345Sdim }) 2157221345Sdim 2158218893SdimDEF_TRAVERSE_STMT(VAArgExpr, { 2159218893Sdim // The child-iterator will pick up the expression argument. 2160218893Sdim TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc())); 2161218893Sdim }) 2162218893Sdim 2163218893SdimDEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, { 2164218893Sdim // This is called for code like 'return T()' where T is a class type. 2165218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); 2166218893Sdim }) 2167218893Sdim 2168234353Sdim// Walk only the visible parts of lambda expressions. 2169234353Sdimtemplate<typename Derived> 2170234353Sdimbool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) { 2171263508Sdim TRY_TO(WalkUpFromLambdaExpr(S)); 2172263508Sdim 2173234353Sdim for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(), 2174234353Sdim CEnd = S->explicit_capture_end(); 2175234353Sdim C != CEnd; ++C) { 2176263508Sdim TRY_TO(TraverseLambdaCapture(S, C)); 2177234353Sdim } 2178234353Sdim 2179234353Sdim if (S->hasExplicitParameters() || S->hasExplicitResultType()) { 2180234353Sdim TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); 2181234353Sdim if (S->hasExplicitParameters() && S->hasExplicitResultType()) { 2182234353Sdim // Visit the whole type. 2183234353Sdim TRY_TO(TraverseTypeLoc(TL)); 2184249423Sdim } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) { 2185234353Sdim if (S->hasExplicitParameters()) { 2186234353Sdim // Visit parameters. 2187234353Sdim for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) { 2188234353Sdim TRY_TO(TraverseDecl(Proto.getArg(I))); 2189234353Sdim } 2190234353Sdim } else { 2191234353Sdim TRY_TO(TraverseTypeLoc(Proto.getResultLoc())); 2192234353Sdim } 2193234353Sdim } 2194234353Sdim } 2195234353Sdim 2196263508Sdim TRY_TO(TraverseLambdaBody(S)); 2197234353Sdim return true; 2198234353Sdim} 2199234353Sdim 2200218893SdimDEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { 2201218893Sdim // This is called for code like 'T()', where T is a template argument. 2202218893Sdim TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); 2203218893Sdim }) 2204218893Sdim 2205218893Sdim// These expressions all might take explicit template arguments. 2206218893Sdim// We traverse those if so. FIXME: implement these. 2207218893SdimDEF_TRAVERSE_STMT(CXXConstructExpr, { }) 2208218893SdimDEF_TRAVERSE_STMT(CallExpr, { }) 2209218893SdimDEF_TRAVERSE_STMT(CXXMemberCallExpr, { }) 2210218893Sdim 2211210299Sed// These exprs (most of them), do not need any action except iterating 2212210299Sed// over the children. 2213210299SedDEF_TRAVERSE_STMT(AddrLabelExpr, { }) 2214210299SedDEF_TRAVERSE_STMT(ArraySubscriptExpr, { }) 2215221345SdimDEF_TRAVERSE_STMT(BlockExpr, { 2216221345Sdim TRY_TO(TraverseDecl(S->getBlockDecl())); 2217221345Sdim return true; // no child statements to loop through. 2218221345Sdim}) 2219210299SedDEF_TRAVERSE_STMT(ChooseExpr, { }) 2220243830SdimDEF_TRAVERSE_STMT(CompoundLiteralExpr, { 2221243830Sdim TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); 2222243830Sdim}) 2223210299SedDEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { }) 2224210299SedDEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { }) 2225210299SedDEF_TRAVERSE_STMT(CXXDefaultArgExpr, { }) 2226251662SdimDEF_TRAVERSE_STMT(CXXDefaultInitExpr, { }) 2227210299SedDEF_TRAVERSE_STMT(CXXDeleteExpr, { }) 2228218893SdimDEF_TRAVERSE_STMT(ExprWithCleanups, { }) 2229210299SedDEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { }) 2230263508SdimDEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { }) 2231234353SdimDEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { 2232219077Sdim TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); 2233218893Sdim if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo()) 2234218893Sdim TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc())); 2235218893Sdim if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo()) 2236218893Sdim TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc())); 2237218893Sdim}) 2238210299SedDEF_TRAVERSE_STMT(CXXThisExpr, { }) 2239210299SedDEF_TRAVERSE_STMT(CXXThrowExpr, { }) 2240234353SdimDEF_TRAVERSE_STMT(UserDefinedLiteral, { }) 2241210299SedDEF_TRAVERSE_STMT(DesignatedInitExpr, { }) 2242210299SedDEF_TRAVERSE_STMT(ExtVectorElementExpr, { }) 2243210299SedDEF_TRAVERSE_STMT(GNUNullExpr, { }) 2244210299SedDEF_TRAVERSE_STMT(ImplicitValueInitExpr, { }) 2245234353SdimDEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, { }) 2246239462SdimDEF_TRAVERSE_STMT(ObjCEncodeExpr, { 2247239462Sdim if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo()) 2248239462Sdim TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); 2249239462Sdim}) 2250210299SedDEF_TRAVERSE_STMT(ObjCIsaExpr, { }) 2251210299SedDEF_TRAVERSE_STMT(ObjCIvarRefExpr, { }) 2252251662SdimDEF_TRAVERSE_STMT(ObjCMessageExpr, { 2253251662Sdim if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo()) 2254251662Sdim TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); 2255251662Sdim}) 2256210299SedDEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { }) 2257234353SdimDEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { }) 2258210299SedDEF_TRAVERSE_STMT(ObjCProtocolExpr, { }) 2259210299SedDEF_TRAVERSE_STMT(ObjCSelectorExpr, { }) 2260224145SdimDEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { }) 2261224145SdimDEF_TRAVERSE_STMT(ObjCBridgedCastExpr, { 2262224145Sdim TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); 2263224145Sdim}) 2264210299SedDEF_TRAVERSE_STMT(ParenExpr, { }) 2265210299SedDEF_TRAVERSE_STMT(ParenListExpr, { }) 2266210299SedDEF_TRAVERSE_STMT(PredefinedExpr, { }) 2267210299SedDEF_TRAVERSE_STMT(ShuffleVectorExpr, { }) 2268263508SdimDEF_TRAVERSE_STMT(ConvertVectorExpr, { }) 2269210299SedDEF_TRAVERSE_STMT(StmtExpr, { }) 2270218893SdimDEF_TRAVERSE_STMT(UnresolvedLookupExpr, { 2271221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); 2272218893Sdim if (S->hasExplicitTemplateArgs()) { 2273234353Sdim TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), 2274218893Sdim S->getNumTemplateArgs())); 2275218893Sdim } 2276218893Sdim}) 2277234353Sdim 2278218893SdimDEF_TRAVERSE_STMT(UnresolvedMemberExpr, { 2279221345Sdim TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); 2280218893Sdim if (S->hasExplicitTemplateArgs()) { 2281234353Sdim TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), 2282218893Sdim S->getNumTemplateArgs())); 2283218893Sdim } 2284218893Sdim}) 2285210299Sed 2286221345SdimDEF_TRAVERSE_STMT(SEHTryStmt, {}) 2287221345SdimDEF_TRAVERSE_STMT(SEHExceptStmt, {}) 2288221345SdimDEF_TRAVERSE_STMT(SEHFinallyStmt,{}) 2289251662SdimDEF_TRAVERSE_STMT(CapturedStmt, { 2290251662Sdim TRY_TO(TraverseDecl(S->getCapturedDecl())); 2291251662Sdim}) 2292221345Sdim 2293210299SedDEF_TRAVERSE_STMT(CXXOperatorCallExpr, { }) 2294218893SdimDEF_TRAVERSE_STMT(OpaqueValueExpr, { }) 2295218893SdimDEF_TRAVERSE_STMT(CUDAKernelCallExpr, { }) 2296210299Sed 2297210299Sed// These operators (all of them) do not need any action except 2298210299Sed// iterating over the children. 2299218893SdimDEF_TRAVERSE_STMT(BinaryConditionalOperator, { }) 2300210299SedDEF_TRAVERSE_STMT(ConditionalOperator, { }) 2301210299SedDEF_TRAVERSE_STMT(UnaryOperator, { }) 2302210299SedDEF_TRAVERSE_STMT(BinaryOperator, { }) 2303210299SedDEF_TRAVERSE_STMT(CompoundAssignOperator, { }) 2304218893SdimDEF_TRAVERSE_STMT(CXXNoexceptExpr, { }) 2305218893SdimDEF_TRAVERSE_STMT(PackExpansionExpr, { }) 2306218893SdimDEF_TRAVERSE_STMT(SizeOfPackExpr, { }) 2307218893SdimDEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { }) 2308224145SdimDEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { }) 2309243830SdimDEF_TRAVERSE_STMT(FunctionParmPackExpr, { }) 2310224145SdimDEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { }) 2311226633SdimDEF_TRAVERSE_STMT(AtomicExpr, { }) 2312210299Sed 2313210299Sed// These literals (all of them) do not need any action. 2314210299SedDEF_TRAVERSE_STMT(IntegerLiteral, { }) 2315210299SedDEF_TRAVERSE_STMT(CharacterLiteral, { }) 2316210299SedDEF_TRAVERSE_STMT(FloatingLiteral, { }) 2317210299SedDEF_TRAVERSE_STMT(ImaginaryLiteral, { }) 2318210299SedDEF_TRAVERSE_STMT(StringLiteral, { }) 2319210299SedDEF_TRAVERSE_STMT(ObjCStringLiteral, { }) 2320239462SdimDEF_TRAVERSE_STMT(ObjCBoxedExpr, { }) 2321234353SdimDEF_TRAVERSE_STMT(ObjCArrayLiteral, { }) 2322234353SdimDEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { }) 2323223017Sdim 2324223017Sdim// Traverse OpenCL: AsType, Convert. 2325223017SdimDEF_TRAVERSE_STMT(AsTypeExpr, { }) 2326210299Sed 2327263508Sdim// OpenMP directives. 2328263508SdimDEF_TRAVERSE_STMT(OMPParallelDirective, { 2329263508Sdim ArrayRef<OMPClause *> Clauses = S->clauses(); 2330263508Sdim for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); 2331263508Sdim I != E; ++I) 2332263508Sdim if (!TraverseOMPClause(*I)) return false; 2333263508Sdim}) 2334263508Sdim 2335263508Sdim// OpenMP clauses. 2336263508Sdimtemplate<typename Derived> 2337263508Sdimbool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { 2338263508Sdim if (!C) return true; 2339263508Sdim switch (C->getClauseKind()) { 2340263508Sdim#define OPENMP_CLAUSE(Name, Class) \ 2341263508Sdim case OMPC_##Name: \ 2342263508Sdim return getDerived().Visit##Class(static_cast<Class*>(C)); 2343263508Sdim#include "clang/Basic/OpenMPKinds.def" 2344263508Sdim default: break; 2345263508Sdim } 2346263508Sdim return true; 2347263508Sdim} 2348263508Sdim 2349263508Sdimtemplate<typename Derived> 2350263508Sdimbool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) { 2351263508Sdim return true; 2352263508Sdim} 2353263508Sdim 2354263508Sdimtemplate<typename Derived> 2355263508Sdimtemplate<typename T> 2356263508Sdimvoid RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { 2357263508Sdim for (typename T::varlist_iterator I = Node->varlist_begin(), 2358263508Sdim E = Node->varlist_end(); 2359263508Sdim I != E; ++I) 2360263508Sdim TraverseStmt(*I); 2361263508Sdim} 2362263508Sdim 2363263508Sdimtemplate<typename Derived> 2364263508Sdimbool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) { 2365263508Sdim VisitOMPClauseList(C); 2366263508Sdim return true; 2367263508Sdim} 2368263508Sdim 2369263508Sdimtemplate<typename Derived> 2370263508Sdimbool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause( 2371263508Sdim OMPFirstprivateClause *C) { 2372263508Sdim VisitOMPClauseList(C); 2373263508Sdim return true; 2374263508Sdim} 2375263508Sdim 2376263508Sdimtemplate<typename Derived> 2377263508Sdimbool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) { 2378263508Sdim VisitOMPClauseList(C); 2379263508Sdim return true; 2380263508Sdim} 2381263508Sdim 2382210299Sed// FIXME: look at the following tricky-seeming exprs to see if we 2383210299Sed// need to recurse on anything. These are ones that have methods 2384210299Sed// returning decls or qualtypes or nestednamespecifier -- though I'm 2385210299Sed// not sure if they own them -- or just seemed very complicated, or 2386210299Sed// had lots of sub-types to explore. 2387210299Sed// 2388210299Sed// VisitOverloadExpr and its children: recurse on template args? etc? 2389210299Sed 2390210299Sed// FIXME: go through all the stmts and exprs again, and see which of them 2391210299Sed// create new types, and recurse on the types (TypeLocs?) of those. 2392210299Sed// Candidates: 2393210299Sed// 2394210299Sed// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html 2395221345Sdim// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html 2396210299Sed// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html 2397210299Sed// Every class that has getQualifier. 2398210299Sed 2399210299Sed#undef DEF_TRAVERSE_STMT 2400210299Sed 2401210299Sed#undef TRY_TO 2402210299Sed 2403208600Srdivacky} // end namespace clang 2404208600Srdivacky 2405208600Srdivacky#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H 2406