blob: 11089f044dcfe07f671fe03d509214574bf9f830 [file] [log] [blame]
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +00001//===--- 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
20namespace clang {
21
22namespace idx {
23
24/// \brief Traverses the full AST, both Decls and Stmts.
25template<typename ImplClass>
26class ASTVisitor : public DeclVisitor<ImplClass>,
27 public StmtVisitor<ImplClass> {
28public:
29 ASTVisitor() : CurrentDecl(0) { }
30
31 Decl *CurrentDecl;
32
33 typedef ASTVisitor<ImplClass> Base;
34 typedef DeclVisitor<ImplClass> BaseDeclVisitor;
35 typedef StmtVisitor<ImplClass> BaseStmtVisitor;
36
37 using BaseStmtVisitor::Visit;
38
39 //===--------------------------------------------------------------------===//
40 // DeclVisitor
41 //===--------------------------------------------------------------------===//
42
43 void Visit(Decl *D) {
44 Decl *PrevDecl = CurrentDecl;
45 CurrentDecl = D;
46 BaseDeclVisitor::Visit(D);
47 CurrentDecl = PrevDecl;
48 }
49
50 void VisitFunctionDecl(FunctionDecl *D) {
51 BaseDeclVisitor::VisitValueDecl(D);
52 if (D->isThisDeclarationADefinition())
53 Visit(D->getBody());
54 }
55
56 void VisitObjCMethodDecl(ObjCMethodDecl *D) {
57 BaseDeclVisitor::VisitNamedDecl(D);
58 if (D->getBody())
59 Visit(D->getBody());
60 }
61
62 void VisitBlockDecl(BlockDecl *D) {
63 BaseDeclVisitor::VisitDecl(D);
64 Visit(D->getBody());
65 }
66
67 void VisitVarDecl(VarDecl *D) {
68 BaseDeclVisitor::VisitValueDecl(D);
69 if (Expr *Init = D->getInit())
70 Visit(Init);
71 }
72
73 void VisitDecl(Decl *D) {
74 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D))
75 return;
76
77 if (DeclContext *DC = dyn_cast<DeclContext>(D))
78 static_cast<ImplClass*>(this)->VisitDeclContext(DC);
79 }
80
81 void VisitDeclContext(DeclContext *DC) {
82 for (DeclContext::decl_iterator
83 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
84 Visit(*I);
85 }
86
87 //===--------------------------------------------------------------------===//
88 // StmtVisitor
89 //===--------------------------------------------------------------------===//
90
91 void VisitDeclStmt(DeclStmt *Node) {
92 for (DeclStmt::decl_iterator
93 I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I)
94 Visit(*I);
95 }
96
Argyrios Kyrtzidisad6e5d12009-07-29 23:40:48 +000097 void VisitBlockExpr(BlockExpr *Node) {
98 Visit(Node->getBlockDecl());
99 }
100
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +0000101 void VisitStmt(Stmt *Node) {
102 for (Stmt::child_iterator
103 I = Node->child_begin(), E = Node->child_end(); I != E; ++I)
104 if (*I)
105 Visit(*I);
106 }
107};
108
109} // namespace idx
110
111} // namespace clang
112
113#endif