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