CursorVisitor.h revision f59edb96b2d0bfe612b732f19519ab84bb995bd4
1//===- CursorVisitor.h - CursorVisitor interface ----------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef LLVM_CLANG_LIBCLANG_CURSORVISITOR_H 11#define LLVM_CLANG_LIBCLANG_CURSORVISITOR_H 12 13#include "CXCursor.h" 14#include "CXTranslationUnit.h" 15#include "Index_Internal.h" 16#include "clang/AST/DeclVisitor.h" 17#include "clang/AST/TypeLocVisitor.h" 18 19namespace clang { 20 class PreprocessingRecord; 21 class ASTUnit; 22 23namespace cxcursor { 24 25class VisitorJob { 26public: 27 enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind, 28 TypeLocVisitKind, OverloadExprPartsKind, 29 DeclRefExprPartsKind, LabelRefVisitKind, 30 ExplicitTemplateArgsVisitKind, 31 NestedNameSpecifierLocVisitKind, 32 DeclarationNameInfoVisitKind, 33 MemberRefVisitKind, SizeOfPackExprPartsKind, 34 LambdaExprPartsKind, PostChildrenVisitKind }; 35protected: 36 void *data[3]; 37 CXCursor parent; 38 Kind K; 39 VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0) 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<VisitorJob, 10> VisitorWorkList; 51 52// Cursor visitor. 53class CursorVisitor : public DeclVisitor<CursorVisitor, bool>, 54 public TypeLocVisitor<CursorVisitor, bool> 55{ 56public: 57 /// \brief 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 /// \brief The translation unit we are traversing. 64 CXTranslationUnit TU; 65 ASTUnit *AU; 66 67 /// \brief The parent cursor whose children we are traversing. 68 CXCursor Parent; 69 70 /// \brief The declaration that serves at the parent of any statement or 71 /// expression nodes. 72 Decl *StmtParent; 73 74 /// \brief The visitor function. 75 CXCursorVisitor Visitor; 76 77 PostChildrenVisitorTy PostChildrenVisitor; 78 79 /// \brief The opaque client data, to be passed along to the visitor. 80 CXClientData ClientData; 81 82 /// \brief Whether we should visit the preprocessing record entries last, 83 /// after visiting other declarations. 84 bool VisitPreprocessorLast; 85 86 /// \brief Whether we should visit declarations or preprocessing record 87 /// entries that are #included inside the \arg RegionOfInterest. 88 bool VisitIncludedEntities; 89 90 /// \brief When valid, a source range to which the cursor should restrict 91 /// its search. 92 SourceRange RegionOfInterest; 93 94 /// \brief 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*, 5> WorkListFreeList; 107 SmallVector<VisitorWorkList*, 5> WorkListCache; 108 109 using DeclVisitor<CursorVisitor, bool>::Visit; 110 using TypeLocVisitor<CursorVisitor, bool>::Visit; 111 112 /// \brief 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 void visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length); 119 120 class SetParentRAII { 121 CXCursor &Parent; 122 Decl *&StmtParent; 123 CXCursor OldParent; 124 125 public: 126 SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent) 127 : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) 128 { 129 Parent = NewParent; 130 if (clang_isDeclaration(Parent.kind)) 131 StmtParent = getCursorDecl(Parent); 132 } 133 134 ~SetParentRAII() { 135 Parent = OldParent; 136 if (clang_isDeclaration(Parent.kind)) 137 StmtParent = getCursorDecl(Parent); 138 } 139 }; 140 141public: 142 CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor, 143 CXClientData ClientData, 144 bool VisitPreprocessorLast, 145 bool VisitIncludedPreprocessingEntries = false, 146 SourceRange RegionOfInterest = SourceRange(), 147 bool VisitDeclsOnly = false, 148 PostChildrenVisitorTy PostChildrenVisitor = 0) 149 : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)), 150 Visitor(Visitor), PostChildrenVisitor(PostChildrenVisitor), 151 ClientData(ClientData), 152 VisitPreprocessorLast(VisitPreprocessorLast), 153 VisitIncludedEntities(VisitIncludedPreprocessingEntries), 154 RegionOfInterest(RegionOfInterest), 155 VisitDeclsOnly(VisitDeclsOnly), 156 DI_current(0), FileDI_current(0) 157 { 158 Parent.kind = CXCursor_NoDeclFound; 159 Parent.data[0] = 0; 160 Parent.data[1] = 0; 161 Parent.data[2] = 0; 162 StmtParent = 0; 163 } 164 165 ~CursorVisitor() { 166 // Free the pre-allocated worklists for data-recursion. 167 for (SmallVectorImpl<VisitorWorkList*>::iterator 168 I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) { 169 delete *I; 170 } 171 } 172 173 ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); } 174 CXTranslationUnit getTU() const { return TU; } 175 176 bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false); 177 178 /// \brief Visit declarations and preprocessed entities for the file region 179 /// designated by \see RegionOfInterest. 180 void visitFileRegion(); 181 182 bool visitPreprocessedEntitiesInRegion(); 183 184 bool shouldVisitIncludedEntities() const { 185 return VisitIncludedEntities; 186 } 187 188 template<typename InputIterator> 189 bool visitPreprocessedEntities(InputIterator First, InputIterator Last, 190 PreprocessingRecord &PPRec, 191 FileID FID = FileID()); 192 193 bool VisitChildren(CXCursor Parent); 194 195 // Declaration visitors 196 bool VisitTypeAliasDecl(TypeAliasDecl *D); 197 bool VisitAttributes(Decl *D); 198 bool VisitBlockDecl(BlockDecl *B); 199 bool VisitCXXRecordDecl(CXXRecordDecl *D); 200 llvm::Optional<bool> shouldVisitCursor(CXCursor C); 201 bool VisitDeclContext(DeclContext *DC); 202 bool VisitTranslationUnitDecl(TranslationUnitDecl *D); 203 bool VisitTypedefDecl(TypedefDecl *D); 204 bool VisitTagDecl(TagDecl *D); 205 bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D); 206 bool VisitClassTemplatePartialSpecializationDecl( 207 ClassTemplatePartialSpecializationDecl *D); 208 bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); 209 bool VisitEnumConstantDecl(EnumConstantDecl *D); 210 bool VisitDeclaratorDecl(DeclaratorDecl *DD); 211 bool VisitFunctionDecl(FunctionDecl *ND); 212 bool VisitFieldDecl(FieldDecl *D); 213 bool VisitVarDecl(VarDecl *); 214 bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); 215 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D); 216 bool VisitClassTemplateDecl(ClassTemplateDecl *D); 217 bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); 218 bool VisitObjCMethodDecl(ObjCMethodDecl *ND); 219 bool VisitObjCContainerDecl(ObjCContainerDecl *D); 220 bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); 221 bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); 222 bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD); 223 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); 224 bool VisitObjCImplDecl(ObjCImplDecl *D); 225 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); 226 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); 227 // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations. 228 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD); 229 bool VisitLinkageSpecDecl(LinkageSpecDecl *D); 230 bool VisitNamespaceDecl(NamespaceDecl *D); 231 bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D); 232 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D); 233 bool VisitUsingDecl(UsingDecl *D); 234 bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); 235 bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); 236 237 // Name visitor 238 bool VisitDeclarationNameInfo(DeclarationNameInfo Name); 239 bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range); 240 bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 241 242 // Template visitors 243 bool VisitTemplateParameters(const TemplateParameterList *Params); 244 bool VisitTemplateName(TemplateName Name, SourceLocation Loc); 245 bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL); 246 247 // Type visitors 248#define ABSTRACT_TYPELOC(CLASS, PARENT) 249#define TYPELOC(CLASS, PARENT) \ 250 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); 251#include "clang/AST/TypeLocNodes.def" 252 253 bool VisitTagTypeLoc(TagTypeLoc TL); 254 bool VisitArrayTypeLoc(ArrayTypeLoc TL); 255 bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); 256 257 // Data-recursive visitor functions. 258 bool IsInRegionOfInterest(CXCursor C); 259 bool RunVisitorWorkList(VisitorWorkList &WL); 260 void EnqueueWorkList(VisitorWorkList &WL, Stmt *S); 261 LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S); 262}; 263 264} 265} 266 267#endif 268 269