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