1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #ifndef LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H |
10 | #define LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H |
11 | |
12 | #include "CXCursor.h" |
13 | #include "CXTranslationUnit.h" |
14 | #include "Index_Internal.h" |
15 | #include "clang/AST/DeclVisitor.h" |
16 | #include "clang/AST/TypeLocVisitor.h" |
17 | |
18 | namespace clang { |
19 | class PreprocessingRecord; |
20 | class ASTUnit; |
21 | |
22 | namespace cxcursor { |
23 | |
24 | class VisitorJob { |
25 | public: |
26 | enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind, |
27 | TypeLocVisitKind, OverloadExprPartsKind, |
28 | DeclRefExprPartsKind, LabelRefVisitKind, |
29 | ExplicitTemplateArgsVisitKind, |
30 | NestedNameSpecifierLocVisitKind, |
31 | DeclarationNameInfoVisitKind, |
32 | MemberRefVisitKind, SizeOfPackExprPartsKind, |
33 | LambdaExprPartsKind, PostChildrenVisitKind }; |
34 | protected: |
35 | const void *data[3]; |
36 | CXCursor parent; |
37 | Kind K; |
38 | VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = nullptr, |
39 | const void *d3 = nullptr) |
40 | : parent(C), K(k) { |
41 | data[0] = d1; |
42 | data[1] = d2; |
43 | data[2] = d3; |
44 | } |
45 | public: |
46 | Kind getKind() const { return K; } |
47 | const CXCursor &getParent() const { return parent; } |
48 | }; |
49 | |
50 | typedef SmallVector<VisitorJob, 10> VisitorWorkList; |
51 | |
52 | |
53 | class CursorVisitor : public DeclVisitor<CursorVisitor, bool>, |
54 | public TypeLocVisitor<CursorVisitor, bool> |
55 | { |
56 | public: |
57 | |
58 | |
59 | typedef bool (*PostChildrenVisitorTy)(CXCursor cursor, |
60 | CXClientData client_data); |
61 | |
62 | private: |
63 | |
64 | CXTranslationUnit TU; |
65 | ASTUnit *AU; |
66 | |
67 | |
68 | CXCursor Parent; |
69 | |
70 | |
71 | |
72 | const Decl *StmtParent; |
73 | |
74 | |
75 | CXCursorVisitor Visitor; |
76 | |
77 | PostChildrenVisitorTy PostChildrenVisitor; |
78 | |
79 | |
80 | CXClientData ClientData; |
81 | |
82 | |
83 | |
84 | bool VisitPreprocessorLast; |
85 | |
86 | |
87 | |
88 | bool VisitIncludedEntities; |
89 | |
90 | |
91 | |
92 | SourceRange RegionOfInterest; |
93 | |
94 | |
95 | |
96 | bool VisitDeclsOnly; |
97 | |
98 | |
99 | |
100 | DeclContext::decl_iterator *DI_current; |
101 | DeclContext::decl_iterator DE_current; |
102 | SmallVectorImpl<Decl *>::iterator *FileDI_current; |
103 | SmallVectorImpl<Decl *>::iterator FileDE_current; |
104 | |
105 | |
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 | |
113 | |
114 | |
115 | |
116 | RangeComparisonResult CompareRegionOfInterest(SourceRange R); |
117 | |
118 | bool visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length); |
119 | |
120 | class SetParentRAII { |
121 | CXCursor &Parent; |
122 | const Decl *&StmtParent; |
123 | CXCursor OldParent; |
124 | |
125 | public: |
126 | SetParentRAII(CXCursor &Parent, const Decl *&StmtParent, |
127 | CXCursor NewParent) |
128 | : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) |
129 | { |
130 | Parent = NewParent; |
131 | if (clang_isDeclaration(Parent.kind)) |
132 | StmtParent = getCursorDecl(Parent); |
133 | } |
134 | |
135 | ~SetParentRAII() { |
136 | Parent = OldParent; |
137 | if (clang_isDeclaration(Parent.kind)) |
138 | StmtParent = getCursorDecl(Parent); |
139 | } |
140 | }; |
141 | |
142 | public: |
143 | CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor, |
144 | CXClientData ClientData, |
145 | bool VisitPreprocessorLast, |
146 | bool VisitIncludedPreprocessingEntries = false, |
147 | SourceRange RegionOfInterest = SourceRange(), |
148 | bool VisitDeclsOnly = false, |
149 | PostChildrenVisitorTy PostChildrenVisitor = nullptr) |
150 | : TU(TU), AU(cxtu::getASTUnit(TU)), |
151 | Visitor(Visitor), PostChildrenVisitor(PostChildrenVisitor), |
152 | ClientData(ClientData), |
153 | VisitPreprocessorLast(VisitPreprocessorLast), |
154 | VisitIncludedEntities(VisitIncludedPreprocessingEntries), |
155 | RegionOfInterest(RegionOfInterest), |
156 | VisitDeclsOnly(VisitDeclsOnly), |
157 | DI_current(nullptr), FileDI_current(nullptr) |
158 | { |
159 | Parent.kind = CXCursor_NoDeclFound; |
160 | Parent.data[0] = nullptr; |
161 | Parent.data[1] = nullptr; |
162 | Parent.data[2] = nullptr; |
163 | StmtParent = nullptr; |
164 | } |
165 | |
166 | ~CursorVisitor() { |
167 | |
168 | for (SmallVectorImpl<VisitorWorkList*>::iterator |
169 | I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) { |
170 | delete *I; |
171 | } |
172 | } |
173 | |
174 | ASTUnit *getASTUnit() const { return AU; } |
175 | CXTranslationUnit getTU() const { return TU; } |
176 | |
177 | bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false); |
178 | |
179 | |
180 | |
181 | bool visitFileRegion(); |
182 | |
183 | bool visitPreprocessedEntitiesInRegion(); |
184 | |
185 | bool shouldVisitIncludedEntities() const { |
186 | return VisitIncludedEntities; |
187 | } |
188 | |
189 | template<typename InputIterator> |
190 | bool visitPreprocessedEntities(InputIterator First, InputIterator Last, |
191 | PreprocessingRecord &PPRec, |
192 | FileID FID = FileID()); |
193 | |
194 | bool VisitChildren(CXCursor Parent); |
195 | |
196 | |
197 | bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); |
198 | bool VisitTypeAliasDecl(TypeAliasDecl *D); |
199 | bool VisitAttributes(Decl *D); |
200 | bool VisitBlockDecl(BlockDecl *B); |
201 | bool VisitCXXRecordDecl(CXXRecordDecl *D); |
202 | Optional<bool> shouldVisitCursor(CXCursor C); |
203 | bool VisitDeclContext(DeclContext *DC); |
204 | bool VisitTranslationUnitDecl(TranslationUnitDecl *D); |
205 | bool VisitTypedefDecl(TypedefDecl *D); |
206 | bool VisitTagDecl(TagDecl *D); |
207 | bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D); |
208 | bool VisitClassTemplatePartialSpecializationDecl( |
209 | ClassTemplatePartialSpecializationDecl *D); |
210 | bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); |
211 | bool VisitEnumConstantDecl(EnumConstantDecl *D); |
212 | bool VisitDeclaratorDecl(DeclaratorDecl *DD); |
213 | bool VisitFunctionDecl(FunctionDecl *ND); |
214 | bool VisitFieldDecl(FieldDecl *D); |
215 | bool VisitVarDecl(VarDecl *); |
216 | bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); |
217 | bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D); |
218 | bool VisitClassTemplateDecl(ClassTemplateDecl *D); |
219 | bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); |
220 | bool VisitObjCTypeParamDecl(ObjCTypeParamDecl *D); |
221 | bool VisitObjCMethodDecl(ObjCMethodDecl *ND); |
222 | bool VisitObjCContainerDecl(ObjCContainerDecl *D); |
223 | bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); |
224 | bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); |
225 | bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD); |
226 | bool VisitObjCTypeParamList(ObjCTypeParamList *typeParamList); |
227 | bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); |
228 | bool VisitObjCImplDecl(ObjCImplDecl *D); |
229 | bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); |
230 | bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); |
231 | |
232 | bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD); |
233 | bool VisitLinkageSpecDecl(LinkageSpecDecl *D); |
234 | bool VisitNamespaceDecl(NamespaceDecl *D); |
235 | bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D); |
236 | bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D); |
237 | bool VisitUsingDecl(UsingDecl *D); |
238 | bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); |
239 | bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); |
240 | bool VisitStaticAssertDecl(StaticAssertDecl *D); |
241 | bool VisitFriendDecl(FriendDecl *D); |
242 | |
243 | |
244 | bool VisitDeclarationNameInfo(DeclarationNameInfo Name); |
245 | bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range); |
246 | bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); |
247 | |
248 | |
249 | bool VisitTemplateParameters(const TemplateParameterList *Params); |
250 | bool VisitTemplateName(TemplateName Name, SourceLocation Loc); |
251 | bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL); |
252 | |
253 | |
254 | #define ABSTRACT_TYPELOC(CLASS, PARENT) |
255 | #define TYPELOC(CLASS, PARENT) \ |
256 | bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); |
257 | #include "clang/AST/TypeLocNodes.def" |
258 | |
259 | bool VisitTagTypeLoc(TagTypeLoc TL); |
260 | bool VisitArrayTypeLoc(ArrayTypeLoc TL); |
261 | bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); |
262 | |
263 | |
264 | bool IsInRegionOfInterest(CXCursor C); |
265 | bool RunVisitorWorkList(VisitorWorkList &WL); |
266 | void EnqueueWorkList(VisitorWorkList &WL, const Stmt *S); |
267 | LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S); |
268 | |
269 | private: |
270 | Optional<bool> handleDeclForVisitation(const Decl *D); |
271 | }; |
272 | |
273 | } |
274 | } |
275 | |
276 | #endif |
277 | |
278 | |