• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
20 namespace clang {
21   class PreprocessingRecord;
22   class ASTUnit;
23 
24 namespace cxcursor {
25 
26 class VisitorJob {
27 public:
28   enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
29               TypeLocVisitKind, OverloadExprPartsKind,
30               DeclRefExprPartsKind, LabelRefVisitKind,
31               ExplicitTemplateArgsVisitKind,
32               NestedNameSpecifierLocVisitKind,
33               DeclarationNameInfoVisitKind,
34               MemberRefVisitKind, SizeOfPackExprPartsKind,
35               LambdaExprPartsKind };
36 protected:
37   void *data[3];
38   CXCursor parent;
39   Kind K;
40   VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
parent(C)41     : parent(C), K(k) {
42     data[0] = d1;
43     data[1] = d2;
44     data[2] = d3;
45   }
46 public:
getKind()47   Kind getKind() const { return K; }
getParent()48   const CXCursor &getParent() const { return parent; }
classof(VisitorJob * VJ)49   static bool classof(VisitorJob *VJ) { return true; }
50 };
51 
52 typedef SmallVector<VisitorJob, 10> VisitorWorkList;
53 
54 // Cursor visitor.
55 class 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:
SetParentRAII(CXCursor & Parent,Decl * & StmtParent,CXCursor NewParent)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 
~SetParentRAII()127     ~SetParentRAII() {
128       Parent = OldParent;
129       if (clang_isDeclaration(Parent.kind))
130         StmtParent = getCursorDecl(Parent);
131     }
132   };
133 
134 public:
135   CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
136                 CXClientData ClientData,
137                 bool VisitPreprocessorLast,
138                 bool VisitIncludedPreprocessingEntries = false,
139                 SourceRange RegionOfInterest = SourceRange(),
140                 bool VisitDeclsOnly = false)
TU(TU)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 
~CursorVisitor()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 
getASTUnit()164   ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
getTU()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 
shouldVisitIncludedEntities()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