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