Coverage Report

Created: 2020-02-15 09:57

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