Coverage Report

Created: 2022-07-16 07:03

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