Coverage Report

Created: 2020-02-15 09:57

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/tools/libclang/CXIndexDataConsumer.h
Line
Count
Source (jump to first uncovered line)
1
//===- CXIndexDataConsumer.h - Index data consumer for libclang--*- 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_CXINDEXDATACONSUMER_H
10
#define LLVM_CLANG_TOOLS_LIBCLANG_CXINDEXDATACONSUMER_H
11
12
#include "CXCursor.h"
13
#include "Index_Internal.h"
14
#include "clang/Index/IndexDataConsumer.h"
15
#include "clang/AST/DeclGroup.h"
16
#include "clang/AST/DeclObjC.h"
17
#include "llvm/ADT/DenseSet.h"
18
19
namespace clang {
20
  class FileEntry;
21
  class MSPropertyDecl;
22
  class ObjCPropertyDecl;
23
  class ClassTemplateDecl;
24
  class FunctionTemplateDecl;
25
  class TypeAliasTemplateDecl;
26
  class ClassTemplateSpecializationDecl;
27
28
namespace cxindex {
29
  class CXIndexDataConsumer;
30
  class AttrListInfo;
31
32
class ScratchAlloc {
33
  CXIndexDataConsumer &IdxCtx;
34
35
public:
36
  explicit ScratchAlloc(CXIndexDataConsumer &indexCtx);
37
  ScratchAlloc(const ScratchAlloc &SA);
38
39
  ~ScratchAlloc();
40
41
  const char *toCStr(StringRef Str);
42
  const char *copyCStr(StringRef Str);
43
44
  template <typename T>
45
  T *allocate();
46
};
47
48
struct EntityInfo : public CXIdxEntityInfo {
49
  const NamedDecl *Dcl;
50
  CXIndexDataConsumer *IndexCtx;
51
  IntrusiveRefCntPtr<AttrListInfo> AttrList;
52
53
4.12k
  EntityInfo() {
54
4.12k
    name = USR = nullptr;
55
4.12k
    attributes = nullptr;
56
4.12k
    numAttributes = 0;
57
4.12k
  }
58
};
59
60
struct ContainerInfo : public CXIdxContainerInfo {
61
  const DeclContext *DC;
62
  CXIndexDataConsumer *IndexCtx;
63
};
64
  
65
struct DeclInfo : public CXIdxDeclInfo {
66
  enum DInfoKind {
67
    Info_Decl,
68
69
    Info_ObjCContainer,
70
      Info_ObjCInterface,
71
      Info_ObjCProtocol,
72
      Info_ObjCCategory,
73
74
    Info_ObjCProperty,
75
76
    Info_CXXClass
77
  };
78
  
79
  DInfoKind Kind;
80
81
  EntityInfo EntInfo;
82
  ContainerInfo SemanticContainer;
83
  ContainerInfo LexicalContainer;
84
  ContainerInfo DeclAsContainer;
85
86
  DeclInfo(bool isRedeclaration, bool isDefinition, bool isContainer)
87
227
    : Kind(Info_Decl) {
88
227
    this->isRedeclaration = isRedeclaration;
89
227
    this->isDefinition = isDefinition;
90
227
    this->isContainer = isContainer;
91
227
    attributes = nullptr;
92
227
    numAttributes = 0;
93
227
    declAsContainer = semanticContainer = lexicalContainer = nullptr;
94
227
    flags = 0;
95
227
  }
96
  DeclInfo(DInfoKind K,
97
           bool isRedeclaration, bool isDefinition, bool isContainer)
98
76
    : Kind(K) {
99
76
    this->isRedeclaration = isRedeclaration;
100
76
    this->isDefinition = isDefinition;
101
76
    this->isContainer = isContainer;
102
76
    attributes = nullptr;
103
76
    numAttributes = 0;
104
76
    declAsContainer = semanticContainer = lexicalContainer = nullptr;
105
76
    flags = 0;
106
76
  }
107
};
108
109
struct ObjCContainerDeclInfo : public DeclInfo {
110
  CXIdxObjCContainerDeclInfo ObjCContDeclInfo;
111
112
  ObjCContainerDeclInfo(bool isForwardRef,
113
                        bool isRedeclaration,
114
                        bool isImplementation)
115
    : DeclInfo(Info_ObjCContainer, isRedeclaration,
116
10
               /*isDefinition=*/!isForwardRef, /*isContainer=*/!isForwardRef) {
117
10
    init(isForwardRef, isImplementation);
118
10
  }
119
  ObjCContainerDeclInfo(DInfoKind K,
120
                        bool isForwardRef,
121
                        bool isRedeclaration,
122
                        bool isImplementation)
123
    : DeclInfo(K, isRedeclaration, /*isDefinition=*/!isForwardRef,
124
26
               /*isContainer=*/!isForwardRef) {
125
26
    init(isForwardRef, isImplementation);
126
26
  }
127
128
72
  static bool classof(const DeclInfo *D) {
129
72
    return Info_ObjCContainer <= D->Kind && D->Kind <= Info_ObjCCategory;
130
72
  }
131
132
private:
133
36
  void init(bool isForwardRef, bool isImplementation) {
134
36
    if (isForwardRef)
135
6
      ObjCContDeclInfo.kind = CXIdxObjCContainer_ForwardRef;
136
30
    else if (isImplementation)
137
4
      ObjCContDeclInfo.kind = CXIdxObjCContainer_Implementation;
138
26
    else
139
26
      ObjCContDeclInfo.kind = CXIdxObjCContainer_Interface;
140
36
  }
141
};
142
143
struct ObjCInterfaceDeclInfo : public ObjCContainerDeclInfo {
144
  CXIdxObjCInterfaceDeclInfo ObjCInterDeclInfo;
145
  CXIdxObjCProtocolRefListInfo ObjCProtoListInfo;
146
147
  ObjCInterfaceDeclInfo(const ObjCInterfaceDecl *D)
148
    : ObjCContainerDeclInfo(Info_ObjCInterface,
149
                            /*isForwardRef=*/false,
150
                            /*isRedeclaration=*/D->getPreviousDecl() != nullptr,
151
20
                            /*isImplementation=*/false) { }
152
153
646
  static bool classof(const DeclInfo *D) {
154
646
    return D->Kind == Info_ObjCInterface;
155
646
  }
156
};
157
158
struct ObjCProtocolDeclInfo : public ObjCContainerDeclInfo {
159
  CXIdxObjCProtocolRefListInfo ObjCProtoRefListInfo;
160
161
  ObjCProtocolDeclInfo(const ObjCProtocolDecl *D)
162
    : ObjCContainerDeclInfo(Info_ObjCProtocol,
163
                            /*isForwardRef=*/false,
164
                            /*isRedeclaration=*/D->getPreviousDecl(),
165
3
                            /*isImplementation=*/false) { }
166
167
286
  static bool classof(const DeclInfo *D) {
168
286
    return D->Kind == Info_ObjCProtocol;
169
286
  }
170
};
171
172
struct ObjCCategoryDeclInfo : public ObjCContainerDeclInfo {
173
  CXIdxObjCCategoryDeclInfo ObjCCatDeclInfo;
174
  CXIdxObjCProtocolRefListInfo ObjCProtoListInfo;
175
176
  explicit ObjCCategoryDeclInfo(bool isImplementation)
177
    : ObjCContainerDeclInfo(Info_ObjCCategory,
178
                            /*isForwardRef=*/false,
179
                            /*isRedeclaration=*/isImplementation,
180
3
                            /*isImplementation=*/isImplementation) { }
181
182
589
  static bool classof(const DeclInfo *D) {
183
589
    return D->Kind == Info_ObjCCategory;
184
589
  }
185
};
186
187
struct ObjCPropertyDeclInfo : public DeclInfo {
188
  CXIdxObjCPropertyDeclInfo ObjCPropDeclInfo;
189
190
  ObjCPropertyDeclInfo()
191
    : DeclInfo(Info_ObjCProperty,
192
               /*isRedeclaration=*/false, /*isDefinition=*/false,
193
8
               /*isContainer=*/false) { }
194
195
311
  static bool classof(const DeclInfo *D) {
196
311
    return D->Kind == Info_ObjCProperty;
197
311
  }
198
};
199
200
struct CXXClassDeclInfo : public DeclInfo {
201
  CXIdxCXXClassDeclInfo CXXClassInfo;
202
203
  CXXClassDeclInfo(bool isRedeclaration, bool isDefinition)
204
32
    : DeclInfo(Info_CXXClass, isRedeclaration, isDefinition, isDefinition) { }
205
206
335
  static bool classof(const DeclInfo *D) {
207
335
    return D->Kind == Info_CXXClass;
208
335
  }
209
};
210
211
struct AttrInfo : public CXIdxAttrInfo {
212
  const Attr *A;
213
214
48
  AttrInfo(CXIdxAttrKind Kind, CXCursor C, CXIdxLoc Loc, const Attr *A) {
215
48
    kind = Kind;
216
48
    cursor = C;
217
48
    loc = Loc;
218
48
    this->A = A;
219
48
  }
220
};
221
222
struct IBOutletCollectionInfo : public AttrInfo {
223
  EntityInfo ClassInfo;
224
  CXIdxIBOutletCollectionAttrInfo IBCollInfo;
225
226
  IBOutletCollectionInfo(CXCursor C, CXIdxLoc Loc, const Attr *A) :
227
3
    AttrInfo(CXIdxAttr_IBOutletCollection, C, Loc, A) {
228
3
    assert(C.kind == CXCursor_IBOutletCollectionAttr);
229
3
    IBCollInfo.objcClass = nullptr;
230
3
  }
231
232
  IBOutletCollectionInfo(const IBOutletCollectionInfo &other);
233
234
0
  static bool classof(const AttrInfo *A) {
235
0
    return A->kind == CXIdxAttr_IBOutletCollection;
236
0
  }
237
};
238
239
class AttrListInfo {
240
  ScratchAlloc SA;
241
242
  SmallVector<AttrInfo, 2> Attrs;
243
  SmallVector<IBOutletCollectionInfo, 2> IBCollAttrs;
244
  SmallVector<CXIdxAttrInfo *, 2> CXAttrs;
245
  unsigned ref_cnt;
246
247
  AttrListInfo(const AttrListInfo &) = delete;
248
  void operator=(const AttrListInfo &) = delete;
249
public:
250
  AttrListInfo(const Decl *D, CXIndexDataConsumer &IdxCtx);
251
252
  static IntrusiveRefCntPtr<AttrListInfo> create(const Decl *D,
253
                                                 CXIndexDataConsumer &IdxCtx);
254
255
42
  const CXIdxAttrInfo *const *getAttrs() const {
256
42
    if (CXAttrs.empty())
257
0
      return nullptr;
258
42
    return CXAttrs.data();
259
42
  }
260
42
  unsigned getNumAttrs() const { return (unsigned)CXAttrs.size(); }
261
262
  /// Retain/Release only useful when we allocate a AttrListInfo from the
263
  /// BumpPtrAllocator, and not from the stack; so that we keep a pointer
264
  // in the EntityInfo
265
42
  void Retain() { ++ref_cnt; }
266
42
  void Release() {
267
42
    assert (ref_cnt > 0 && "Reference count is already zero.");
268
42
    if (--ref_cnt == 0) {
269
42
      // Memory is allocated from a BumpPtrAllocator, no need to delete it.
270
42
      this->~AttrListInfo();
271
42
    }
272
42
  }
273
};
274
275
class CXIndexDataConsumer : public index::IndexDataConsumer {
276
  ASTContext *Ctx;
277
  CXClientData ClientData;
278
  IndexerCallbacks &CB;
279
  unsigned IndexOptions;
280
  CXTranslationUnit CXTU;
281
  
282
  typedef llvm::DenseMap<const FileEntry *, CXIdxClientFile> FileMapTy;
283
  typedef llvm::DenseMap<const DeclContext *, CXIdxClientContainer>
284
    ContainerMapTy;
285
  typedef llvm::DenseMap<const Decl *, CXIdxClientEntity> EntityMapTy;
286
287
  FileMapTy FileMap;
288
  ContainerMapTy ContainerMap;
289
  EntityMapTy EntityMap;
290
291
  typedef std::pair<const FileEntry *, const Decl *> RefFileOccurrence;
292
  llvm::DenseSet<RefFileOccurrence> RefFileOccurrences;
293
294
  llvm::BumpPtrAllocator StrScratch;
295
  unsigned StrAdapterCount;
296
  friend class ScratchAlloc;
297
298
  struct ObjCProtocolListInfo {
299
    SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos;
300
    SmallVector<EntityInfo, 4> ProtEntities;
301
    SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots;
302
303
26
    CXIdxObjCProtocolRefListInfo getListInfo() const {
304
26
      CXIdxObjCProtocolRefListInfo Info = { Prots.data(),
305
26
                                            (unsigned)Prots.size() };
306
26
      return Info;
307
26
    }
308
309
    ObjCProtocolListInfo(const ObjCProtocolList &ProtList,
310
                         CXIndexDataConsumer &IdxCtx,
311
                         ScratchAlloc &SA);
312
  };
313
314
  struct CXXBasesListInfo {
315
    SmallVector<CXIdxBaseClassInfo, 4> BaseInfos;
316
    SmallVector<EntityInfo, 4> BaseEntities;
317
    SmallVector<CXIdxBaseClassInfo *, 4> CXBases;
318
319
34
    const CXIdxBaseClassInfo *const *getBases() const {
320
34
      return CXBases.data();
321
34
    }
322
35
    unsigned getNumBases() const { return (unsigned)CXBases.size(); }
323
324
    CXXBasesListInfo(const CXXRecordDecl *D,
325
                     CXIndexDataConsumer &IdxCtx, ScratchAlloc &SA);
326
327
  private:
328
    SourceLocation getBaseLoc(const CXXBaseSpecifier &Base) const;
329
  };
330
331
  friend class AttrListInfo;
332
333
public:
334
  CXIndexDataConsumer(CXClientData clientData, IndexerCallbacks &indexCallbacks,
335
                  unsigned indexOptions, CXTranslationUnit cxTU)
336
    : Ctx(nullptr), ClientData(clientData), CB(indexCallbacks),
337
      IndexOptions(indexOptions), CXTU(cxTU),
338
44
      StrScratch(), StrAdapterCount(0) { }
339
340
2.20k
  ASTContext &getASTContext() const { return *Ctx; }
341
1.86k
  CXTranslationUnit getCXTU() const { return CXTU; }
342
343
  void setASTContext(ASTContext &ctx);
344
  void setPreprocessor(std::shared_ptr<Preprocessor> PP) override;
345
346
2.24k
  bool shouldSuppressRefs() const {
347
2.24k
    return IndexOptions & CXIndexOpt_SuppressRedundantRefs;
348
2.24k
  }
349
350
2.20k
  bool shouldIndexFunctionLocalSymbols() const {
351
2.20k
    return IndexOptions & CXIndexOpt_IndexFunctionLocalSymbols;
352
2.20k
  }
353
354
108
  bool shouldIndexImplicitTemplateInsts() const {
355
108
    return IndexOptions & CXIndexOpt_IndexImplicitTemplateInstantiations;
356
108
  }
357
358
  static bool isFunctionLocalDecl(const Decl *D);
359
360
  bool shouldAbort();
361
362
52
  bool hasDiagnosticCallback() const { return CB.diagnostic; }
363
364
  void enteredMainFile(const FileEntry *File);
365
366
  void ppIncludedFile(SourceLocation hashLoc,
367
                      StringRef filename, const FileEntry *File,
368
                      bool isImport, bool isAngled, bool isModuleImport);
369
370
  void importedModule(const ImportDecl *ImportD);
371
  void importedPCH(const FileEntry *File);
372
373
  void startedTranslationUnit();
374
375
  void indexDiagnostics();
376
377
  void handleDiagnosticSet(CXDiagnosticSet CXDiagSet);
378
379
  bool handleFunction(const FunctionDecl *FD);
380
381
  bool handleVar(const VarDecl *D);
382
383
  bool handleField(const FieldDecl *D);
384
385
  bool handleEnumerator(const EnumConstantDecl *D);
386
387
  bool handleTagDecl(const TagDecl *D);
388
  
389
  bool handleTypedefName(const TypedefNameDecl *D);
390
391
  bool handleObjCInterface(const ObjCInterfaceDecl *D);
392
  bool handleObjCImplementation(const ObjCImplementationDecl *D);
393
394
  bool handleObjCProtocol(const ObjCProtocolDecl *D);
395
396
  bool handleObjCCategory(const ObjCCategoryDecl *D);
397
  bool handleObjCCategoryImpl(const ObjCCategoryImplDecl *D);
398
399
  bool handleObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc);
400
401
  bool handleSynthesizedObjCProperty(const ObjCPropertyImplDecl *D);
402
  bool handleSynthesizedObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc,
403
                                   const DeclContext *LexicalDC);
404
405
  bool handleObjCProperty(const ObjCPropertyDecl *D);
406
407
  bool handleNamespace(const NamespaceDecl *D);
408
409
  bool handleClassTemplate(const ClassTemplateDecl *D);
410
  bool handleFunctionTemplate(const FunctionTemplateDecl *D);
411
  bool handleTypeAliasTemplate(const TypeAliasTemplateDecl *D);
412
413
  bool handleReference(const NamedDecl *D, SourceLocation Loc, CXCursor Cursor,
414
                       const NamedDecl *Parent,
415
                       const DeclContext *DC,
416
                       const Expr *E = nullptr,
417
                       CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct,
418
                       CXSymbolRole Role = CXSymbolRole_None);
419
420
  bool isNotFromSourceFile(SourceLocation Loc) const;
421
422
  void translateLoc(SourceLocation Loc, CXIdxClientFile *indexFile, CXFile *file,
423
                    unsigned *line, unsigned *column, unsigned *offset);
424
425
  CXIdxClientContainer getClientContainerForDC(const DeclContext *DC) const;
426
  void addContainerInMap(const DeclContext *DC, CXIdxClientContainer container);
427
428
  CXIdxClientEntity getClientEntity(const Decl *D) const;
429
  void setClientEntity(const Decl *D, CXIdxClientEntity client);
430
431
  static bool isTemplateImplicitInstantiation(const Decl *D);
432
433
private:
434
  bool handleDeclOccurrence(const Decl *D, index::SymbolRoleSet Roles,
435
                            ArrayRef<index::SymbolRelation> Relations,
436
                            SourceLocation Loc, ASTNodeInfo ASTNode) override;
437
438
  bool handleModuleOccurrence(const ImportDecl *ImportD, const Module *Mod,
439
                              index::SymbolRoleSet Roles,
440
                              SourceLocation Loc) override;
441
442
  void finish() override;
443
444
  bool handleDecl(const NamedDecl *D,
445
                  SourceLocation Loc, CXCursor Cursor,
446
                  DeclInfo &DInfo,
447
                  const DeclContext *LexicalDC = nullptr,
448
                  const DeclContext *SemaDC = nullptr);
449
450
  bool handleObjCContainer(const ObjCContainerDecl *D,
451
                           SourceLocation Loc, CXCursor Cursor,
452
                           ObjCContainerDeclInfo &ContDInfo);
453
454
  bool handleCXXRecordDecl(const CXXRecordDecl *RD, const NamedDecl *OrigD);
455
456
  bool markEntityOccurrenceInFile(const NamedDecl *D, SourceLocation Loc);
457
458
  const NamedDecl *getEntityDecl(const NamedDecl *D) const;
459
460
  const DeclContext *getEntityContainer(const Decl *D) const;
461
462
  CXIdxClientFile getIndexFile(const FileEntry *File);
463
  
464
  CXIdxLoc getIndexLoc(SourceLocation Loc) const;
465
466
  void getEntityInfo(const NamedDecl *D,
467
                     EntityInfo &EntityInfo,
468
                     ScratchAlloc &SA);
469
470
  void getContainerInfo(const DeclContext *DC, ContainerInfo &ContInfo);
471
472
6.72k
  CXCursor getCursor(const Decl *D) {
473
6.72k
    return cxcursor::MakeCXCursor(D, CXTU);
474
6.72k
  }
475
476
  CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc);
477
478
  static bool shouldIgnoreIfImplicit(const Decl *D);
479
};
480
481
2.38k
inline ScratchAlloc::ScratchAlloc(CXIndexDataConsumer &idxCtx) : IdxCtx(idxCtx) {
482
2.38k
  ++IdxCtx.StrAdapterCount;
483
2.38k
}
484
inline ScratchAlloc::ScratchAlloc(const ScratchAlloc &SA) : IdxCtx(SA.IdxCtx) {
485
  ++IdxCtx.StrAdapterCount;
486
}
487
488
2.38k
inline ScratchAlloc::~ScratchAlloc() {
489
2.38k
  --IdxCtx.StrAdapterCount;
490
2.38k
  if (IdxCtx.StrAdapterCount == 0)
491
2.23k
    IdxCtx.StrScratch.Reset();
492
2.38k
}
493
494
template <typename T>
495
42
inline T *ScratchAlloc::allocate() {
496
42
  return IdxCtx.StrScratch.Allocate<T>();
497
42
}
498
499
}} // end clang::cxindex
500
501
#endif