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