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