clang API Documentation
00001 //===--- ASTVisitor.h - Visitor for an ASTContext ---------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the ASTVisitor interface. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_INDEX_ASTVISITOR_H 00015 #define LLVM_CLANG_INDEX_ASTVISITOR_H 00016 00017 #include "clang/AST/DeclVisitor.h" 00018 #include "clang/AST/StmtVisitor.h" 00019 #include "clang/AST/TypeLocVisitor.h" 00020 00021 namespace clang { 00022 00023 namespace idx { 00024 00025 /// \brief Traverses the full AST, both Decls and Stmts. 00026 template<typename ImplClass> 00027 class ASTVisitor : public DeclVisitor<ImplClass>, 00028 public StmtVisitor<ImplClass>, 00029 public TypeLocVisitor<ImplClass> { 00030 public: 00031 ASTVisitor() : CurrentDecl(0) { } 00032 00033 Decl *CurrentDecl; 00034 00035 typedef ASTVisitor<ImplClass> Base; 00036 typedef DeclVisitor<ImplClass> BaseDeclVisitor; 00037 typedef StmtVisitor<ImplClass> BaseStmtVisitor; 00038 typedef TypeLocVisitor<ImplClass> BaseTypeLocVisitor; 00039 00040 using BaseStmtVisitor::Visit; 00041 00042 //===--------------------------------------------------------------------===// 00043 // DeclVisitor 00044 //===--------------------------------------------------------------------===// 00045 00046 void Visit(Decl *D) { 00047 Decl *PrevDecl = CurrentDecl; 00048 CurrentDecl = D; 00049 BaseDeclVisitor::Visit(D); 00050 CurrentDecl = PrevDecl; 00051 } 00052 00053 void VisitDeclaratorDecl(DeclaratorDecl *D) { 00054 BaseDeclVisitor::VisitDeclaratorDecl(D); 00055 if (TypeSourceInfo *TInfo = D->getTypeSourceInfo()) 00056 Visit(TInfo->getTypeLoc()); 00057 } 00058 00059 void VisitFunctionDecl(FunctionDecl *D) { 00060 BaseDeclVisitor::VisitFunctionDecl(D); 00061 if (D->isThisDeclarationADefinition()) 00062 Visit(D->getBody()); 00063 } 00064 00065 void VisitObjCMethodDecl(ObjCMethodDecl *D) { 00066 BaseDeclVisitor::VisitObjCMethodDecl(D); 00067 if (D->getBody()) 00068 Visit(D->getBody()); 00069 } 00070 00071 void VisitBlockDecl(BlockDecl *D) { 00072 BaseDeclVisitor::VisitBlockDecl(D); 00073 Visit(D->getBody()); 00074 } 00075 00076 void VisitVarDecl(VarDecl *D) { 00077 BaseDeclVisitor::VisitVarDecl(D); 00078 if (Expr *Init = D->getInit()) 00079 Visit(Init); 00080 } 00081 00082 void VisitDecl(Decl *D) { 00083 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)) 00084 return; 00085 00086 if (DeclContext *DC = dyn_cast<DeclContext>(D)) 00087 static_cast<ImplClass*>(this)->VisitDeclContext(DC); 00088 } 00089 00090 void VisitDeclContext(DeclContext *DC) { 00091 for (DeclContext::decl_iterator 00092 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) 00093 Visit(*I); 00094 } 00095 00096 //===--------------------------------------------------------------------===// 00097 // StmtVisitor 00098 //===--------------------------------------------------------------------===// 00099 00100 void VisitDeclStmt(DeclStmt *Node) { 00101 for (DeclStmt::decl_iterator 00102 I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) 00103 Visit(*I); 00104 } 00105 00106 void VisitBlockExpr(BlockExpr *Node) { 00107 // The BlockDecl is also visited by 'VisitDeclContext()'. No need to visit it twice. 00108 } 00109 00110 void VisitStmt(Stmt *Node) { 00111 for (Stmt::child_range I = Node->children(); I; ++I) 00112 if (*I) 00113 Visit(*I); 00114 } 00115 00116 //===--------------------------------------------------------------------===// 00117 // TypeLocVisitor 00118 //===--------------------------------------------------------------------===// 00119 00120 void Visit(TypeLoc TL) { 00121 for (; TL; TL = TL.getNextTypeLoc()) 00122 BaseTypeLocVisitor::Visit(TL); 00123 } 00124 00125 void VisitArrayLoc(ArrayTypeLoc TL) { 00126 BaseTypeLocVisitor::VisitArrayTypeLoc(TL); 00127 if (TL.getSizeExpr()) 00128 Visit(TL.getSizeExpr()); 00129 } 00130 00131 void VisitFunctionTypeLoc(FunctionTypeLoc TL) { 00132 BaseTypeLocVisitor::VisitFunctionTypeLoc(TL); 00133 for (unsigned i = 0; i != TL.getNumArgs(); ++i) 00134 Visit(TL.getArg(i)); 00135 } 00136 00137 }; 00138 00139 } // namespace idx 00140 00141 } // namespace clang 00142 00143 #endif