brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.2 KiB · b207db7 Raw
503 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXINDEXDATACONSUMER_H10#define LLVM_CLANG_TOOLS_LIBCLANG_CXINDEXDATACONSUMER_H11 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 19namespace clang {20  class FileEntry;21  class MSPropertyDecl;22  class ObjCPropertyDecl;23  class ClassTemplateDecl;24  class FunctionTemplateDecl;25  class TypeAliasTemplateDecl;26  class ClassTemplateSpecializationDecl;27 28namespace cxindex {29  class CXIndexDataConsumer;30  class AttrListInfo;31 32class ScratchAlloc {33  CXIndexDataConsumer &IdxCtx;34 35public: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 48struct EntityInfo : public CXIdxEntityInfo {49  const NamedDecl *Dcl;50  CXIndexDataConsumer *IndexCtx;51  IntrusiveRefCntPtr<AttrListInfo> AttrList;52 53  EntityInfo() {54    name = USR = nullptr;55    attributes = nullptr;56    numAttributes = 0;57  }58};59 60struct ContainerInfo : public CXIdxContainerInfo {61  const DeclContext *DC;62  CXIndexDataConsumer *IndexCtx;63};64  65struct 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_CXXClass77  };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    : Kind(Info_Decl) {88    this->isRedeclaration = isRedeclaration;89    this->isDefinition = isDefinition;90    this->isContainer = isContainer;91    attributes = nullptr;92    numAttributes = 0;93    declAsContainer = semanticContainer = lexicalContainer = nullptr;94    flags = 0;95  }96  DeclInfo(DInfoKind K,97           bool isRedeclaration, bool isDefinition, bool isContainer)98    : Kind(K) {99    this->isRedeclaration = isRedeclaration;100    this->isDefinition = isDefinition;101    this->isContainer = isContainer;102    attributes = nullptr;103    numAttributes = 0;104    declAsContainer = semanticContainer = lexicalContainer = nullptr;105    flags = 0;106  }107};108 109struct ObjCContainerDeclInfo : public DeclInfo {110  CXIdxObjCContainerDeclInfo ObjCContDeclInfo;111 112  ObjCContainerDeclInfo(bool isForwardRef,113                        bool isRedeclaration,114                        bool isImplementation)115    : DeclInfo(Info_ObjCContainer, isRedeclaration,116               /*isDefinition=*/!isForwardRef, /*isContainer=*/!isForwardRef) {117    init(isForwardRef, isImplementation);118  }119  ObjCContainerDeclInfo(DInfoKind K,120                        bool isForwardRef,121                        bool isRedeclaration,122                        bool isImplementation)123    : DeclInfo(K, isRedeclaration, /*isDefinition=*/!isForwardRef,124               /*isContainer=*/!isForwardRef) {125    init(isForwardRef, isImplementation);126  }127 128  static bool classof(const DeclInfo *D) {129    return Info_ObjCContainer <= D->Kind && D->Kind <= Info_ObjCCategory;130  }131 132private:133  void init(bool isForwardRef, bool isImplementation) {134    if (isForwardRef)135      ObjCContDeclInfo.kind = CXIdxObjCContainer_ForwardRef;136    else if (isImplementation)137      ObjCContDeclInfo.kind = CXIdxObjCContainer_Implementation;138    else139      ObjCContDeclInfo.kind = CXIdxObjCContainer_Interface;140  }141};142 143struct 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                            /*isImplementation=*/false) { }152 153  static bool classof(const DeclInfo *D) {154    return D->Kind == Info_ObjCInterface;155  }156};157 158struct ObjCProtocolDeclInfo : public ObjCContainerDeclInfo {159  CXIdxObjCProtocolRefListInfo ObjCProtoRefListInfo;160 161  ObjCProtocolDeclInfo(const ObjCProtocolDecl *D)162    : ObjCContainerDeclInfo(Info_ObjCProtocol,163                            /*isForwardRef=*/false,164                            /*isRedeclaration=*/D->getPreviousDecl(),165                            /*isImplementation=*/false) { }166 167  static bool classof(const DeclInfo *D) {168    return D->Kind == Info_ObjCProtocol;169  }170};171 172struct 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                            /*isImplementation=*/isImplementation) { }181 182  static bool classof(const DeclInfo *D) {183    return D->Kind == Info_ObjCCategory;184  }185};186 187struct ObjCPropertyDeclInfo : public DeclInfo {188  CXIdxObjCPropertyDeclInfo ObjCPropDeclInfo;189 190  ObjCPropertyDeclInfo()191    : DeclInfo(Info_ObjCProperty,192               /*isRedeclaration=*/false, /*isDefinition=*/false,193               /*isContainer=*/false) { }194 195  static bool classof(const DeclInfo *D) {196    return D->Kind == Info_ObjCProperty;197  }198};199 200struct CXXClassDeclInfo : public DeclInfo {201  CXIdxCXXClassDeclInfo CXXClassInfo;202 203  CXXClassDeclInfo(bool isRedeclaration, bool isDefinition)204    : DeclInfo(Info_CXXClass, isRedeclaration, isDefinition, isDefinition) { }205 206  static bool classof(const DeclInfo *D) {207    return D->Kind == Info_CXXClass;208  }209};210 211struct AttrInfo : public CXIdxAttrInfo {212  const Attr *A;213 214  AttrInfo(CXIdxAttrKind Kind, CXCursor C, CXIdxLoc Loc, const Attr *A) {215    kind = Kind;216    cursor = C;217    loc = Loc;218    this->A = A;219  }220};221 222struct IBOutletCollectionInfo : public AttrInfo {223  EntityInfo ClassInfo;224  CXIdxIBOutletCollectionAttrInfo IBCollInfo;225 226  IBOutletCollectionInfo(CXCursor C, CXIdxLoc Loc, const Attr *A) :227    AttrInfo(CXIdxAttr_IBOutletCollection, C, Loc, A) {228    assert(C.kind == CXCursor_IBOutletCollectionAttr);229    IBCollInfo.objcClass = nullptr;230  }231 232  IBOutletCollectionInfo(const IBOutletCollectionInfo &other);233 234  static bool classof(const AttrInfo *A) {235    return A->kind == CXIdxAttr_IBOutletCollection;236  }237};238 239class 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;249public:250  AttrListInfo(const Decl *D, CXIndexDataConsumer &IdxCtx);251 252  static IntrusiveRefCntPtr<AttrListInfo> create(const Decl *D,253                                                 CXIndexDataConsumer &IdxCtx);254 255  const CXIdxAttrInfo *const *getAttrs() const {256    if (CXAttrs.empty())257      return nullptr;258    return CXAttrs.data();259  }260  unsigned getNumAttrs() const { return (unsigned)CXAttrs.size(); }261 262  /// Retain/Release only useful when we allocate a AttrListInfo from the263  /// BumpPtrAllocator, and not from the stack; so that we keep a pointer264  // in the EntityInfo265  void Retain() { ++ref_cnt; }266  void Release() {267    assert (ref_cnt > 0 && "Reference count is already zero.");268    if (--ref_cnt == 0) {269      // Memory is allocated from a BumpPtrAllocator, no need to delete it.270      this->~AttrListInfo();271    }272  }273};274 275class 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    CXIdxObjCProtocolRefListInfo getListInfo() const {304      CXIdxObjCProtocolRefListInfo Info = { Prots.data(),305                                            (unsigned)Prots.size() };306      return Info;307    }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    const CXIdxBaseClassInfo *const *getBases() const {320      return CXBases.data();321    }322    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 333public:334  CXIndexDataConsumer(CXClientData clientData, IndexerCallbacks &indexCallbacks,335                      unsigned indexOptions, CXTranslationUnit cxTU)336      : Ctx(nullptr), ClientData(clientData), CB(indexCallbacks),337        IndexOptions(indexOptions), CXTU(cxTU), StrAdapterCount(0) {}338 339  ASTContext &getASTContext() const { return *Ctx; }340  CXTranslationUnit getCXTU() const { return CXTU; }341 342  void setASTContext(llvm::IntrusiveRefCntPtr<ASTContext> ctx);343  void setPreprocessor(std::shared_ptr<Preprocessor> PP) override;344 345  bool shouldSuppressRefs() const {346    return IndexOptions & CXIndexOpt_SuppressRedundantRefs;347  }348 349  bool shouldIndexFunctionLocalSymbols() const {350    return IndexOptions & CXIndexOpt_IndexFunctionLocalSymbols;351  }352 353  bool shouldIndexImplicitTemplateInsts() const {354    return IndexOptions & CXIndexOpt_IndexImplicitTemplateInstantiations;355  }356 357  static bool isFunctionLocalDecl(const Decl *D);358 359  bool shouldAbort();360 361  bool hasDiagnosticCallback() const { return CB.diagnostic; }362 363  void enteredMainFile(OptionalFileEntryRef File);364 365  void ppIncludedFile(SourceLocation hashLoc, StringRef filename,366                      OptionalFileEntryRef File, bool isImport, bool isAngled,367                      bool isModuleImport);368 369  void importedModule(const ImportDecl *ImportD);370  void importedPCH(FileEntryRef File);371 372  void startedTranslationUnit();373 374  void indexDiagnostics();375 376  void handleDiagnosticSet(CXDiagnosticSet CXDiagSet);377 378  bool handleFunction(const FunctionDecl *FD);379 380  bool handleVar(const VarDecl *D);381 382  bool handleField(const FieldDecl *D);383 384  bool handleEnumerator(const EnumConstantDecl *D);385 386  bool handleTagDecl(const TagDecl *D);387  388  bool handleTypedefName(const TypedefNameDecl *D);389 390  bool handleObjCInterface(const ObjCInterfaceDecl *D);391  bool handleObjCImplementation(const ObjCImplementationDecl *D);392 393  bool handleObjCProtocol(const ObjCProtocolDecl *D);394 395  bool handleObjCCategory(const ObjCCategoryDecl *D);396  bool handleObjCCategoryImpl(const ObjCCategoryImplDecl *D);397 398  bool handleObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc);399 400  bool handleSynthesizedObjCProperty(const ObjCPropertyImplDecl *D);401  bool handleSynthesizedObjCMethod(const ObjCMethodDecl *D, SourceLocation Loc,402                                   const DeclContext *LexicalDC);403 404  bool handleObjCProperty(const ObjCPropertyDecl *D);405 406  bool handleNamespace(const NamespaceDecl *D);407 408  bool handleClassTemplate(const ClassTemplateDecl *D);409  bool handleFunctionTemplate(const FunctionTemplateDecl *D);410  bool handleTypeAliasTemplate(const TypeAliasTemplateDecl *D);411 412  bool handleConcept(const ConceptDecl *D);413 414  bool handleReference(const NamedDecl *D, SourceLocation Loc, CXCursor Cursor,415                       const NamedDecl *Parent,416                       const DeclContext *DC,417                       const Expr *E = nullptr,418                       CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct,419                       CXSymbolRole Role = CXSymbolRole_None);420 421  bool isNotFromSourceFile(SourceLocation Loc) const;422 423  void translateLoc(SourceLocation Loc, CXIdxClientFile *indexFile, CXFile *file,424                    unsigned *line, unsigned *column, unsigned *offset);425 426  CXIdxClientContainer getClientContainerForDC(const DeclContext *DC) const;427  void addContainerInMap(const DeclContext *DC, CXIdxClientContainer container);428 429  CXIdxClientEntity getClientEntity(const Decl *D) const;430  void setClientEntity(const Decl *D, CXIdxClientEntity client);431 432  static bool isTemplateImplicitInstantiation(const Decl *D);433 434private:435  bool handleDeclOccurrence(const Decl *D, index::SymbolRoleSet Roles,436                            ArrayRef<index::SymbolRelation> Relations,437                            SourceLocation Loc, ASTNodeInfo ASTNode) override;438 439  bool handleModuleOccurrence(const ImportDecl *ImportD, const Module *Mod,440                              index::SymbolRoleSet Roles,441                              SourceLocation Loc) override;442 443  void finish() override;444 445  bool handleDecl(const NamedDecl *D,446                  SourceLocation Loc, CXCursor Cursor,447                  DeclInfo &DInfo,448                  const DeclContext *LexicalDC = nullptr,449                  const DeclContext *SemaDC = nullptr);450 451  bool handleObjCContainer(const ObjCContainerDecl *D,452                           SourceLocation Loc, CXCursor Cursor,453                           ObjCContainerDeclInfo &ContDInfo);454 455  bool handleCXXRecordDecl(const CXXRecordDecl *RD, const NamedDecl *OrigD);456 457  bool markEntityOccurrenceInFile(const NamedDecl *D, SourceLocation Loc);458 459  const NamedDecl *getEntityDecl(const NamedDecl *D) const;460 461  const DeclContext *getEntityContainer(const Decl *D) const;462 463  CXIdxClientFile getIndexFile(OptionalFileEntryRef File);464 465  CXIdxLoc getIndexLoc(SourceLocation Loc) const;466 467  void getEntityInfo(const NamedDecl *D,468                     EntityInfo &EntityInfo,469                     ScratchAlloc &SA);470 471  void getContainerInfo(const DeclContext *DC, ContainerInfo &ContInfo);472 473  CXCursor getCursor(const Decl *D) {474    return cxcursor::MakeCXCursor(D, CXTU);475  }476 477  CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc);478 479  static bool shouldIgnoreIfImplicit(const Decl *D);480};481 482inline ScratchAlloc::ScratchAlloc(CXIndexDataConsumer &idxCtx) : IdxCtx(idxCtx) {483  ++IdxCtx.StrAdapterCount;484}485inline ScratchAlloc::ScratchAlloc(const ScratchAlloc &SA) : IdxCtx(SA.IdxCtx) {486  ++IdxCtx.StrAdapterCount;487}488 489inline ScratchAlloc::~ScratchAlloc() {490  --IdxCtx.StrAdapterCount;491  if (IdxCtx.StrAdapterCount == 0)492    IdxCtx.StrScratch.Reset();493}494 495template <typename T>496inline T *ScratchAlloc::allocate() {497  return IdxCtx.StrScratch.Allocate<T>();498}499 500}} // end clang::cxindex501 502#endif503