1 //===--- ASTVisitor.h - Visitor for an ASTContext ---------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the ASTVisitor interface. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_INDEX_ASTVISITOR_H 15 #define LLVM_CLANG_INDEX_ASTVISITOR_H 16 17 #include "clang/AST/DeclVisitor.h" 18 #include "clang/AST/StmtVisitor.h" 19 #include "clang/AST/TypeLocVisitor.h" 20 21 namespace clang { 22 23 namespace idx { 24 25 /// \brief Traverses the full AST, both Decls and Stmts. 26 template<typename ImplClass> 27 class ASTVisitor : public DeclVisitor<ImplClass>, 28 public StmtVisitor<ImplClass>, 29 public TypeLocVisitor<ImplClass> { 30 public: ASTVisitor()31 ASTVisitor() : CurrentDecl(0) { } 32 33 Decl *CurrentDecl; 34 35 typedef ASTVisitor<ImplClass> Base; 36 typedef DeclVisitor<ImplClass> BaseDeclVisitor; 37 typedef StmtVisitor<ImplClass> BaseStmtVisitor; 38 typedef TypeLocVisitor<ImplClass> BaseTypeLocVisitor; 39 40 using BaseStmtVisitor::Visit; 41 42 //===--------------------------------------------------------------------===// 43 // DeclVisitor 44 //===--------------------------------------------------------------------===// 45 Visit(Decl * D)46 void Visit(Decl *D) { 47 Decl *PrevDecl = CurrentDecl; 48 CurrentDecl = D; 49 BaseDeclVisitor::Visit(D); 50 CurrentDecl = PrevDecl; 51 } 52 VisitDeclaratorDecl(DeclaratorDecl * D)53 void VisitDeclaratorDecl(DeclaratorDecl *D) { 54 BaseDeclVisitor::VisitDeclaratorDecl(D); 55 if (TypeSourceInfo *TInfo = D->getTypeSourceInfo()) 56 Visit(TInfo->getTypeLoc()); 57 } 58 VisitFunctionDecl(FunctionDecl * D)59 void VisitFunctionDecl(FunctionDecl *D) { 60 BaseDeclVisitor::VisitFunctionDecl(D); 61 if (D->isThisDeclarationADefinition()) 62 Visit(D->getBody()); 63 } 64 VisitObjCMethodDecl(ObjCMethodDecl * D)65 void VisitObjCMethodDecl(ObjCMethodDecl *D) { 66 BaseDeclVisitor::VisitObjCMethodDecl(D); 67 if (D->getBody()) 68 Visit(D->getBody()); 69 } 70 VisitBlockDecl(BlockDecl * D)71 void VisitBlockDecl(BlockDecl *D) { 72 BaseDeclVisitor::VisitBlockDecl(D); 73 Visit(D->getBody()); 74 } 75 VisitVarDecl(VarDecl * D)76 void VisitVarDecl(VarDecl *D) { 77 BaseDeclVisitor::VisitVarDecl(D); 78 if (Expr *Init = D->getInit()) 79 Visit(Init); 80 } 81 VisitDecl(Decl * D)82 void VisitDecl(Decl *D) { 83 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)) 84 return; 85 86 if (DeclContext *DC = dyn_cast<DeclContext>(D)) 87 static_cast<ImplClass*>(this)->VisitDeclContext(DC); 88 } 89 VisitDeclContext(DeclContext * DC)90 void VisitDeclContext(DeclContext *DC) { 91 for (DeclContext::decl_iterator 92 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) 93 Visit(*I); 94 } 95 96 //===--------------------------------------------------------------------===// 97 // StmtVisitor 98 //===--------------------------------------------------------------------===// 99 VisitDeclStmt(DeclStmt * Node)100 void VisitDeclStmt(DeclStmt *Node) { 101 for (DeclStmt::decl_iterator 102 I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) 103 Visit(*I); 104 } 105 VisitBlockExpr(BlockExpr * Node)106 void VisitBlockExpr(BlockExpr *Node) { 107 // The BlockDecl is also visited by 'VisitDeclContext()'. No need to visit it twice. 108 } 109 VisitStmt(Stmt * Node)110 void VisitStmt(Stmt *Node) { 111 for (Stmt::child_range I = Node->children(); I; ++I) 112 if (*I) 113 Visit(*I); 114 } 115 116 //===--------------------------------------------------------------------===// 117 // TypeLocVisitor 118 //===--------------------------------------------------------------------===// 119 Visit(TypeLoc TL)120 void Visit(TypeLoc TL) { 121 for (; TL; TL = TL.getNextTypeLoc()) 122 BaseTypeLocVisitor::Visit(TL); 123 } 124 VisitArrayLoc(ArrayTypeLoc TL)125 void VisitArrayLoc(ArrayTypeLoc TL) { 126 BaseTypeLocVisitor::VisitArrayTypeLoc(TL); 127 if (TL.getSizeExpr()) 128 Visit(TL.getSizeExpr()); 129 } 130 VisitFunctionTypeLoc(FunctionTypeLoc TL)131 void VisitFunctionTypeLoc(FunctionTypeLoc TL) { 132 BaseTypeLocVisitor::VisitFunctionTypeLoc(TL); 133 for (unsigned i = 0; i != TL.getNumArgs(); ++i) 134 Visit(TL.getArg(i)); 135 } 136 137 }; 138 139 } // namespace idx 140 141 } // namespace clang 142 143 #endif 144