1 //===- CursorVisitor.h - CursorVisitor interface ----------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
10 #define LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
13 #include "CXTranslationUnit.h"
14 #include "Index_Internal.h"
15 #include "clang/AST/DeclVisitor.h"
16 #include "clang/AST/TypeLocVisitor.h"
19 class PreprocessingRecord
;
35 OverloadExprPartsKind
,
38 ExplicitTemplateArgsVisitKind
,
39 NestedNameSpecifierLocVisitKind
,
40 DeclarationNameInfoVisitKind
,
42 SizeOfPackExprPartsKind
,
44 ConceptSpecializationExprVisitKind
,
45 RequiresExprVisitKind
,
53 VisitorJob(CXCursor C
, Kind k
, const void *d1
, const void *d2
= nullptr,
54 const void *d3
= nullptr)
62 Kind
getKind() const { return K
; }
63 const CXCursor
&getParent() const { return parent
; }
66 typedef SmallVector
<VisitorJob
, 10> VisitorWorkList
;
69 class CursorVisitor
: public DeclVisitor
<CursorVisitor
, bool>,
70 public TypeLocVisitor
<CursorVisitor
, bool> {
72 /// Callback called after child nodes of a cursor have been visited.
73 /// Return true to break visitation or false to continue.
74 typedef bool (*PostChildrenVisitorTy
)(CXCursor cursor
,
75 CXClientData client_data
);
78 /// The translation unit we are traversing.
82 /// The parent cursor whose children we are traversing.
85 /// The declaration that serves at the parent of any statement or
87 const Decl
*StmtParent
;
89 /// The visitor function.
90 CXCursorVisitor Visitor
;
92 PostChildrenVisitorTy PostChildrenVisitor
;
94 /// The opaque client data, to be passed along to the visitor.
95 CXClientData ClientData
;
97 /// Whether we should visit the preprocessing record entries last,
98 /// after visiting other declarations.
99 bool VisitPreprocessorLast
;
101 /// Whether we should visit declarations or preprocessing record
102 /// entries that are #included inside the \arg RegionOfInterest.
103 bool VisitIncludedEntities
;
105 /// When valid, a source range to which the cursor should restrict
107 SourceRange RegionOfInterest
;
109 /// Whether we should only visit declarations and not preprocessing
113 // FIXME: Eventually remove. This part of a hack to support proper
114 // iteration over all Decls contained lexically within an ObjC container.
115 DeclContext::decl_iterator
*DI_current
;
116 DeclContext::decl_iterator DE_current
;
117 SmallVectorImpl
<Decl
*>::iterator
*FileDI_current
;
118 SmallVectorImpl
<Decl
*>::iterator FileDE_current
;
120 // Cache of pre-allocated worklists for data-recursion walk of Stmts.
121 SmallVector
<VisitorWorkList
*, 5> WorkListFreeList
;
122 SmallVector
<VisitorWorkList
*, 5> WorkListCache
;
124 using DeclVisitor
<CursorVisitor
, bool>::Visit
;
125 using TypeLocVisitor
<CursorVisitor
, bool>::Visit
;
127 /// Determine whether this particular source range comes before, comes
128 /// after, or overlaps the region of interest.
130 /// \param R a half-open source range retrieved from the abstract syntax tree.
131 RangeComparisonResult
CompareRegionOfInterest(SourceRange R
);
133 bool visitDeclsFromFileRegion(FileID File
, unsigned Offset
, unsigned Length
);
135 class SetParentRAII
{
137 const Decl
*&StmtParent
;
141 SetParentRAII(CXCursor
&Parent
, const Decl
*&StmtParent
, CXCursor NewParent
)
142 : Parent(Parent
), StmtParent(StmtParent
), OldParent(Parent
) {
144 if (clang_isDeclaration(Parent
.kind
))
145 StmtParent
= getCursorDecl(Parent
);
150 if (clang_isDeclaration(Parent
.kind
))
151 StmtParent
= getCursorDecl(Parent
);
156 CursorVisitor(CXTranslationUnit TU
, CXCursorVisitor Visitor
,
157 CXClientData ClientData
, bool VisitPreprocessorLast
,
158 bool VisitIncludedPreprocessingEntries
= false,
159 SourceRange RegionOfInterest
= SourceRange(),
160 bool VisitDeclsOnly
= false,
161 PostChildrenVisitorTy PostChildrenVisitor
= nullptr)
162 : TU(TU
), AU(cxtu::getASTUnit(TU
)), Visitor(Visitor
),
163 PostChildrenVisitor(PostChildrenVisitor
), ClientData(ClientData
),
164 VisitPreprocessorLast(VisitPreprocessorLast
),
165 VisitIncludedEntities(VisitIncludedPreprocessingEntries
),
166 RegionOfInterest(RegionOfInterest
), VisitDeclsOnly(VisitDeclsOnly
),
167 DI_current(nullptr), FileDI_current(nullptr) {
168 Parent
.kind
= CXCursor_NoDeclFound
;
169 Parent
.data
[0] = nullptr;
170 Parent
.data
[1] = nullptr;
171 Parent
.data
[2] = nullptr;
172 StmtParent
= nullptr;
176 // Free the pre-allocated worklists for data-recursion.
177 for (SmallVectorImpl
<VisitorWorkList
*>::iterator I
= WorkListCache
.begin(),
178 E
= WorkListCache
.end();
184 ASTUnit
*getASTUnit() const { return AU
; }
185 CXTranslationUnit
getTU() const { return TU
; }
187 bool Visit(CXCursor Cursor
, bool CheckedRegionOfInterest
= false);
189 /// Visit declarations and preprocessed entities for the file region
190 /// designated by \see RegionOfInterest.
191 bool visitFileRegion();
193 bool visitPreprocessedEntitiesInRegion();
195 bool shouldVisitIncludedEntities() const { return VisitIncludedEntities
; }
197 template <typename InputIterator
>
198 bool visitPreprocessedEntities(InputIterator First
, InputIterator Last
,
199 PreprocessingRecord
&PPRec
,
200 FileID FID
= FileID());
202 bool VisitChildren(CXCursor Parent
);
204 // Declaration visitors
205 bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl
*D
);
206 bool VisitTypeAliasDecl(TypeAliasDecl
*D
);
207 bool VisitAttributes(Decl
*D
);
208 bool VisitBlockDecl(BlockDecl
*B
);
209 bool VisitCXXRecordDecl(CXXRecordDecl
*D
);
210 Optional
<bool> shouldVisitCursor(CXCursor C
);
211 bool VisitDeclContext(DeclContext
*DC
);
212 bool VisitTranslationUnitDecl(TranslationUnitDecl
*D
);
213 bool VisitTypedefDecl(TypedefDecl
*D
);
214 bool VisitTagDecl(TagDecl
*D
);
215 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl
*D
);
216 bool VisitClassTemplatePartialSpecializationDecl(
217 ClassTemplatePartialSpecializationDecl
*D
);
218 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl
*D
);
219 bool VisitEnumConstantDecl(EnumConstantDecl
*D
);
220 bool VisitDeclaratorDecl(DeclaratorDecl
*DD
);
221 bool VisitFunctionDecl(FunctionDecl
*ND
);
222 bool VisitFieldDecl(FieldDecl
*D
);
223 bool VisitVarDecl(VarDecl
*);
224 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl
*D
);
225 bool VisitFunctionTemplateDecl(FunctionTemplateDecl
*D
);
226 bool VisitClassTemplateDecl(ClassTemplateDecl
*D
);
227 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl
*D
);
228 bool VisitObjCTypeParamDecl(ObjCTypeParamDecl
*D
);
229 bool VisitObjCMethodDecl(ObjCMethodDecl
*ND
);
230 bool VisitObjCContainerDecl(ObjCContainerDecl
*D
);
231 bool VisitObjCCategoryDecl(ObjCCategoryDecl
*ND
);
232 bool VisitObjCProtocolDecl(ObjCProtocolDecl
*PID
);
233 bool VisitObjCPropertyDecl(ObjCPropertyDecl
*PD
);
234 bool VisitObjCTypeParamList(ObjCTypeParamList
*typeParamList
);
235 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl
*D
);
236 bool VisitObjCImplDecl(ObjCImplDecl
*D
);
237 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl
*D
);
238 bool VisitObjCImplementationDecl(ObjCImplementationDecl
*D
);
239 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
240 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl
*PD
);
241 bool VisitLinkageSpecDecl(LinkageSpecDecl
*D
);
242 bool VisitNamespaceDecl(NamespaceDecl
*D
);
243 bool VisitNamespaceAliasDecl(NamespaceAliasDecl
*D
);
244 bool VisitUsingDirectiveDecl(UsingDirectiveDecl
*D
);
245 bool VisitUsingDecl(UsingDecl
*D
);
246 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl
*D
);
247 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl
*D
);
248 bool VisitStaticAssertDecl(StaticAssertDecl
*D
);
249 bool VisitFriendDecl(FriendDecl
*D
);
250 bool VisitDecompositionDecl(DecompositionDecl
*D
);
251 bool VisitConceptDecl(ConceptDecl
*D
);
252 bool VisitTypeConstraint(const TypeConstraint
&TC
);
253 bool VisitConceptRequirement(const concepts::Requirement
&R
);
256 bool VisitDeclarationNameInfo(DeclarationNameInfo Name
);
257 bool VisitNestedNameSpecifier(NestedNameSpecifier
*NNS
, SourceRange Range
);
258 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS
);
261 bool VisitTemplateParameters(const TemplateParameterList
*Params
);
262 bool VisitTemplateName(TemplateName Name
, SourceLocation Loc
);
263 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc
&TAL
);
266 #define ABSTRACT_TYPELOC(CLASS, PARENT)
267 #define TYPELOC(CLASS, PARENT) bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
268 #include "clang/AST/TypeLocNodes.def"
270 bool VisitTagTypeLoc(TagTypeLoc TL
);
271 bool VisitArrayTypeLoc(ArrayTypeLoc TL
);
272 bool VisitFunctionTypeLoc(FunctionTypeLoc TL
, bool SkipResultType
= false);
274 // Data-recursive visitor functions.
275 bool IsInRegionOfInterest(CXCursor C
);
276 bool RunVisitorWorkList(VisitorWorkList
&WL
);
277 void EnqueueWorkList(VisitorWorkList
&WL
, const Stmt
*S
);
278 LLVM_ATTRIBUTE_NOINLINE
bool Visit(const Stmt
*S
);
281 Optional
<bool> handleDeclForVisitation(const Decl
*D
);
284 } // namespace cxcursor