• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ASTVisitor()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 
Visit(Decl * D)46   void Visit(Decl *D) {
47     Decl *PrevDecl = CurrentDecl;
48     CurrentDecl = D;
49     BaseDeclVisitor::Visit(D);
50     CurrentDecl = PrevDecl;
51   }
52 
VisitDeclaratorDecl(DeclaratorDecl * D)53   void VisitDeclaratorDecl(DeclaratorDecl *D) {
54     BaseDeclVisitor::VisitDeclaratorDecl(D);
55     if (TypeSourceInfo *TInfo = D->getTypeSourceInfo())
56       Visit(TInfo->getTypeLoc());
57   }
58 
VisitFunctionDecl(FunctionDecl * D)59   void VisitFunctionDecl(FunctionDecl *D) {
60     BaseDeclVisitor::VisitFunctionDecl(D);
61     if (D->isThisDeclarationADefinition())
62       Visit(D->getBody());
63   }
64 
VisitObjCMethodDecl(ObjCMethodDecl * D)65   void VisitObjCMethodDecl(ObjCMethodDecl *D) {
66     BaseDeclVisitor::VisitObjCMethodDecl(D);
67     if (D->getBody())
68       Visit(D->getBody());
69   }
70 
VisitBlockDecl(BlockDecl * D)71   void VisitBlockDecl(BlockDecl *D) {
72     BaseDeclVisitor::VisitBlockDecl(D);
73     Visit(D->getBody());
74   }
75 
VisitVarDecl(VarDecl * D)76   void VisitVarDecl(VarDecl *D) {
77     BaseDeclVisitor::VisitVarDecl(D);
78     if (Expr *Init = D->getInit())
79       Visit(Init);
80   }
81 
VisitDecl(Decl * D)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 
VisitDeclContext(DeclContext * DC)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 
VisitDeclStmt(DeclStmt * Node)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 
VisitBlockExpr(BlockExpr * Node)106   void VisitBlockExpr(BlockExpr *Node) {
107     // The BlockDecl is also visited by 'VisitDeclContext()'.  No need to visit it twice.
108   }
109 
VisitStmt(Stmt * Node)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 
Visit(TypeLoc TL)120   void Visit(TypeLoc TL) {
121     for (; TL; TL = TL.getNextTypeLoc())
122       BaseTypeLocVisitor::Visit(TL);
123   }
124 
VisitArrayLoc(ArrayTypeLoc TL)125   void VisitArrayLoc(ArrayTypeLoc TL) {
126     BaseTypeLocVisitor::VisitArrayTypeLoc(TL);
127     if (TL.getSizeExpr())
128       Visit(TL.getSizeExpr());
129   }
130 
VisitFunctionTypeLoc(FunctionTypeLoc TL)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