Clang Project

clang_source_code/tools/libclang/CursorVisitor.h
1//===- CursorVisitor.h - CursorVisitor interface ----------------*- C++ -*-===//
2//
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
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
18namespace clang {
19  class PreprocessingRecord;
20  class ASTUnit;
21
22namespace cxcursor {
23
24class VisitorJob {
25public:
26  enum Kind { DeclVisitKindStmtVisitKindMemberExprPartsKind,
27              TypeLocVisitKindOverloadExprPartsKind,
28              DeclRefExprPartsKindLabelRefVisitKind,
29              ExplicitTemplateArgsVisitKind,
30              NestedNameSpecifierLocVisitKind,
31              DeclarationNameInfoVisitKind,
32              MemberRefVisitKindSizeOfPackExprPartsKind,
33              LambdaExprPartsKindPostChildrenVisitKind };
34protected:
35  const void *data[3];
36  CXCursor parent;
37  Kind K;
38  VisitorJob(CXCursor CKind kconst void *d1const 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  }
45public:
46  Kind getKind() const { return K; }
47  const CXCursor &getParent() const { return parent; }
48};
49  
50typedef SmallVector<VisitorJob10VisitorWorkList;
51
52// Cursor visitor.
53class CursorVisitor : public DeclVisitor<CursorVisitorbool>,
54                      public TypeLocVisitor<CursorVisitorbool>
55{
56public:
57  /// Callback called after child nodes of a cursor have been visited.
58  /// Return true to break visitation or false to continue.
59  typedef bool (*PostChildrenVisitorTy)(CXCursor cursor,
60                                        CXClientData client_data);
61
62private:
63  /// The translation unit we are traversing.
64  CXTranslationUnit TU;
65  ASTUnit *AU;
66
67  /// The parent cursor whose children we are traversing.
68  CXCursor Parent;
69
70  /// The declaration that serves at the parent of any statement or
71  /// expression nodes.
72  const Decl *StmtParent;
73
74  /// The visitor function.
75  CXCursorVisitor Visitor;
76
77  PostChildrenVisitorTy PostChildrenVisitor;
78
79  /// The opaque client data, to be passed along to the visitor.
80  CXClientData ClientData;
81
82  /// Whether we should visit the preprocessing record entries last, 
83  /// after visiting other declarations.
84  bool VisitPreprocessorLast;
85
86  /// Whether we should visit declarations or preprocessing record
87  /// entries that are #included inside the \arg RegionOfInterest.
88  bool VisitIncludedEntities;
89  
90  /// When valid, a source range to which the cursor should restrict
91  /// its search.
92  SourceRange RegionOfInterest;
93
94  /// Whether we should only visit declarations and not preprocessing
95  /// record entries.
96  bool VisitDeclsOnly;
97
98  // FIXME: Eventually remove.  This part of a hack to support proper
99  // iteration over all Decls contained lexically within an ObjC container.
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  // Cache of pre-allocated worklists for data-recursion walk of Stmts.
106  SmallVector<VisitorWorkList*, 5WorkListFreeList;
107  SmallVector<VisitorWorkList*, 5WorkListCache;
108
109  using DeclVisitor<CursorVisitorbool>::Visit;
110  using TypeLocVisitor<CursorVisitorbool>::Visit;
111
112  /// Determine whether this particular source range comes before, comes
113  /// after, or overlaps the region of interest.
114  ///
115  /// \param R a half-open source range retrieved from the abstract syntax tree.
116  RangeComparisonResult CompareRegionOfInterest(SourceRange R);
117
118  bool visitDeclsFromFileRegion(FileID Fileunsigned Offsetunsigned Length);
119
120  class SetParentRAII {
121    CXCursor &Parent;
122    const Decl *&StmtParent;
123    CXCursor OldParent;
124
125  public:
126    SetParentRAII(CXCursor &Parentconst 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
142public:
143  CursorVisitor(CXTranslationUnit TUCXCursorVisitor 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    // Free the pre-allocated worklists for data-recursion.
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 Cursorbool CheckedRegionOfInterest = false);
178
179  /// Visit declarations and preprocessed entities for the file region
180  /// designated by \see RegionOfInterest.
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  // Declaration visitors
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<boolshouldVisitCursor(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  // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
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  // Name visitor
244  bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
245  bool VisitNestedNameSpecifier(NestedNameSpecifier *NNSSourceRange Range);
246  bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
247  
248  // Template visitors
249  bool VisitTemplateParameters(const TemplateParameterList *Params);
250  bool VisitTemplateName(TemplateName NameSourceLocation Loc);
251  bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
252  
253  // Type visitors
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 TLbool SkipResultType = false);
262
263  // Data-recursive visitor functions.
264  bool IsInRegionOfInterest(CXCursor C);
265  bool RunVisitorWorkList(VisitorWorkList &WL);
266  void EnqueueWorkList(VisitorWorkList &WLconst Stmt *S);
267  LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S);
268
269private:
270  Optional<boolhandleDeclForVisitation(const Decl *D);
271};
272
273}
274}
275
276#endif
277
278
clang::cxcursor::VisitorJob::Kind
clang::cxcursor::VisitorJob::data
clang::cxcursor::VisitorJob::parent
clang::cxcursor::VisitorJob::K
clang::cxcursor::VisitorJob::getKind
clang::cxcursor::VisitorJob::getParent
clang::cxcursor::CursorVisitor::TU
clang::cxcursor::CursorVisitor::AU
clang::cxcursor::CursorVisitor::Parent
clang::cxcursor::CursorVisitor::StmtParent
clang::cxcursor::CursorVisitor::Visitor
clang::cxcursor::CursorVisitor::PostChildrenVisitor
clang::cxcursor::CursorVisitor::ClientData
clang::cxcursor::CursorVisitor::VisitPreprocessorLast
clang::cxcursor::CursorVisitor::VisitIncludedEntities
clang::cxcursor::CursorVisitor::RegionOfInterest
clang::cxcursor::CursorVisitor::VisitDeclsOnly
clang::cxcursor::CursorVisitor::DI_current
clang::cxcursor::CursorVisitor::DE_current
clang::cxcursor::CursorVisitor::FileDI_current
clang::cxcursor::CursorVisitor::FileDE_current
clang::cxcursor::CursorVisitor::WorkListFreeList
clang::cxcursor::CursorVisitor::WorkListCache
clang::cxcursor::CursorVisitor::CompareRegionOfInterest
clang::cxcursor::CursorVisitor::visitDeclsFromFileRegion
clang::cxcursor::CursorVisitor::SetParentRAII
clang::cxcursor::CursorVisitor::SetParentRAII::Parent
clang::cxcursor::CursorVisitor::SetParentRAII::StmtParent
clang::cxcursor::CursorVisitor::SetParentRAII::OldParent
clang::cxcursor::CursorVisitor::getASTUnit
clang::cxcursor::CursorVisitor::getTU
clang::cxcursor::CursorVisitor::Visit
clang::cxcursor::CursorVisitor::visitFileRegion
clang::cxcursor::CursorVisitor::visitPreprocessedEntitiesInRegion
clang::cxcursor::CursorVisitor::shouldVisitIncludedEntities
clang::cxcursor::CursorVisitor::visitPreprocessedEntities
clang::cxcursor::CursorVisitor::VisitChildren
clang::cxcursor::CursorVisitor::VisitTypeAliasTemplateDecl
clang::cxcursor::CursorVisitor::VisitTypeAliasDecl
clang::cxcursor::CursorVisitor::VisitAttributes
clang::cxcursor::CursorVisitor::VisitBlockDecl
clang::cxcursor::CursorVisitor::VisitCXXRecordDecl
clang::cxcursor::CursorVisitor::shouldVisitCursor
clang::cxcursor::CursorVisitor::VisitDeclContext
clang::cxcursor::CursorVisitor::VisitTranslationUnitDecl
clang::cxcursor::CursorVisitor::VisitTypedefDecl
clang::cxcursor::CursorVisitor::VisitTagDecl
clang::cxcursor::CursorVisitor::VisitClassTemplateSpecializationDecl
clang::cxcursor::CursorVisitor::VisitClassTemplatePartialSpecializationDecl
clang::cxcursor::CursorVisitor::VisitTemplateTypeParmDecl
clang::cxcursor::CursorVisitor::VisitEnumConstantDecl
clang::cxcursor::CursorVisitor::VisitDeclaratorDecl
clang::cxcursor::CursorVisitor::VisitFunctionDecl
clang::cxcursor::CursorVisitor::VisitFieldDecl
clang::cxcursor::CursorVisitor::VisitVarDecl
clang::cxcursor::CursorVisitor::VisitNonTypeTemplateParmDecl
clang::cxcursor::CursorVisitor::VisitFunctionTemplateDecl
clang::cxcursor::CursorVisitor::VisitClassTemplateDecl
clang::cxcursor::CursorVisitor::VisitTemplateTemplateParmDecl
clang::cxcursor::CursorVisitor::VisitObjCTypeParamDecl
clang::cxcursor::CursorVisitor::VisitObjCMethodDecl
clang::cxcursor::CursorVisitor::VisitObjCContainerDecl
clang::cxcursor::CursorVisitor::VisitObjCCategoryDecl
clang::cxcursor::CursorVisitor::VisitObjCProtocolDecl
clang::cxcursor::CursorVisitor::VisitObjCPropertyDecl
clang::cxcursor::CursorVisitor::VisitObjCTypeParamList
clang::cxcursor::CursorVisitor::VisitObjCInterfaceDecl
clang::cxcursor::CursorVisitor::VisitObjCImplDecl
clang::cxcursor::CursorVisitor::VisitObjCCategoryImplDecl
clang::cxcursor::CursorVisitor::VisitObjCImplementationDecl
clang::cxcursor::CursorVisitor::VisitObjCPropertyImplDecl
clang::cxcursor::CursorVisitor::VisitLinkageSpecDecl
clang::cxcursor::CursorVisitor::VisitNamespaceDecl
clang::cxcursor::CursorVisitor::VisitNamespaceAliasDecl
clang::cxcursor::CursorVisitor::VisitUsingDirectiveDecl
clang::cxcursor::CursorVisitor::VisitUsingDecl
clang::cxcursor::CursorVisitor::VisitUnresolvedUsingValueDecl
clang::cxcursor::CursorVisitor::VisitUnresolvedUsingTypenameDecl
clang::cxcursor::CursorVisitor::VisitStaticAssertDecl
clang::cxcursor::CursorVisitor::VisitFriendDecl
clang::cxcursor::CursorVisitor::VisitDeclarationNameInfo
clang::cxcursor::CursorVisitor::VisitNestedNameSpecifier
clang::cxcursor::CursorVisitor::VisitNestedNameSpecifierLoc
clang::cxcursor::CursorVisitor::VisitTemplateParameters
clang::cxcursor::CursorVisitor::VisitTemplateName
clang::cxcursor::CursorVisitor::VisitTemplateArgumentLoc
clang::cxcursor::CursorVisitor::VisitTagTypeLoc
clang::cxcursor::CursorVisitor::VisitArrayTypeLoc
clang::cxcursor::CursorVisitor::VisitFunctionTypeLoc
clang::cxcursor::CursorVisitor::IsInRegionOfInterest
clang::cxcursor::CursorVisitor::RunVisitorWorkList
clang::cxcursor::CursorVisitor::EnqueueWorkList
clang::cxcursor::CursorVisitor::Visit
clang::cxcursor::CursorVisitor::handleDeclForVisitation