]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/lib/Index/ASTVisitor.h
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / llvm / tools / clang / lib / Index / ASTVisitor.h
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:
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