blob: 0b8425b2f337e915a87d9f6aedd1c8fb15953297 [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"
Argyrios Kyrtzidis0c411802009-09-29 21:27:32 +000019#include "clang/AST/TypeLocVisitor.h"
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +000020
21namespace clang {
22
23namespace idx {
24
25/// \brief Traverses the full AST, both Decls and Stmts.
26template<typename ImplClass>
27class ASTVisitor : public DeclVisitor<ImplClass>,
Argyrios Kyrtzidisb1168842009-09-29 21:26:53 +000028 public StmtVisitor<ImplClass>,
29 public TypeLocVisitor<ImplClass> {
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +000030public:
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 Kyrtzidisb1168842009-09-29 21:26:53 +000038 typedef TypeLocVisitor<ImplClass> BaseTypeLocVisitor;
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +000039
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 Kyrtzidisb1168842009-09-29 21:26:53 +000052
53 void VisitDeclaratorDecl(DeclaratorDecl *D) {
54 BaseDeclVisitor::VisitDeclaratorDecl(D);
John McCalla93c9342009-12-07 02:54:59 +000055 if (TypeSourceInfo *TInfo = D->getTypeSourceInfo())
56 Visit(TInfo->getTypeLoc());
Argyrios Kyrtzidisb1168842009-09-29 21:26:53 +000057 }
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +000058
59 void VisitFunctionDecl(FunctionDecl *D) {
Argyrios Kyrtzidis09d8a952009-09-29 21:26:35 +000060 BaseDeclVisitor::VisitFunctionDecl(D);
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +000061 if (D->isThisDeclarationADefinition())
62 Visit(D->getBody());
63 }
64
65 void VisitObjCMethodDecl(ObjCMethodDecl *D) {
Argyrios Kyrtzidis09d8a952009-09-29 21:26:35 +000066 BaseDeclVisitor::VisitObjCMethodDecl(D);
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +000067 if (D->getBody())
68 Visit(D->getBody());
69 }
70
71 void VisitBlockDecl(BlockDecl *D) {
Argyrios Kyrtzidis09d8a952009-09-29 21:26:35 +000072 BaseDeclVisitor::VisitBlockDecl(D);
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +000073 Visit(D->getBody());
74 }
75
76 void VisitVarDecl(VarDecl *D) {
Argyrios Kyrtzidis09d8a952009-09-29 21:26:35 +000077 BaseDeclVisitor::VisitVarDecl(D);
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +000078 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 Kyrtzidisad6e5d12009-07-29 23:40:48 +0000106 void VisitBlockExpr(BlockExpr *Node) {
Ted Kremenek3cdff232009-12-07 22:01:30 +0000107 // The BlockDecl is also visited by 'VisitDeclContext()'. No need to visit it twice.
Argyrios Kyrtzidisad6e5d12009-07-29 23:40:48 +0000108 }
109
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +0000110 void VisitStmt(Stmt *Node) {
John McCall7502c1d2011-02-13 04:07:26 +0000111 for (Stmt::child_range I = Node->children(); I; ++I)
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +0000112 if (*I)
113 Visit(*I);
114 }
Argyrios Kyrtzidisb1168842009-09-29 21:26:53 +0000115
116 //===--------------------------------------------------------------------===//
117 // TypeLocVisitor
118 //===--------------------------------------------------------------------===//
119
120 void Visit(TypeLoc TL) {
121 for (; TL; TL = TL.getNextTypeLoc())
122 BaseTypeLocVisitor::Visit(TL);
123 }
124
John McCall51bd8032009-10-18 01:05:36 +0000125 void VisitArrayLoc(ArrayTypeLoc TL) {
126 BaseTypeLocVisitor::VisitArrayTypeLoc(TL);
Argyrios Kyrtzidisb1168842009-09-29 21:26:53 +0000127 if (TL.getSizeExpr())
128 Visit(TL.getSizeExpr());
129 }
130
John McCall51bd8032009-10-18 01:05:36 +0000131 void VisitFunctionTypeLoc(FunctionTypeLoc TL) {
132 BaseTypeLocVisitor::VisitFunctionTypeLoc(TL);
Argyrios Kyrtzidisb1168842009-09-29 21:26:53 +0000133 for (unsigned i = 0; i != TL.getNumArgs(); ++i)
134 Visit(TL.getArg(i));
135 }
136
Argyrios Kyrtzidis81e84562009-07-29 23:40:39 +0000137};
138
139} // namespace idx
140
141} // namespace clang
142
143#endif