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