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