CursorVisitor.h 9.7 KB

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