1 //===- CursorVisitor.h - CursorVisitor interface ----------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
11 #define LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
14 #include "CXTranslationUnit.h"
15 #include "Index_Internal.h"
16 #include "clang/AST/DeclVisitor.h"
17 #include "clang/AST/TypeLocVisitor.h"
20 class PreprocessingRecord;
27 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
28 TypeLocVisitKind, OverloadExprPartsKind,
29 DeclRefExprPartsKind, LabelRefVisitKind,
30 ExplicitTemplateArgsVisitKind,
31 NestedNameSpecifierLocVisitKind,
32 DeclarationNameInfoVisitKind,
33 MemberRefVisitKind, SizeOfPackExprPartsKind,
34 LambdaExprPartsKind, PostChildrenVisitKind };
39 VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = nullptr,
40 const void *d3 = nullptr)
47 Kind getKind() const { return K; }
48 const CXCursor &getParent() const { return parent; }
51 typedef SmallVector<VisitorJob, 10> VisitorWorkList;
54 class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
55 public TypeLocVisitor<CursorVisitor, bool>
58 /// Callback called after child nodes of a cursor have been visited.
59 /// Return true to break visitation or false to continue.
60 typedef bool (*PostChildrenVisitorTy)(CXCursor cursor,
61 CXClientData client_data);
64 /// The translation unit we are traversing.
68 /// The parent cursor whose children we are traversing.
71 /// The declaration that serves at the parent of any statement or
73 const Decl *StmtParent;
75 /// The visitor function.
76 CXCursorVisitor Visitor;
78 PostChildrenVisitorTy PostChildrenVisitor;
80 /// The opaque client data, to be passed along to the visitor.
81 CXClientData ClientData;
83 /// Whether we should visit the preprocessing record entries last,
84 /// after visiting other declarations.
85 bool VisitPreprocessorLast;
87 /// Whether we should visit declarations or preprocessing record
88 /// entries that are #included inside the \arg RegionOfInterest.
89 bool VisitIncludedEntities;
91 /// When valid, a source range to which the cursor should restrict
93 SourceRange RegionOfInterest;
95 /// Whether we should only visit declarations and not preprocessing
99 // FIXME: Eventually remove. This part of a hack to support proper
100 // iteration over all Decls contained lexically within an ObjC container.
101 DeclContext::decl_iterator *DI_current;
102 DeclContext::decl_iterator DE_current;
103 SmallVectorImpl<Decl *>::iterator *FileDI_current;
104 SmallVectorImpl<Decl *>::iterator FileDE_current;
106 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
107 SmallVector<VisitorWorkList*, 5> WorkListFreeList;
108 SmallVector<VisitorWorkList*, 5> WorkListCache;
110 using DeclVisitor<CursorVisitor, bool>::Visit;
111 using TypeLocVisitor<CursorVisitor, bool>::Visit;
113 /// Determine whether this particular source range comes before, comes
114 /// after, or overlaps the region of interest.
116 /// \param R a half-open source range retrieved from the abstract syntax tree.
117 RangeComparisonResult CompareRegionOfInterest(SourceRange R);
119 bool visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
121 class SetParentRAII {
123 const Decl *&StmtParent;
127 SetParentRAII(CXCursor &Parent, const Decl *&StmtParent,
129 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
132 if (clang_isDeclaration(Parent.kind))
133 StmtParent = getCursorDecl(Parent);
138 if (clang_isDeclaration(Parent.kind))
139 StmtParent = getCursorDecl(Parent);
144 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
145 CXClientData ClientData,
146 bool VisitPreprocessorLast,
147 bool VisitIncludedPreprocessingEntries = false,
148 SourceRange RegionOfInterest = SourceRange(),
149 bool VisitDeclsOnly = false,
150 PostChildrenVisitorTy PostChildrenVisitor = nullptr)
151 : TU(TU), AU(cxtu::getASTUnit(TU)),
152 Visitor(Visitor), PostChildrenVisitor(PostChildrenVisitor),
153 ClientData(ClientData),
154 VisitPreprocessorLast(VisitPreprocessorLast),
155 VisitIncludedEntities(VisitIncludedPreprocessingEntries),
156 RegionOfInterest(RegionOfInterest),
157 VisitDeclsOnly(VisitDeclsOnly),
158 DI_current(nullptr), FileDI_current(nullptr)
160 Parent.kind = CXCursor_NoDeclFound;
161 Parent.data[0] = nullptr;
162 Parent.data[1] = nullptr;
163 Parent.data[2] = nullptr;
164 StmtParent = nullptr;
168 // Free the pre-allocated worklists for data-recursion.
169 for (SmallVectorImpl<VisitorWorkList*>::iterator
170 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
175 ASTUnit *getASTUnit() const { return AU; }
176 CXTranslationUnit getTU() const { return TU; }
178 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
180 /// Visit declarations and preprocessed entities for the file region
181 /// designated by \see RegionOfInterest.
182 bool visitFileRegion();
184 bool visitPreprocessedEntitiesInRegion();
186 bool shouldVisitIncludedEntities() const {
187 return VisitIncludedEntities;
190 template<typename InputIterator>
191 bool visitPreprocessedEntities(InputIterator First, InputIterator Last,
192 PreprocessingRecord &PPRec,
193 FileID FID = FileID());
195 bool VisitChildren(CXCursor Parent);
197 // Declaration visitors
198 bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
199 bool VisitTypeAliasDecl(TypeAliasDecl *D);
200 bool VisitAttributes(Decl *D);
201 bool VisitBlockDecl(BlockDecl *B);
202 bool VisitCXXRecordDecl(CXXRecordDecl *D);
203 Optional<bool> shouldVisitCursor(CXCursor C);
204 bool VisitDeclContext(DeclContext *DC);
205 bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
206 bool VisitTypedefDecl(TypedefDecl *D);
207 bool VisitTagDecl(TagDecl *D);
208 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
209 bool VisitClassTemplatePartialSpecializationDecl(
210 ClassTemplatePartialSpecializationDecl *D);
211 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
212 bool VisitEnumConstantDecl(EnumConstantDecl *D);
213 bool VisitDeclaratorDecl(DeclaratorDecl *DD);
214 bool VisitFunctionDecl(FunctionDecl *ND);
215 bool VisitFieldDecl(FieldDecl *D);
216 bool VisitVarDecl(VarDecl *);
217 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
218 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
219 bool VisitClassTemplateDecl(ClassTemplateDecl *D);
220 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
221 bool VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
222 bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
223 bool VisitObjCContainerDecl(ObjCContainerDecl *D);
224 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
225 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
226 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
227 bool VisitObjCTypeParamList(ObjCTypeParamList *typeParamList);
228 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
229 bool VisitObjCImplDecl(ObjCImplDecl *D);
230 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
231 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
232 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
233 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
234 bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
235 bool VisitNamespaceDecl(NamespaceDecl *D);
236 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
237 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
238 bool VisitUsingDecl(UsingDecl *D);
239 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
240 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
241 bool VisitStaticAssertDecl(StaticAssertDecl *D);
242 bool VisitFriendDecl(FriendDecl *D);
245 bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
246 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
247 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
250 bool VisitTemplateParameters(const TemplateParameterList *Params);
251 bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
252 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
255 #define ABSTRACT_TYPELOC(CLASS, PARENT)
256 #define TYPELOC(CLASS, PARENT) \
257 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
258 #include "clang/AST/TypeLocNodes.def"
260 bool VisitTagTypeLoc(TagTypeLoc TL);
261 bool VisitArrayTypeLoc(ArrayTypeLoc TL);
262 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
264 // Data-recursive visitor functions.
265 bool IsInRegionOfInterest(CXCursor C);
266 bool RunVisitorWorkList(VisitorWorkList &WL);
267 void EnqueueWorkList(VisitorWorkList &WL, const Stmt *S);
268 LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S);
271 Optional<bool> handleDeclForVisitation(const Decl *D);