blob: 88b70a490eb73a51478452257deac5309643ae46 [file] [log] [blame]
Argyrios Kyrtzidise397bf12011-11-03 19:02:34 +00001//===- CursorVisitor.h - CursorVisitor interface --------------------------===//
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#ifndef LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
11#define LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
12
13#include "Index_Internal.h"
14#include "CXCursor.h"
15#include "CXTranslationUnit.h"
16
17#include "clang/AST/DeclVisitor.h"
18#include "clang/AST/TypeLocVisitor.h"
19
20namespace clang {
21 class PreprocessingRecord;
22 class ASTUnit;
23
24namespace cxcursor {
25
26class VisitorJob {
27public:
28 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
29 TypeLocVisitKind, OverloadExprPartsKind,
30 DeclRefExprPartsKind, LabelRefVisitKind,
31 ExplicitTemplateArgsVisitKind,
32 NestedNameSpecifierLocVisitKind,
33 DeclarationNameInfoVisitKind,
Douglas Gregor011d8b92012-02-15 00:54:55 +000034 MemberRefVisitKind, SizeOfPackExprPartsKind,
35 LambdaExprPartsKind };
Argyrios Kyrtzidise397bf12011-11-03 19:02:34 +000036protected:
37 void *data[3];
38 CXCursor parent;
39 Kind K;
40 VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
41 : parent(C), K(k) {
42 data[0] = d1;
43 data[1] = d2;
44 data[2] = d3;
45 }
46public:
47 Kind getKind() const { return K; }
48 const CXCursor &getParent() const { return parent; }
49 static bool classof(VisitorJob *VJ) { return true; }
50};
51
52typedef SmallVector<VisitorJob, 10> VisitorWorkList;
53
54// Cursor visitor.
55class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
56 public TypeLocVisitor<CursorVisitor, bool>
57{
58 /// \brief The translation unit we are traversing.
59 CXTranslationUnit TU;
60 ASTUnit *AU;
61
62 /// \brief The parent cursor whose children we are traversing.
63 CXCursor Parent;
64
65 /// \brief The declaration that serves at the parent of any statement or
66 /// expression nodes.
67 Decl *StmtParent;
68
69 /// \brief The visitor function.
70 CXCursorVisitor Visitor;
71
72 /// \brief The opaque client data, to be passed along to the visitor.
73 CXClientData ClientData;
74
75 /// \brief Whether we should visit the preprocessing record entries last,
76 /// after visiting other declarations.
77 bool VisitPreprocessorLast;
78
79 /// \brief Whether we should visit declarations or preprocessing record
80 /// entries that are #included inside the \arg RegionOfInterest.
81 bool VisitIncludedEntities;
82
83 /// \brief When valid, a source range to which the cursor should restrict
84 /// its search.
85 SourceRange RegionOfInterest;
86
Argyrios Kyrtzidisb49e7282011-11-29 03:14:11 +000087 /// \brief Whether we should only visit declarations and not preprocessing
88 /// record entries.
89 bool VisitDeclsOnly;
90
Argyrios Kyrtzidise397bf12011-11-03 19:02:34 +000091 // FIXME: Eventually remove. This part of a hack to support proper
92 // iteration over all Decls contained lexically within an ObjC container.
93 DeclContext::decl_iterator *DI_current;
94 DeclContext::decl_iterator DE_current;
Argyrios Kyrtzidis03ee2dd2011-11-16 08:58:57 +000095 SmallVectorImpl<Decl *>::iterator *FileDI_current;
96 SmallVectorImpl<Decl *>::iterator FileDE_current;
Argyrios Kyrtzidise397bf12011-11-03 19:02:34 +000097
98 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
99 SmallVector<VisitorWorkList*, 5> WorkListFreeList;
100 SmallVector<VisitorWorkList*, 5> WorkListCache;
101
102 using DeclVisitor<CursorVisitor, bool>::Visit;
103 using TypeLocVisitor<CursorVisitor, bool>::Visit;
104
105 /// \brief Determine whether this particular source range comes before, comes
106 /// after, or overlaps the region of interest.
107 ///
108 /// \param R a half-open source range retrieved from the abstract syntax tree.
109 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
110
111 void visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
112
113 class SetParentRAII {
114 CXCursor &Parent;
115 Decl *&StmtParent;
116 CXCursor OldParent;
117
118 public:
119 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
120 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
121 {
122 Parent = NewParent;
123 if (clang_isDeclaration(Parent.kind))
124 StmtParent = getCursorDecl(Parent);
125 }
126
127 ~SetParentRAII() {
128 Parent = OldParent;
129 if (clang_isDeclaration(Parent.kind))
130 StmtParent = getCursorDecl(Parent);
131 }
132 };
133
134public:
135 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
136 CXClientData ClientData,
137 bool VisitPreprocessorLast,
138 bool VisitIncludedPreprocessingEntries = false,
Argyrios Kyrtzidisb49e7282011-11-29 03:14:11 +0000139 SourceRange RegionOfInterest = SourceRange(),
140 bool VisitDeclsOnly = false)
Argyrios Kyrtzidise397bf12011-11-03 19:02:34 +0000141 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
142 Visitor(Visitor), ClientData(ClientData),
143 VisitPreprocessorLast(VisitPreprocessorLast),
144 VisitIncludedEntities(VisitIncludedPreprocessingEntries),
Argyrios Kyrtzidisb49e7282011-11-29 03:14:11 +0000145 RegionOfInterest(RegionOfInterest),
146 VisitDeclsOnly(VisitDeclsOnly),
147 DI_current(0), FileDI_current(0)
Argyrios Kyrtzidise397bf12011-11-03 19:02:34 +0000148 {
149 Parent.kind = CXCursor_NoDeclFound;
150 Parent.data[0] = 0;
151 Parent.data[1] = 0;
152 Parent.data[2] = 0;
153 StmtParent = 0;
154 }
155
156 ~CursorVisitor() {
157 // Free the pre-allocated worklists for data-recursion.
158 for (SmallVectorImpl<VisitorWorkList*>::iterator
159 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
160 delete *I;
161 }
162 }
163
164 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
165 CXTranslationUnit getTU() const { return TU; }
166
167 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
168
169 /// \brief Visit declarations and preprocessed entities for the file region
170 /// designated by \see RegionOfInterest.
171 void visitFileRegion();
172
173 bool visitPreprocessedEntitiesInRegion();
174
175 bool shouldVisitIncludedEntities() const {
176 return VisitIncludedEntities;
177 }
178
179 template<typename InputIterator>
180 bool visitPreprocessedEntities(InputIterator First, InputIterator Last,
181 PreprocessingRecord &PPRec,
182 FileID FID = FileID());
183
184 bool VisitChildren(CXCursor Parent);
185
186 // Declaration visitors
187 bool VisitTypeAliasDecl(TypeAliasDecl *D);
188 bool VisitAttributes(Decl *D);
189 bool VisitBlockDecl(BlockDecl *B);
190 bool VisitCXXRecordDecl(CXXRecordDecl *D);
191 llvm::Optional<bool> shouldVisitCursor(CXCursor C);
192 bool VisitDeclContext(DeclContext *DC);
193 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
194 bool VisitTypedefDecl(TypedefDecl *D);
195 bool VisitTagDecl(TagDecl *D);
196 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
197 bool VisitClassTemplatePartialSpecializationDecl(
198 ClassTemplatePartialSpecializationDecl *D);
199 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
200 bool VisitEnumConstantDecl(EnumConstantDecl *D);
201 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
202 bool VisitFunctionDecl(FunctionDecl *ND);
203 bool VisitFieldDecl(FieldDecl *D);
204 bool VisitVarDecl(VarDecl *);
205 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
206 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
207 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
208 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
209 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
210 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
211 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
212 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
213 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
214 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
215 bool VisitObjCImplDecl(ObjCImplDecl *D);
216 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
217 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
218 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
Argyrios Kyrtzidise397bf12011-11-03 19:02:34 +0000219 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
220 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
221 bool VisitNamespaceDecl(NamespaceDecl *D);
222 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
223 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
224 bool VisitUsingDecl(UsingDecl *D);
225 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
226 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
227
228 // Name visitor
229 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
230 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
231 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
232
233 // Template visitors
234 bool VisitTemplateParameters(const TemplateParameterList *Params);
235 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
236 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
237
238 // Type visitors
239#define ABSTRACT_TYPELOC(CLASS, PARENT)
240#define TYPELOC(CLASS, PARENT) \
241 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
242#include "clang/AST/TypeLocNodes.def"
243
244 bool VisitTagTypeLoc(TagTypeLoc TL);
245 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
246 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
247
248 // Data-recursive visitor functions.
249 bool IsInRegionOfInterest(CXCursor C);
250 bool RunVisitorWorkList(VisitorWorkList &WL);
251 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
252 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
253};
254
255}
256}
257
258#endif
259