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