CursorVisitor.h 10 KB

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