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