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 21namespace clang { 22 23namespace idx { 24 25/// \brief Traverses the full AST, both Decls and Stmts. 26template<typename ImplClass> 27class ASTVisitor : public DeclVisitor<ImplClass>, 28 public StmtVisitor<ImplClass>, 29 public TypeLocVisitor<ImplClass> { 30public: 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 46 void Visit(Decl *D) { 47 Decl *PrevDecl = CurrentDecl; 48 CurrentDecl = D; 49 BaseDeclVisitor::Visit(D); 50 CurrentDecl = PrevDecl; 51 } 52 53 void VisitDeclaratorDecl(DeclaratorDecl *D) { 54 BaseDeclVisitor::VisitDeclaratorDecl(D); 55 if (TypeSourceInfo *TInfo = D->getTypeSourceInfo()) 56 Visit(TInfo->getTypeLoc()); 57 } 58 59 void VisitFunctionDecl(FunctionDecl *D) { 60 BaseDeclVisitor::VisitFunctionDecl(D); 61 if (D->isThisDeclarationADefinition()) 62 Visit(D->getBody()); 63 } 64 65 void VisitObjCMethodDecl(ObjCMethodDecl *D) { 66 BaseDeclVisitor::VisitObjCMethodDecl(D); 67 if (D->getBody()) 68 Visit(D->getBody()); 69 } 70 71 void VisitBlockDecl(BlockDecl *D) { 72 BaseDeclVisitor::VisitBlockDecl(D); 73 Visit(D->getBody()); 74 } 75 76 void VisitVarDecl(VarDecl *D) { 77 BaseDeclVisitor::VisitVarDecl(D); 78 if (Expr *Init = D->getInit()) 79 Visit(Init); 80 } 81 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 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 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 106 void VisitBlockExpr(BlockExpr *Node) { 107 // The BlockDecl is also visited by 'VisitDeclContext()'. No need to visit it twice. 108 } 109 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 120 void Visit(TypeLoc TL) { 121 for (; TL; TL = TL.getNextTypeLoc()) 122 BaseTypeLocVisitor::Visit(TL); 123 } 124 125 void VisitArrayLoc(ArrayTypeLoc TL) { 126 BaseTypeLocVisitor::VisitArrayTypeLoc(TL); 127 if (TL.getSizeExpr()) 128 Visit(TL.getSizeExpr()); 129 } 130 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