Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 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" |
Argyrios Kyrtzidis | 0c41180 | 2009-09-29 21:27:32 +0000 | [diff] [blame] | 19 | #include "clang/AST/TypeLocVisitor.h" |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 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>, |
Argyrios Kyrtzidis | b116884 | 2009-09-29 21:26:53 +0000 | [diff] [blame] | 28 | public StmtVisitor<ImplClass>, |
| 29 | public TypeLocVisitor<ImplClass> { |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 30 | public: |
| 31 | ASTVisitor() : CurrentDecl(0) { } |
| 32 | |
| 33 | Decl *CurrentDecl; |
| 34 | |
| 35 | typedef ASTVisitor<ImplClass> Base; |
| 36 | typedef DeclVisitor<ImplClass> BaseDeclVisitor; |
| 37 | typedef StmtVisitor<ImplClass> BaseStmtVisitor; |
Argyrios Kyrtzidis | b116884 | 2009-09-29 21:26:53 +0000 | [diff] [blame] | 38 | typedef TypeLocVisitor<ImplClass> BaseTypeLocVisitor; |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 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 | } |
Argyrios Kyrtzidis | b116884 | 2009-09-29 21:26:53 +0000 | [diff] [blame] | 52 | |
| 53 | void VisitDeclaratorDecl(DeclaratorDecl *D) { |
| 54 | BaseDeclVisitor::VisitDeclaratorDecl(D); |
| 55 | if (DeclaratorInfo *DInfo = D->getDeclaratorInfo()) |
| 56 | Visit(DInfo->getTypeLoc()); |
| 57 | } |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 58 | |
| 59 | void VisitFunctionDecl(FunctionDecl *D) { |
Argyrios Kyrtzidis | 09d8a95 | 2009-09-29 21:26:35 +0000 | [diff] [blame] | 60 | BaseDeclVisitor::VisitFunctionDecl(D); |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 61 | if (D->isThisDeclarationADefinition()) |
| 62 | Visit(D->getBody()); |
| 63 | } |
| 64 | |
| 65 | void VisitObjCMethodDecl(ObjCMethodDecl *D) { |
Argyrios Kyrtzidis | 09d8a95 | 2009-09-29 21:26:35 +0000 | [diff] [blame] | 66 | BaseDeclVisitor::VisitObjCMethodDecl(D); |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 67 | if (D->getBody()) |
| 68 | Visit(D->getBody()); |
| 69 | } |
| 70 | |
| 71 | void VisitBlockDecl(BlockDecl *D) { |
Argyrios Kyrtzidis | 09d8a95 | 2009-09-29 21:26:35 +0000 | [diff] [blame] | 72 | BaseDeclVisitor::VisitBlockDecl(D); |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 73 | Visit(D->getBody()); |
| 74 | } |
| 75 | |
| 76 | void VisitVarDecl(VarDecl *D) { |
Argyrios Kyrtzidis | 09d8a95 | 2009-09-29 21:26:35 +0000 | [diff] [blame] | 77 | BaseDeclVisitor::VisitVarDecl(D); |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 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 | |
Argyrios Kyrtzidis | ad6e5d1 | 2009-07-29 23:40:48 +0000 | [diff] [blame] | 106 | void VisitBlockExpr(BlockExpr *Node) { |
| 107 | Visit(Node->getBlockDecl()); |
| 108 | } |
| 109 | |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 110 | void VisitStmt(Stmt *Node) { |
| 111 | for (Stmt::child_iterator |
| 112 | I = Node->child_begin(), E = Node->child_end(); I != E; ++I) |
| 113 | if (*I) |
| 114 | Visit(*I); |
| 115 | } |
Argyrios Kyrtzidis | b116884 | 2009-09-29 21:26:53 +0000 | [diff] [blame] | 116 | |
| 117 | //===--------------------------------------------------------------------===// |
| 118 | // TypeLocVisitor |
| 119 | //===--------------------------------------------------------------------===// |
| 120 | |
| 121 | void Visit(TypeLoc TL) { |
| 122 | for (; TL; TL = TL.getNextTypeLoc()) |
| 123 | BaseTypeLocVisitor::Visit(TL); |
| 124 | } |
| 125 | |
John McCall | 51bd803 | 2009-10-18 01:05:36 +0000 | [diff] [blame] | 126 | void VisitArrayLoc(ArrayTypeLoc TL) { |
| 127 | BaseTypeLocVisitor::VisitArrayTypeLoc(TL); |
Argyrios Kyrtzidis | b116884 | 2009-09-29 21:26:53 +0000 | [diff] [blame] | 128 | if (TL.getSizeExpr()) |
| 129 | Visit(TL.getSizeExpr()); |
| 130 | } |
| 131 | |
John McCall | 51bd803 | 2009-10-18 01:05:36 +0000 | [diff] [blame] | 132 | void VisitFunctionTypeLoc(FunctionTypeLoc TL) { |
| 133 | BaseTypeLocVisitor::VisitFunctionTypeLoc(TL); |
Argyrios Kyrtzidis | b116884 | 2009-09-29 21:26:53 +0000 | [diff] [blame] | 134 | for (unsigned i = 0; i != TL.getNumArgs(); ++i) |
| 135 | Visit(TL.getArg(i)); |
| 136 | } |
| 137 | |
Argyrios Kyrtzidis | 81e8456 | 2009-07-29 23:40:39 +0000 | [diff] [blame] | 138 | }; |
| 139 | |
| 140 | } // namespace idx |
| 141 | |
| 142 | } // namespace clang |
| 143 | |
| 144 | #endif |