CursorVisitor.h revision e397bf1bd90cfceb0166606ebcd2580b7671a828
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===- CursorVisitor.h - CursorVisitor interface --------------------------===// 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The LLVM Compiler Infrastructure 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// License. See LICENSE.TXT for details. 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//===----------------------------------------------------------------------===// 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef LLVM_CLANG_LIBCLANG_CURSORVISITOR_H 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define LLVM_CLANG_LIBCLANG_CURSORVISITOR_H 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "Index_Internal.h" 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "CXCursor.h" 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "CXTranslationUnit.h" 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "clang/AST/DeclVisitor.h" 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "clang/AST/TypeLocVisitor.h" 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace clang { 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class PreprocessingRecord; 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) class ASTUnit; 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)namespace cxcursor { 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)class VisitorJob { 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)public: 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind, 29e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) TypeLocVisitKind, OverloadExprPartsKind, 30e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) DeclRefExprPartsKind, LabelRefVisitKind, 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ExplicitTemplateArgsVisitKind, 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NestedNameSpecifierLocVisitKind, 33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) DeclarationNameInfoVisitKind, 3402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch MemberRefVisitKind, SizeOfPackExprPartsKind }; 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected: 3602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch void *data[3]; 375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) CXCursor parent; 3851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) Kind K; 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : parent(C), K(k) { 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[0] = d1; 425d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) data[1] = d2; 435d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) data[2] = d3; 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 463c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch Kind getKind() const { return K; } 473c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch const CXCursor &getParent() const { return parent; } 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static bool classof(VisitorJob *VJ) { return true; } 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef SmallVector<VisitorJob, 10> VisitorWorkList; 5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Cursor visitor. 547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass CursorVisitor : public DeclVisitor<CursorVisitor, bool>, 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public TypeLocVisitor<CursorVisitor, bool> 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// \brief The translation unit we are traversing. 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) CXTranslationUnit TU; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASTUnit *AU; 6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// \brief The parent cursor whose children we are traversing. 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CXCursor Parent; 63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// \brief The declaration that serves at the parent of any statement or 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// expression nodes. 66197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Decl *StmtParent; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch /// \brief The visitor function. 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CXCursorVisitor Visitor; 70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// \brief The opaque client data, to be passed along to the visitor. 7202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch CXClientData ClientData; 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /// \brief Whether we should visit the preprocessing record entries last, 75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) /// after visiting other declarations. 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool VisitPreprocessorLast; 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// \brief Whether we should visit declarations or preprocessing record 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// entries that are #included inside the \arg RegionOfInterest. 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool VisitIncludedEntities; 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// \brief When valid, a source range to which the cursor should restrict 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// its search. 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SourceRange RegionOfInterest; 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 863c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // FIXME: Eventually remove. This part of a hack to support proper 873c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch // iteration over all Decls contained lexically within an ObjC container. 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DeclContext::decl_iterator *DI_current; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DeclContext::decl_iterator DE_current; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) // Cache of pre-allocated worklists for data-recursion walk of Stmts. 928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) SmallVector<VisitorWorkList*, 5> WorkListFreeList; 93c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles) SmallVector<VisitorWorkList*, 5> WorkListCache; 943c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch 953c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch using DeclVisitor<CursorVisitor, bool>::Visit; 963c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch using TypeLocVisitor<CursorVisitor, bool>::Visit; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 983c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch /// \brief Determine whether this particular source range comes before, comes 993c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch /// after, or overlaps the region of interest. 1003c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch /// 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /// \param R a half-open source range retrieved from the abstract syntax tree. 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RangeComparisonResult CompareRegionOfInterest(SourceRange R); 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 106 class SetParentRAII { 107 CXCursor &Parent; 108 Decl *&StmtParent; 109 CXCursor OldParent; 110 111 public: 112 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent) 113 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) 114 { 115 Parent = NewParent; 116 if (clang_isDeclaration(Parent.kind)) 117 StmtParent = getCursorDecl(Parent); 118 } 119 120 ~SetParentRAII() { 121 Parent = OldParent; 122 if (clang_isDeclaration(Parent.kind)) 123 StmtParent = getCursorDecl(Parent); 124 } 125 }; 126 127public: 128 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor, 129 CXClientData ClientData, 130 bool VisitPreprocessorLast, 131 bool VisitIncludedPreprocessingEntries = false, 132 SourceRange RegionOfInterest = SourceRange()) 133 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)), 134 Visitor(Visitor), ClientData(ClientData), 135 VisitPreprocessorLast(VisitPreprocessorLast), 136 VisitIncludedEntities(VisitIncludedPreprocessingEntries), 137 RegionOfInterest(RegionOfInterest), DI_current(0) 138 { 139 Parent.kind = CXCursor_NoDeclFound; 140 Parent.data[0] = 0; 141 Parent.data[1] = 0; 142 Parent.data[2] = 0; 143 StmtParent = 0; 144 } 145 146 ~CursorVisitor() { 147 // Free the pre-allocated worklists for data-recursion. 148 for (SmallVectorImpl<VisitorWorkList*>::iterator 149 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) { 150 delete *I; 151 } 152 } 153 154 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); } 155 CXTranslationUnit getTU() const { return TU; } 156 157 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false); 158 159 /// \brief Visit declarations and preprocessed entities for the file region 160 /// designated by \see RegionOfInterest. 161 void visitFileRegion(); 162 163 bool visitPreprocessedEntitiesInRegion(); 164 165 bool shouldVisitIncludedEntities() const { 166 return VisitIncludedEntities; 167 } 168 169 template<typename InputIterator> 170 bool visitPreprocessedEntities(InputIterator First, InputIterator Last, 171 PreprocessingRecord &PPRec, 172 FileID FID = FileID()); 173 174 bool VisitChildren(CXCursor Parent); 175 176 // Declaration visitors 177 bool VisitTypeAliasDecl(TypeAliasDecl *D); 178 bool VisitAttributes(Decl *D); 179 bool VisitBlockDecl(BlockDecl *B); 180 bool VisitCXXRecordDecl(CXXRecordDecl *D); 181 llvm::Optional<bool> shouldVisitCursor(CXCursor C); 182 bool VisitDeclContext(DeclContext *DC); 183 bool VisitTranslationUnitDecl(TranslationUnitDecl *D); 184 bool VisitTypedefDecl(TypedefDecl *D); 185 bool VisitTagDecl(TagDecl *D); 186 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D); 187 bool VisitClassTemplatePartialSpecializationDecl( 188 ClassTemplatePartialSpecializationDecl *D); 189 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); 190 bool VisitEnumConstantDecl(EnumConstantDecl *D); 191 bool VisitDeclaratorDecl(DeclaratorDecl *DD); 192 bool VisitFunctionDecl(FunctionDecl *ND); 193 bool VisitFieldDecl(FieldDecl *D); 194 bool VisitVarDecl(VarDecl *); 195 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); 196 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D); 197 bool VisitClassTemplateDecl(ClassTemplateDecl *D); 198 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); 199 bool VisitObjCMethodDecl(ObjCMethodDecl *ND); 200 bool VisitObjCContainerDecl(ObjCContainerDecl *D); 201 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); 202 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); 203 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD); 204 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); 205 bool VisitObjCImplDecl(ObjCImplDecl *D); 206 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); 207 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); 208 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations. 209 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); 210 bool VisitObjCClassDecl(ObjCClassDecl *D); 211 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD); 212 bool VisitLinkageSpecDecl(LinkageSpecDecl *D); 213 bool VisitNamespaceDecl(NamespaceDecl *D); 214 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D); 215 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D); 216 bool VisitUsingDecl(UsingDecl *D); 217 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); 218 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); 219 220 // Name visitor 221 bool VisitDeclarationNameInfo(DeclarationNameInfo Name); 222 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range); 223 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 224 225 // Template visitors 226 bool VisitTemplateParameters(const TemplateParameterList *Params); 227 bool VisitTemplateName(TemplateName Name, SourceLocation Loc); 228 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL); 229 230 // Type visitors 231#define ABSTRACT_TYPELOC(CLASS, PARENT) 232#define TYPELOC(CLASS, PARENT) \ 233 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); 234#include "clang/AST/TypeLocNodes.def" 235 236 bool VisitTagTypeLoc(TagTypeLoc TL); 237 bool VisitArrayTypeLoc(ArrayTypeLoc TL); 238 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); 239 240 // Data-recursive visitor functions. 241 bool IsInRegionOfInterest(CXCursor C); 242 bool RunVisitorWorkList(VisitorWorkList &WL); 243 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S); 244 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S); 245}; 246 247} 248} 249 250#endif 251 252