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