1308 lines · cpp
1//===- CXIndexDataConsumer.cpp - Index data consumer for libclang----------===//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#include "CXIndexDataConsumer.h"10#include "CIndexDiagnostic.h"11#include "CXFile.h"12#include "CXTranslationUnit.h"13#include "clang/AST/Attr.h"14#include "clang/AST/DeclCXX.h"15#include "clang/AST/DeclTemplate.h"16#include "clang/AST/DeclVisitor.h"17#include "clang/Frontend/ASTUnit.h"18#include "llvm/ADT/STLExtras.h"19 20using namespace clang;21using namespace clang::index;22using namespace cxindex;23using namespace cxcursor;24 25namespace {26class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {27 CXIndexDataConsumer &DataConsumer;28 SourceLocation DeclLoc;29 const DeclContext *LexicalDC;30 31public:32 IndexingDeclVisitor(CXIndexDataConsumer &dataConsumer, SourceLocation Loc,33 const DeclContext *lexicalDC)34 : DataConsumer(dataConsumer), DeclLoc(Loc), LexicalDC(lexicalDC) { }35 36 bool VisitFunctionDecl(const FunctionDecl *D) {37 DataConsumer.handleFunction(D);38 return true;39 }40 41 bool VisitVarDecl(const VarDecl *D) {42 DataConsumer.handleVar(D);43 return true;44 }45 46 bool VisitFieldDecl(const FieldDecl *D) {47 DataConsumer.handleField(D);48 return true;49 }50 51 bool VisitMSPropertyDecl(const MSPropertyDecl *D) {52 return true;53 }54 55 bool VisitEnumConstantDecl(const EnumConstantDecl *D) {56 DataConsumer.handleEnumerator(D);57 return true;58 }59 60 bool VisitTypedefNameDecl(const TypedefNameDecl *D) {61 DataConsumer.handleTypedefName(D);62 return true;63 }64 65 bool VisitTagDecl(const TagDecl *D) {66 DataConsumer.handleTagDecl(D);67 return true;68 }69 70 bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {71 DataConsumer.handleObjCInterface(D);72 return true;73 }74 75 bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {76 DataConsumer.handleObjCProtocol(D);77 return true;78 }79 80 bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {81 DataConsumer.handleObjCImplementation(D);82 return true;83 }84 85 bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {86 DataConsumer.handleObjCCategory(D);87 return true;88 }89 90 bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {91 DataConsumer.handleObjCCategoryImpl(D);92 return true;93 }94 95 bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {96 if (isa<ObjCImplDecl>(LexicalDC) && !D->isThisDeclarationADefinition())97 DataConsumer.handleSynthesizedObjCMethod(D, DeclLoc, LexicalDC);98 else99 DataConsumer.handleObjCMethod(D, DeclLoc);100 return true;101 }102 103 bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {104 DataConsumer.handleObjCProperty(D);105 return true;106 }107 108 bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {109 DataConsumer.handleSynthesizedObjCProperty(D);110 return true;111 }112 113 bool VisitNamespaceDecl(const NamespaceDecl *D) {114 DataConsumer.handleNamespace(D);115 return true;116 }117 118 bool VisitUsingDecl(const UsingDecl *D) {119 return true;120 }121 122 bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {123 return true;124 }125 126 bool VisitClassTemplateDecl(const ClassTemplateDecl *D) {127 DataConsumer.handleClassTemplate(D);128 return true;129 }130 131 bool VisitClassTemplateSpecializationDecl(const132 ClassTemplateSpecializationDecl *D) {133 DataConsumer.handleTagDecl(D);134 return true;135 }136 137 bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {138 DataConsumer.handleFunctionTemplate(D);139 return true;140 }141 142 bool VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {143 DataConsumer.handleTypeAliasTemplate(D);144 return true;145 }146 147 bool VisitImportDecl(const ImportDecl *D) {148 DataConsumer.importedModule(D);149 return true;150 }151 152 bool VisitConceptDecl(const ConceptDecl *D) {153 DataConsumer.handleConcept(D);154 return true;155 }156};157 158CXSymbolRole getSymbolRole(SymbolRoleSet Role) {159 // CXSymbolRole mirrors low 9 bits of clang::index::SymbolRole.160 return CXSymbolRole(static_cast<uint32_t>(Role) & ((1 << 9) - 1));161}162}163 164bool CXIndexDataConsumer::handleDeclOccurrence(165 const Decl *D, SymbolRoleSet Roles, ArrayRef<SymbolRelation> Relations,166 SourceLocation Loc, ASTNodeInfo ASTNode) {167 Loc = getASTContext().getSourceManager().getFileLoc(Loc);168 169 if (Roles & (unsigned)SymbolRole::Reference) {170 const NamedDecl *ND = dyn_cast<NamedDecl>(D);171 if (!ND)172 return true;173 174 if (auto *ObjCID = dyn_cast_or_null<ObjCInterfaceDecl>(ASTNode.OrigD)) {175 if (!ObjCID->isThisDeclarationADefinition() &&176 ObjCID->getLocation() == Loc) {177 // The libclang API treats this as ObjCClassRef declaration.178 IndexingDeclVisitor(*this, Loc, nullptr).Visit(ObjCID);179 return true;180 }181 }182 if (auto *ObjCPD = dyn_cast_or_null<ObjCProtocolDecl>(ASTNode.OrigD)) {183 if (!ObjCPD->isThisDeclarationADefinition() &&184 ObjCPD->getLocation() == Loc) {185 // The libclang API treats this as ObjCProtocolRef declaration.186 IndexingDeclVisitor(*this, Loc, nullptr).Visit(ObjCPD);187 return true;188 }189 }190 191 CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct;192 if (Roles & (unsigned)SymbolRole::Implicit) {193 Kind = CXIdxEntityRef_Implicit;194 }195 CXSymbolRole CXRole = getSymbolRole(Roles);196 197 CXCursor Cursor;198 if (ASTNode.OrigE) {199 Cursor = cxcursor::MakeCXCursor(ASTNode.OrigE,200 cast<Decl>(ASTNode.ContainerDC),201 getCXTU());202 } else {203 if (ASTNode.OrigD) {204 if (auto *OrigND = dyn_cast<NamedDecl>(ASTNode.OrigD))205 Cursor = getRefCursor(OrigND, Loc);206 else207 Cursor = MakeCXCursor(ASTNode.OrigD, CXTU);208 } else {209 Cursor = getRefCursor(ND, Loc);210 }211 }212 handleReference(ND, Loc, Cursor,213 dyn_cast_or_null<NamedDecl>(ASTNode.Parent),214 ASTNode.ContainerDC, ASTNode.OrigE, Kind, CXRole);215 216 } else {217 const DeclContext *LexicalDC = ASTNode.ContainerDC;218 if (!LexicalDC) {219 for (const auto &SymRel : Relations) {220 if (SymRel.Roles & (unsigned)SymbolRole::RelationChildOf)221 LexicalDC = dyn_cast<DeclContext>(SymRel.RelatedSymbol);222 }223 }224 IndexingDeclVisitor(*this, Loc, LexicalDC).Visit(ASTNode.OrigD);225 }226 227 return !shouldAbort();228}229 230bool CXIndexDataConsumer::handleModuleOccurrence(const ImportDecl *ImportD,231 const Module *Mod,232 SymbolRoleSet Roles,233 SourceLocation Loc) {234 if (Roles & (SymbolRoleSet)SymbolRole::Declaration)235 IndexingDeclVisitor(*this, SourceLocation(), nullptr).Visit(ImportD);236 return !shouldAbort();237}238 239void CXIndexDataConsumer::finish() {240 indexDiagnostics();241}242 243 244CXIndexDataConsumer::ObjCProtocolListInfo::ObjCProtocolListInfo(245 const ObjCProtocolList &ProtList,246 CXIndexDataConsumer &IdxCtx,247 ScratchAlloc &SA) {248 ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();249 for (ObjCInterfaceDecl::protocol_iterator250 I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {251 SourceLocation Loc = *LI;252 ObjCProtocolDecl *PD = *I;253 ProtEntities.push_back(EntityInfo());254 IdxCtx.getEntityInfo(PD, ProtEntities.back(), SA);255 CXIdxObjCProtocolRefInfo ProtInfo = { nullptr,256 MakeCursorObjCProtocolRef(PD, Loc, IdxCtx.CXTU),257 IdxCtx.getIndexLoc(Loc) };258 ProtInfos.push_back(ProtInfo);259 260 if (IdxCtx.shouldSuppressRefs())261 IdxCtx.markEntityOccurrenceInFile(PD, Loc);262 }263 264 for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)265 ProtInfos[i].protocol = &ProtEntities[i];266 267 for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)268 Prots.push_back(&ProtInfos[i]);269}270 271 272IBOutletCollectionInfo::IBOutletCollectionInfo(273 const IBOutletCollectionInfo &other)274 : AttrInfo(CXIdxAttr_IBOutletCollection, other.cursor, other.loc, other.A) {275 276 IBCollInfo.attrInfo = this;277 IBCollInfo.classCursor = other.IBCollInfo.classCursor;278 IBCollInfo.classLoc = other.IBCollInfo.classLoc;279 if (other.IBCollInfo.objcClass) {280 ClassInfo = other.ClassInfo;281 IBCollInfo.objcClass = &ClassInfo;282 } else283 IBCollInfo.objcClass = nullptr;284}285 286AttrListInfo::AttrListInfo(const Decl *D, CXIndexDataConsumer &IdxCtx)287 : SA(IdxCtx), ref_cnt(0) {288 289 if (!D->hasAttrs())290 return;291 292 for (const auto *A : D->attrs()) {293 CXCursor C = MakeCXCursor(A, D, IdxCtx.CXTU);294 CXIdxLoc Loc = IdxCtx.getIndexLoc(A->getLocation());295 switch (C.kind) {296 default:297 Attrs.push_back(AttrInfo(CXIdxAttr_Unexposed, C, Loc, A));298 break;299 case CXCursor_IBActionAttr:300 Attrs.push_back(AttrInfo(CXIdxAttr_IBAction, C, Loc, A));301 break;302 case CXCursor_IBOutletAttr:303 Attrs.push_back(AttrInfo(CXIdxAttr_IBOutlet, C, Loc, A));304 break;305 case CXCursor_IBOutletCollectionAttr:306 IBCollAttrs.push_back(IBOutletCollectionInfo(C, Loc, A));307 break;308 }309 }310 311 for (unsigned i = 0, e = IBCollAttrs.size(); i != e; ++i) {312 IBOutletCollectionInfo &IBInfo = IBCollAttrs[i];313 CXAttrs.push_back(&IBInfo);314 315 const IBOutletCollectionAttr *316 IBAttr = cast<IBOutletCollectionAttr>(IBInfo.A);317 SourceLocation InterfaceLocStart =318 IBAttr->getInterfaceLoc()->getTypeLoc().getBeginLoc();319 IBInfo.IBCollInfo.attrInfo = &IBInfo;320 IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(InterfaceLocStart);321 IBInfo.IBCollInfo.objcClass = nullptr;322 IBInfo.IBCollInfo.classCursor = clang_getNullCursor();323 QualType Ty = IBAttr->getInterface();324 if (const ObjCObjectType *ObjectTy = Ty->getAs<ObjCObjectType>()) {325 if (const ObjCInterfaceDecl *InterD = ObjectTy->getInterface()) {326 IdxCtx.getEntityInfo(InterD, IBInfo.ClassInfo, SA);327 IBInfo.IBCollInfo.objcClass = &IBInfo.ClassInfo;328 IBInfo.IBCollInfo.classCursor =329 MakeCursorObjCClassRef(InterD, InterfaceLocStart, IdxCtx.CXTU);330 }331 }332 }333 334 for (unsigned i = 0, e = Attrs.size(); i != e; ++i)335 CXAttrs.push_back(&Attrs[i]);336}337 338IntrusiveRefCntPtr<AttrListInfo>339AttrListInfo::create(const Decl *D, CXIndexDataConsumer &IdxCtx) {340 ScratchAlloc SA(IdxCtx);341 AttrListInfo *attrs = SA.allocate<AttrListInfo>();342 return new (attrs) AttrListInfo(D, IdxCtx);343}344 345CXIndexDataConsumer::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,346 CXIndexDataConsumer &IdxCtx,347 ScratchAlloc &SA) {348 for (const auto &Base : D->bases()) {349 BaseEntities.push_back(EntityInfo());350 const NamedDecl *BaseD = nullptr;351 QualType T = Base.getType();352 SourceLocation Loc = getBaseLoc(Base);353 354 if (const TypedefType *TDT = T->getAs<TypedefType>()) {355 BaseD = TDT->getDecl();356 } else if (const TemplateSpecializationType *357 TST = T->getAs<TemplateSpecializationType>()) {358 BaseD = TST->getTemplateName().getAsTemplateDecl();359 } else if (const RecordType *RT = T->getAs<RecordType>()) {360 BaseD = RT->getDecl();361 }362 363 if (BaseD)364 IdxCtx.getEntityInfo(BaseD, BaseEntities.back(), SA);365 CXIdxBaseClassInfo BaseInfo = { nullptr,366 MakeCursorCXXBaseSpecifier(&Base, IdxCtx.CXTU),367 IdxCtx.getIndexLoc(Loc) };368 BaseInfos.push_back(BaseInfo);369 }370 371 for (unsigned i = 0, e = BaseInfos.size(); i != e; ++i) {372 if (BaseEntities[i].name && BaseEntities[i].USR)373 BaseInfos[i].base = &BaseEntities[i];374 }375 376 for (unsigned i = 0, e = BaseInfos.size(); i != e; ++i)377 CXBases.push_back(&BaseInfos[i]);378}379 380SourceLocation CXIndexDataConsumer::CXXBasesListInfo::getBaseLoc(381 const CXXBaseSpecifier &Base) const {382 SourceLocation Loc = Base.getSourceRange().getBegin();383 TypeLoc TL;384 if (Base.getTypeSourceInfo())385 TL = Base.getTypeSourceInfo()->getTypeLoc();386 if (TL.isNull())387 return Loc;388 389 if (QualifiedTypeLoc QL = TL.getAs<QualifiedTypeLoc>())390 TL = QL.getUnqualifiedLoc();391 392 // FIXME: Factor this out, a lot of TypeLoc users seem to need a generic393 // TypeLoc::getNameLoc()394 if (auto TTL = TL.getAs<DependentNameTypeLoc>())395 return TTL.getNameLoc();396 if (auto TTL = TL.getAs<TemplateSpecializationTypeLoc>())397 return TTL.getTemplateNameLoc();398 if (auto TTL = TL.getAs<TagTypeLoc>())399 return TTL.getNameLoc();400 if (auto TTL = TL.getAs<TypedefTypeLoc>())401 return TTL.getNameLoc();402 if (auto TTL = TL.getAs<UnresolvedUsingTypeLoc>())403 return TTL.getNameLoc();404 if (auto TTL = TL.getAs<UsingTypeLoc>())405 return TTL.getNameLoc();406 407 return Loc;408}409 410const char *ScratchAlloc::toCStr(StringRef Str) {411 if (Str.empty())412 return "";413 if (Str.data()[Str.size()] == '\0')414 return Str.data();415 return copyCStr(Str);416}417 418const char *ScratchAlloc::copyCStr(StringRef Str) {419 char *buf = IdxCtx.StrScratch.Allocate<char>(Str.size() + 1);420 llvm::uninitialized_copy(Str, buf);421 buf[Str.size()] = '\0';422 return buf;423}424 425void CXIndexDataConsumer::setASTContext(IntrusiveRefCntPtr<ASTContext> ctx) {426 Ctx = ctx.get();427 cxtu::getASTUnit(CXTU)->setASTContext(std::move(ctx));428}429 430void CXIndexDataConsumer::setPreprocessor(std::shared_ptr<Preprocessor> PP) {431 cxtu::getASTUnit(CXTU)->setPreprocessor(std::move(PP));432}433 434bool CXIndexDataConsumer::isFunctionLocalDecl(const Decl *D) {435 assert(D);436 437 if (!D->getParentFunctionOrMethod())438 return false;439 440 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {441 switch (ND->getFormalLinkage()) {442 case Linkage::Invalid:443 llvm_unreachable("Linkage hasn't been computed!");444 case Linkage::None:445 case Linkage::Internal:446 return true;447 case Linkage::VisibleNone:448 case Linkage::UniqueExternal:449 llvm_unreachable("Not a sema linkage");450 case Linkage::Module:451 case Linkage::External:452 return false;453 }454 }455 456 return true;457}458 459bool CXIndexDataConsumer::shouldAbort() {460 if (!CB.abortQuery)461 return false;462 return CB.abortQuery(ClientData, nullptr);463}464 465void CXIndexDataConsumer::enteredMainFile(OptionalFileEntryRef File) {466 if (File && CB.enteredMainFile) {467 CXIdxClientFile idxFile =468 CB.enteredMainFile(ClientData, cxfile::makeCXFile(*File), nullptr);469 FileMap[*File] = idxFile;470 }471}472 473void CXIndexDataConsumer::ppIncludedFile(SourceLocation hashLoc,474 StringRef filename,475 OptionalFileEntryRef File,476 bool isImport, bool isAngled,477 bool isModuleImport) {478 if (!CB.ppIncludedFile)479 return;480 481 const FileEntry *FE = File ? &File->getFileEntry() : nullptr;482 483 ScratchAlloc SA(*this);484 CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),485 SA.toCStr(filename),486 cxfile::makeCXFile(File),487 isImport, isAngled, isModuleImport };488 CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info);489 FileMap[FE] = idxFile;490}491 492void CXIndexDataConsumer::importedModule(const ImportDecl *ImportD) {493 if (!CB.importedASTFile)494 return;495 496 Module *Mod = ImportD->getImportedModule();497 if (!Mod)498 return;499 500 // If the imported module is part of the top-level module that we're501 // indexing, it doesn't correspond to an imported AST file.502 // FIXME: This assumes that AST files and top-level modules directly503 // correspond, which is unlikely to remain true forever.504 if (Module *SrcMod = ImportD->getImportedOwningModule())505 if (SrcMod->getTopLevelModule() == Mod->getTopLevelModule())506 return;507 508 OptionalFileEntryRef FE = Mod->getASTFile();509 CXIdxImportedASTFileInfo Info = {cxfile::makeCXFile(FE), Mod,510 getIndexLoc(ImportD->getLocation()),511 ImportD->isImplicit()};512 CXIdxClientASTFile astFile = CB.importedASTFile(ClientData, &Info);513 (void)astFile;514}515 516void CXIndexDataConsumer::importedPCH(FileEntryRef File) {517 if (!CB.importedASTFile)518 return;519 520 CXIdxImportedASTFileInfo Info = {521 cxfile::makeCXFile(File),522 /*module=*/nullptr,523 getIndexLoc(SourceLocation()),524 /*isImplicit=*/false525 };526 CXIdxClientASTFile astFile = CB.importedASTFile(ClientData, &Info);527 (void)astFile;528}529 530void CXIndexDataConsumer::startedTranslationUnit() {531 CXIdxClientContainer idxCont = nullptr;532 if (CB.startedTranslationUnit)533 idxCont = CB.startedTranslationUnit(ClientData, nullptr);534 addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);535}536 537void CXIndexDataConsumer::indexDiagnostics() {538 if (!hasDiagnosticCallback())539 return;540 541 CXDiagnosticSetImpl *DiagSet = cxdiag::lazyCreateDiags(getCXTU());542 handleDiagnosticSet(DiagSet);543}544 545void CXIndexDataConsumer::handleDiagnosticSet(CXDiagnostic CXDiagSet) {546 if (!CB.diagnostic)547 return;548 549 CB.diagnostic(ClientData, CXDiagSet, nullptr);550}551 552bool CXIndexDataConsumer::handleDecl(const NamedDecl *D,553 SourceLocation Loc, CXCursor Cursor,554 DeclInfo &DInfo,555 const DeclContext *LexicalDC,556 const DeclContext *SemaDC) {557 if (!CB.indexDeclaration || !D)558 return false;559 if (D->isImplicit() && shouldIgnoreIfImplicit(D))560 return false;561 562 ScratchAlloc SA(*this);563 getEntityInfo(D, DInfo.EntInfo, SA);564 if ((!shouldIndexFunctionLocalSymbols() && !DInfo.EntInfo.USR)565 || Loc.isInvalid())566 return false;567 568 if (!LexicalDC)569 LexicalDC = D->getLexicalDeclContext();570 571 if (shouldSuppressRefs())572 markEntityOccurrenceInFile(D, Loc);573 574 DInfo.entityInfo = &DInfo.EntInfo;575 DInfo.cursor = Cursor;576 DInfo.loc = getIndexLoc(Loc);577 DInfo.isImplicit = D->isImplicit();578 579 DInfo.attributes = DInfo.EntInfo.attributes;580 DInfo.numAttributes = DInfo.EntInfo.numAttributes;581 582 if (!SemaDC)583 SemaDC = D->getDeclContext();584 getContainerInfo(SemaDC, DInfo.SemanticContainer);585 DInfo.semanticContainer = &DInfo.SemanticContainer;586 587 if (LexicalDC == SemaDC) {588 DInfo.lexicalContainer = &DInfo.SemanticContainer;589 } else if (isTemplateImplicitInstantiation(D)) {590 // Implicit instantiations have the lexical context of where they were591 // instantiated first. We choose instead the semantic context because:592 // 1) at the time that we see the instantiation we have not seen the593 // function where it occurred yet.594 // 2) the lexical context of the first instantiation is not useful595 // information anyway.596 DInfo.lexicalContainer = &DInfo.SemanticContainer;597 } else {598 getContainerInfo(LexicalDC, DInfo.LexicalContainer);599 DInfo.lexicalContainer = &DInfo.LexicalContainer;600 }601 602 if (DInfo.isContainer) {603 getContainerInfo(getEntityContainer(D), DInfo.DeclAsContainer);604 DInfo.declAsContainer = &DInfo.DeclAsContainer;605 }606 607 CB.indexDeclaration(ClientData, &DInfo);608 return true;609}610 611bool CXIndexDataConsumer::handleObjCContainer(const ObjCContainerDecl *D,612 SourceLocation Loc, CXCursor Cursor,613 ObjCContainerDeclInfo &ContDInfo) {614 ContDInfo.ObjCContDeclInfo.declInfo = &ContDInfo;615 return handleDecl(D, Loc, Cursor, ContDInfo);616}617 618bool CXIndexDataConsumer::handleFunction(const FunctionDecl *D) {619 bool isDef = D->isThisDeclarationADefinition();620 bool isContainer = isDef;621 bool isSkipped = false;622 if (D->hasSkippedBody()) {623 isSkipped = true;624 isDef = true;625 isContainer = false;626 }627 628 DeclInfo DInfo(!D->isFirstDecl(), isDef, isContainer);629 if (isSkipped)630 DInfo.flags |= CXIdxDeclFlag_Skipped;631 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);632}633 634bool CXIndexDataConsumer::handleVar(const VarDecl *D) {635 DeclInfo DInfo(!D->isFirstDecl(), D->isThisDeclarationADefinition(),636 /*isContainer=*/false);637 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);638}639 640bool CXIndexDataConsumer::handleField(const FieldDecl *D) {641 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,642 /*isContainer=*/false);643 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);644}645 646bool CXIndexDataConsumer::handleEnumerator(const EnumConstantDecl *D) {647 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,648 /*isContainer=*/false);649 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);650}651 652bool CXIndexDataConsumer::handleTagDecl(const TagDecl *D) {653 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(D))654 return handleCXXRecordDecl(CXXRD, D);655 656 DeclInfo DInfo(!D->isFirstDecl(), D->isThisDeclarationADefinition(),657 D->isThisDeclarationADefinition());658 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);659}660 661bool CXIndexDataConsumer::handleTypedefName(const TypedefNameDecl *D) {662 DeclInfo DInfo(!D->isFirstDecl(), /*isDefinition=*/true,663 /*isContainer=*/false);664 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);665}666 667bool CXIndexDataConsumer::handleObjCInterface(const ObjCInterfaceDecl *D) {668 // For @class forward declarations, suppress them the same way as references.669 if (!D->isThisDeclarationADefinition()) {670 if (shouldSuppressRefs() && markEntityOccurrenceInFile(D, D->getLocation()))671 return false; // already occurred.672 673 // FIXME: This seems like the wrong definition for redeclaration.674 bool isRedeclaration = D->hasDefinition() || D->getPreviousDecl();675 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true, isRedeclaration,676 /*isImplementation=*/false);677 return handleObjCContainer(D, D->getLocation(),678 MakeCursorObjCClassRef(D, D->getLocation(),679 CXTU), 680 ContDInfo);681 }682 683 ScratchAlloc SA(*this);684 685 CXIdxBaseClassInfo BaseClass;686 EntityInfo BaseEntity;687 BaseClass.cursor = clang_getNullCursor();688 if (ObjCInterfaceDecl *SuperD = D->getSuperClass()) {689 getEntityInfo(SuperD, BaseEntity, SA);690 SourceLocation SuperLoc = D->getSuperClassLoc();691 BaseClass.base = &BaseEntity;692 BaseClass.cursor = MakeCursorObjCSuperClassRef(SuperD, SuperLoc, CXTU);693 BaseClass.loc = getIndexLoc(SuperLoc);694 695 if (shouldSuppressRefs())696 markEntityOccurrenceInFile(SuperD, SuperLoc);697 }698 699 ObjCProtocolList EmptyProtoList;700 ObjCProtocolListInfo ProtInfo(D->isThisDeclarationADefinition() 701 ? D->getReferencedProtocols()702 : EmptyProtoList, 703 *this, SA);704 705 ObjCInterfaceDeclInfo InterInfo(D);706 InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();707 InterInfo.ObjCInterDeclInfo.containerInfo = &InterInfo.ObjCContDeclInfo;708 InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass709 : nullptr;710 InterInfo.ObjCInterDeclInfo.protocols = &InterInfo.ObjCProtoListInfo;711 712 return handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);713}714 715bool CXIndexDataConsumer::handleObjCImplementation(716 const ObjCImplementationDecl *D) {717 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/false,718 /*isRedeclaration=*/true,719 /*isImplementation=*/true);720 return handleObjCContainer(D, D->getLocation(), getCursor(D), ContDInfo);721}722 723bool CXIndexDataConsumer::handleObjCProtocol(const ObjCProtocolDecl *D) {724 if (!D->isThisDeclarationADefinition()) {725 if (shouldSuppressRefs() && markEntityOccurrenceInFile(D, D->getLocation()))726 return false; // already occurred.727 728 // FIXME: This seems like the wrong definition for redeclaration.729 bool isRedeclaration = D->hasDefinition() || D->getPreviousDecl();730 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true,731 isRedeclaration,732 /*isImplementation=*/false);733 return handleObjCContainer(D, D->getLocation(), 734 MakeCursorObjCProtocolRef(D, D->getLocation(),735 CXTU),736 ContDInfo); 737 }738 739 ScratchAlloc SA(*this);740 ObjCProtocolList EmptyProtoList;741 ObjCProtocolListInfo ProtListInfo(D->isThisDeclarationADefinition()742 ? D->getReferencedProtocols()743 : EmptyProtoList,744 *this, SA);745 746 ObjCProtocolDeclInfo ProtInfo(D);747 ProtInfo.ObjCProtoRefListInfo = ProtListInfo.getListInfo();748 749 return handleObjCContainer(D, D->getLocation(), getCursor(D), ProtInfo);750}751 752bool CXIndexDataConsumer::handleObjCCategory(const ObjCCategoryDecl *D) {753 ScratchAlloc SA(*this);754 755 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);756 EntityInfo ClassEntity;757 const ObjCInterfaceDecl *IFaceD = D->getClassInterface();758 SourceLocation ClassLoc = D->getLocation();759 SourceLocation CategoryLoc = D->IsClassExtension() ? ClassLoc760 : D->getCategoryNameLoc();761 getEntityInfo(IFaceD, ClassEntity, SA);762 763 if (shouldSuppressRefs())764 markEntityOccurrenceInFile(IFaceD, ClassLoc);765 766 ObjCProtocolListInfo ProtInfo(D->getReferencedProtocols(), *this, SA);767 768 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;769 if (IFaceD) {770 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;771 CatDInfo.ObjCCatDeclInfo.classCursor =772 MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);773 } else {774 CatDInfo.ObjCCatDeclInfo.objcClass = nullptr;775 CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();776 }777 CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);778 CatDInfo.ObjCProtoListInfo = ProtInfo.getListInfo();779 CatDInfo.ObjCCatDeclInfo.protocols = &CatDInfo.ObjCProtoListInfo;780 781 return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);782}783 784bool CXIndexDataConsumer::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {785 ScratchAlloc SA(*this);786 787 const ObjCCategoryDecl *CatD = D->getCategoryDecl();788 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);789 EntityInfo ClassEntity;790 const ObjCInterfaceDecl *IFaceD = CatD->getClassInterface();791 SourceLocation ClassLoc = D->getLocation();792 SourceLocation CategoryLoc = D->getCategoryNameLoc();793 getEntityInfo(IFaceD, ClassEntity, SA);794 795 if (shouldSuppressRefs())796 markEntityOccurrenceInFile(IFaceD, ClassLoc);797 798 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;799 if (IFaceD) {800 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;801 CatDInfo.ObjCCatDeclInfo.classCursor =802 MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);803 } else {804 CatDInfo.ObjCCatDeclInfo.objcClass = nullptr;805 CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();806 }807 CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);808 CatDInfo.ObjCCatDeclInfo.protocols = nullptr;809 810 return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);811}812 813bool CXIndexDataConsumer::handleObjCMethod(const ObjCMethodDecl *D,814 SourceLocation Loc) {815 bool isDef = D->isThisDeclarationADefinition();816 bool isContainer = isDef;817 bool isSkipped = false;818 if (D->hasSkippedBody()) {819 isSkipped = true;820 isDef = true;821 isContainer = false;822 }823 824 DeclInfo DInfo(!D->isCanonicalDecl(), isDef, isContainer);825 if (isSkipped)826 DInfo.flags |= CXIdxDeclFlag_Skipped;827 return handleDecl(D, Loc, getCursor(D), DInfo);828}829 830bool CXIndexDataConsumer::handleSynthesizedObjCProperty(831 const ObjCPropertyImplDecl *D) {832 ObjCPropertyDecl *PD = D->getPropertyDecl();833 auto *DC = D->getDeclContext();834 return handleReference(PD, D->getLocation(), getCursor(D),835 dyn_cast<NamedDecl>(DC), DC);836}837 838bool CXIndexDataConsumer::handleSynthesizedObjCMethod(const ObjCMethodDecl *D,839 SourceLocation Loc,840 const DeclContext *LexicalDC) {841 DeclInfo DInfo(/*isRedeclaration=*/true, /*isDefinition=*/true,842 /*isContainer=*/false);843 return handleDecl(D, Loc, getCursor(D), DInfo, LexicalDC, D->getDeclContext());844}845 846bool CXIndexDataConsumer::handleObjCProperty(const ObjCPropertyDecl *D) {847 ScratchAlloc SA(*this);848 849 ObjCPropertyDeclInfo DInfo;850 EntityInfo GetterEntity;851 EntityInfo SetterEntity;852 853 DInfo.ObjCPropDeclInfo.declInfo = &DInfo;854 855 if (ObjCMethodDecl *Getter = D->getGetterMethodDecl()) {856 getEntityInfo(Getter, GetterEntity, SA);857 DInfo.ObjCPropDeclInfo.getter = &GetterEntity;858 } else {859 DInfo.ObjCPropDeclInfo.getter = nullptr;860 }861 if (ObjCMethodDecl *Setter = D->getSetterMethodDecl()) {862 getEntityInfo(Setter, SetterEntity, SA);863 DInfo.ObjCPropDeclInfo.setter = &SetterEntity;864 } else {865 DInfo.ObjCPropDeclInfo.setter = nullptr;866 }867 868 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);869}870 871bool CXIndexDataConsumer::handleNamespace(const NamespaceDecl *D) {872 DeclInfo DInfo(/*isRedeclaration=*/!D->isFirstDecl(),873 /*isDefinition=*/true,874 /*isContainer=*/true);875 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);876}877 878bool CXIndexDataConsumer::handleClassTemplate(const ClassTemplateDecl *D) {879 return handleCXXRecordDecl(D->getTemplatedDecl(), D);880}881 882bool CXIndexDataConsumer::handleFunctionTemplate(const FunctionTemplateDecl *D) {883 DeclInfo DInfo(/*isRedeclaration=*/!D->isCanonicalDecl(),884 /*isDefinition=*/D->isThisDeclarationADefinition(),885 /*isContainer=*/D->isThisDeclarationADefinition());886 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);887}888 889bool CXIndexDataConsumer::handleTypeAliasTemplate(const TypeAliasTemplateDecl *D) {890 DeclInfo DInfo(/*isRedeclaration=*/!D->isCanonicalDecl(),891 /*isDefinition=*/true, /*isContainer=*/false);892 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);893}894 895bool CXIndexDataConsumer::handleConcept(const ConceptDecl *D) {896 DeclInfo DInfo(/*isRedeclaration=*/!D->isCanonicalDecl(),897 /*isDefinition=*/true, /*isContainer=*/false);898 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);899}900 901bool CXIndexDataConsumer::handleReference(const NamedDecl *D, SourceLocation Loc,902 CXCursor Cursor,903 const NamedDecl *Parent,904 const DeclContext *DC,905 const Expr *E,906 CXIdxEntityRefKind Kind,907 CXSymbolRole Role) {908 if (!CB.indexEntityReference)909 return false;910 911 if (!D || !DC)912 return false;913 if (Loc.isInvalid())914 return false;915 if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))916 return false;917 if (isNotFromSourceFile(D->getLocation()))918 return false;919 if (D->isImplicit() && shouldIgnoreIfImplicit(D))920 return false;921 922 if (shouldSuppressRefs()) {923 if (markEntityOccurrenceInFile(D, Loc))924 return false; // already occurred.925 }926 927 ScratchAlloc SA(*this);928 EntityInfo RefEntity, ParentEntity;929 getEntityInfo(D, RefEntity, SA);930 if (!RefEntity.USR)931 return false;932 933 getEntityInfo(Parent, ParentEntity, SA);934 935 ContainerInfo Container;936 getContainerInfo(DC, Container);937 938 CXIdxEntityRefInfo Info = { Kind,939 Cursor,940 getIndexLoc(Loc),941 &RefEntity,942 Parent ? &ParentEntity : nullptr,943 &Container,944 Role };945 CB.indexEntityReference(ClientData, &Info);946 return true;947}948 949bool CXIndexDataConsumer::isNotFromSourceFile(SourceLocation Loc) const {950 if (Loc.isInvalid())951 return true;952 SourceManager &SM = Ctx->getSourceManager();953 SourceLocation FileLoc = SM.getFileLoc(Loc);954 FileID FID = SM.getFileID(FileLoc);955 return SM.getFileEntryForID(FID) == nullptr;956}957 958void CXIndexDataConsumer::addContainerInMap(const DeclContext *DC,959 CXIdxClientContainer container) {960 if (!DC)961 return;962 963 // Allow changing the container of a previously seen DeclContext so we964 // can handle invalid user code, like a function re-definition.965 if (container)966 ContainerMap[DC] = container;967 else968 ContainerMap.erase(DC);969}970 971CXIdxClientEntity CXIndexDataConsumer::getClientEntity(const Decl *D) const {972 return D ? EntityMap.lookup(D) : nullptr;973}974 975void CXIndexDataConsumer::setClientEntity(const Decl *D, CXIdxClientEntity client) {976 if (!D)977 return;978 EntityMap[D] = client;979}980 981bool CXIndexDataConsumer::handleCXXRecordDecl(const CXXRecordDecl *RD,982 const NamedDecl *OrigD) {983 if (RD->isThisDeclarationADefinition()) {984 ScratchAlloc SA(*this);985 CXXClassDeclInfo CXXDInfo(/*isRedeclaration=*/!OrigD->isCanonicalDecl(),986 /*isDefinition=*/RD->isThisDeclarationADefinition());987 CXXBasesListInfo BaseList(RD, *this, SA);988 CXXDInfo.CXXClassInfo.declInfo = &CXXDInfo;989 CXXDInfo.CXXClassInfo.bases = BaseList.getBases();990 CXXDInfo.CXXClassInfo.numBases = BaseList.getNumBases();991 992 if (shouldSuppressRefs()) {993 // Go through bases and mark them as referenced.994 for (unsigned i = 0, e = BaseList.getNumBases(); i != e; ++i) {995 const CXIdxBaseClassInfo *baseInfo = BaseList.getBases()[i];996 if (baseInfo->base) {997 const NamedDecl *BaseD = BaseList.BaseEntities[i].Dcl;998 SourceLocation999 Loc = SourceLocation::getFromRawEncoding(baseInfo->loc.int_data);1000 markEntityOccurrenceInFile(BaseD, Loc);1001 }1002 }1003 }1004 1005 return handleDecl(OrigD, OrigD->getLocation(), getCursor(OrigD), CXXDInfo);1006 }1007 1008 DeclInfo DInfo(/*isRedeclaration=*/!OrigD->isCanonicalDecl(),1009 /*isDefinition=*/RD->isThisDeclarationADefinition(),1010 /*isContainer=*/RD->isThisDeclarationADefinition());1011 return handleDecl(OrigD, OrigD->getLocation(), getCursor(OrigD), DInfo);1012}1013 1014bool CXIndexDataConsumer::markEntityOccurrenceInFile(const NamedDecl *D,1015 SourceLocation Loc) {1016 if (!D || Loc.isInvalid())1017 return true;1018 1019 SourceManager &SM = Ctx->getSourceManager();1020 D = getEntityDecl(D);1021 1022 FileIDAndOffset LocInfo = SM.getDecomposedLoc(SM.getFileLoc(Loc));1023 FileID FID = LocInfo.first;1024 if (FID.isInvalid())1025 return true;1026 1027 const FileEntry *FE = SM.getFileEntryForID(FID);1028 if (!FE)1029 return true;1030 RefFileOccurrence RefOccur(FE, D);1031 std::pair<llvm::DenseSet<RefFileOccurrence>::iterator, bool>1032 res = RefFileOccurrences.insert(RefOccur);1033 return !res.second; // already in map1034}1035 1036const NamedDecl *CXIndexDataConsumer::getEntityDecl(const NamedDecl *D) const {1037 assert(D);1038 D = cast<NamedDecl>(D->getCanonicalDecl());1039 1040 if (const ObjCImplementationDecl *1041 ImplD = dyn_cast<ObjCImplementationDecl>(D)) {1042 return getEntityDecl(ImplD->getClassInterface());1043 1044 } else if (const ObjCCategoryImplDecl *1045 CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {1046 return getEntityDecl(CatImplD->getCategoryDecl());1047 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {1048 if (FunctionTemplateDecl *TemplD = FD->getDescribedFunctionTemplate())1049 return getEntityDecl(TemplD);1050 } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {1051 if (ClassTemplateDecl *TemplD = RD->getDescribedClassTemplate())1052 return getEntityDecl(TemplD);1053 }1054 1055 return D;1056}1057 1058const DeclContext *1059CXIndexDataConsumer::getEntityContainer(const Decl *D) const {1060 const DeclContext *DC = dyn_cast<DeclContext>(D);1061 if (DC)1062 return DC;1063 1064 if (const ClassTemplateDecl *ClassTempl = dyn_cast<ClassTemplateDecl>(D)) {1065 DC = ClassTempl->getTemplatedDecl();1066 } else if (const FunctionTemplateDecl *1067 FuncTempl = dyn_cast<FunctionTemplateDecl>(D)) {1068 DC = FuncTempl->getTemplatedDecl();1069 }1070 1071 return DC;1072}1073 1074CXIdxClientContainer1075CXIndexDataConsumer::getClientContainerForDC(const DeclContext *DC) const {1076 return DC ? ContainerMap.lookup(DC) : nullptr;1077}1078 1079CXIdxClientFile CXIndexDataConsumer::getIndexFile(OptionalFileEntryRef File) {1080 return File ? FileMap.lookup(*File) : nullptr;1081}1082 1083CXIdxLoc CXIndexDataConsumer::getIndexLoc(SourceLocation Loc) const {1084 CXIdxLoc idxLoc = { {nullptr, nullptr}, 0 };1085 if (Loc.isInvalid())1086 return idxLoc;1087 1088 idxLoc.ptr_data[0] = const_cast<CXIndexDataConsumer *>(this);1089 idxLoc.int_data = Loc.getRawEncoding();1090 return idxLoc;1091}1092 1093void CXIndexDataConsumer::translateLoc(SourceLocation Loc,1094 CXIdxClientFile *indexFile, CXFile *file,1095 unsigned *line, unsigned *column,1096 unsigned *offset) {1097 if (Loc.isInvalid())1098 return;1099 1100 SourceManager &SM = Ctx->getSourceManager();1101 Loc = SM.getFileLoc(Loc);1102 1103 FileIDAndOffset LocInfo = SM.getDecomposedLoc(Loc);1104 FileID FID = LocInfo.first;1105 unsigned FileOffset = LocInfo.second;1106 1107 if (FID.isInvalid())1108 return;1109 1110 OptionalFileEntryRef FE = SM.getFileEntryRefForID(FID);1111 if (indexFile)1112 *indexFile = getIndexFile(FE);1113 if (file)1114 *file = cxfile::makeCXFile(FE);1115 if (line)1116 *line = SM.getLineNumber(FID, FileOffset);1117 if (column)1118 *column = SM.getColumnNumber(FID, FileOffset);1119 if (offset)1120 *offset = FileOffset;1121}1122 1123static CXIdxEntityKind getEntityKindFromSymbolKind(SymbolKind K, SymbolLanguage L);1124static CXIdxEntityCXXTemplateKind1125getEntityKindFromSymbolProperties(SymbolPropertySet K);1126static CXIdxEntityLanguage getEntityLangFromSymbolLang(SymbolLanguage L);1127 1128void CXIndexDataConsumer::getEntityInfo(const NamedDecl *D,1129 EntityInfo &EntityInfo,1130 ScratchAlloc &SA) {1131 if (!D)1132 return;1133 1134 D = getEntityDecl(D);1135 EntityInfo.cursor = getCursor(D);1136 EntityInfo.Dcl = D;1137 EntityInfo.IndexCtx = this;1138 1139 SymbolInfo SymInfo = getSymbolInfo(D);1140 EntityInfo.kind = getEntityKindFromSymbolKind(SymInfo.Kind, SymInfo.Lang);1141 EntityInfo.templateKind = getEntityKindFromSymbolProperties(SymInfo.Properties);1142 EntityInfo.lang = getEntityLangFromSymbolLang(SymInfo.Lang);1143 1144 if (D->hasAttrs()) {1145 EntityInfo.AttrList = AttrListInfo::create(D, *this);1146 EntityInfo.attributes = EntityInfo.AttrList->getAttrs();1147 EntityInfo.numAttributes = EntityInfo.AttrList->getNumAttrs();1148 }1149 1150 if (EntityInfo.kind == CXIdxEntity_Unexposed)1151 return;1152 1153 if (IdentifierInfo *II = D->getIdentifier()) {1154 EntityInfo.name = SA.toCStr(II->getName());1155 1156 } else if (isa<TagDecl>(D) || isa<FieldDecl>(D) || isa<NamespaceDecl>(D)) {1157 EntityInfo.name = nullptr; // anonymous tag/field/namespace.1158 1159 } else {1160 SmallString<256> StrBuf;1161 {1162 llvm::raw_svector_ostream OS(StrBuf);1163 D->printName(OS);1164 }1165 EntityInfo.name = SA.copyCStr(StrBuf.str());1166 }1167 1168 {1169 SmallString<512> StrBuf;1170 bool Ignore = getDeclCursorUSR(D, StrBuf);1171 if (Ignore) {1172 EntityInfo.USR = nullptr;1173 } else {1174 EntityInfo.USR = SA.copyCStr(StrBuf.str());1175 }1176 }1177}1178 1179void CXIndexDataConsumer::getContainerInfo(const DeclContext *DC,1180 ContainerInfo &ContInfo) {1181 ContInfo.cursor = getCursor(cast<Decl>(DC));1182 ContInfo.DC = DC;1183 ContInfo.IndexCtx = this;1184}1185 1186CXCursor CXIndexDataConsumer::getRefCursor(const NamedDecl *D, SourceLocation Loc) {1187 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))1188 return MakeCursorTypeRef(TD, Loc, CXTU);1189 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))1190 return MakeCursorObjCClassRef(ID, Loc, CXTU);1191 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))1192 return MakeCursorObjCProtocolRef(PD, Loc, CXTU);1193 if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D))1194 return MakeCursorTemplateRef(Template, Loc, CXTU);1195 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(D))1196 return MakeCursorNamespaceRef(Namespace, Loc, CXTU);1197 if (const NamespaceAliasDecl *Namespace = dyn_cast<NamespaceAliasDecl>(D))1198 return MakeCursorNamespaceRef(Namespace, Loc, CXTU);1199 if (const FieldDecl *Field = dyn_cast<FieldDecl>(D))1200 return MakeCursorMemberRef(Field, Loc, CXTU);1201 if (const VarDecl *Var = dyn_cast<VarDecl>(D))1202 return MakeCursorVariableRef(Var, Loc, CXTU);1203 1204 return clang_getNullCursor();1205}1206 1207bool CXIndexDataConsumer::shouldIgnoreIfImplicit(const Decl *D) {1208 if (isa<ObjCInterfaceDecl>(D))1209 return false;1210 if (isa<ObjCCategoryDecl>(D))1211 return false;1212 if (isa<ObjCIvarDecl>(D))1213 return false;1214 if (isa<ObjCMethodDecl>(D))1215 return false;1216 if (isa<ImportDecl>(D))1217 return false;1218 return true;1219}1220 1221bool CXIndexDataConsumer::isTemplateImplicitInstantiation(const Decl *D) {1222 if (const ClassTemplateSpecializationDecl *1223 SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {1224 return SD->getSpecializationKind() == TSK_ImplicitInstantiation;1225 }1226 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {1227 return FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation;1228 }1229 return false;1230}1231 1232static CXIdxEntityKind getEntityKindFromSymbolKind(SymbolKind K, SymbolLanguage Lang) {1233 switch (K) {1234 case SymbolKind::Unknown:1235 case SymbolKind::Module:1236 case SymbolKind::Macro:1237 case SymbolKind::ClassProperty:1238 case SymbolKind::Using:1239 case SymbolKind::TemplateTypeParm:1240 case SymbolKind::TemplateTemplateParm:1241 case SymbolKind::NonTypeTemplateParm:1242 case SymbolKind::IncludeDirective:1243 return CXIdxEntity_Unexposed;1244 1245 case SymbolKind::Enum: return CXIdxEntity_Enum;1246 case SymbolKind::Struct: return CXIdxEntity_Struct;1247 case SymbolKind::Union: return CXIdxEntity_Union;1248 case SymbolKind::TypeAlias:1249 if (Lang == SymbolLanguage::CXX)1250 return CXIdxEntity_CXXTypeAlias;1251 return CXIdxEntity_Typedef;1252 case SymbolKind::Function: return CXIdxEntity_Function;1253 case SymbolKind::Variable: return CXIdxEntity_Variable;1254 case SymbolKind::Field:1255 if (Lang == SymbolLanguage::ObjC)1256 return CXIdxEntity_ObjCIvar;1257 return CXIdxEntity_Field;1258 case SymbolKind::EnumConstant: return CXIdxEntity_EnumConstant;1259 case SymbolKind::Class:1260 if (Lang == SymbolLanguage::ObjC)1261 return CXIdxEntity_ObjCClass;1262 return CXIdxEntity_CXXClass;1263 case SymbolKind::Protocol:1264 if (Lang == SymbolLanguage::ObjC)1265 return CXIdxEntity_ObjCProtocol;1266 return CXIdxEntity_CXXInterface;1267 case SymbolKind::Extension: return CXIdxEntity_ObjCCategory;1268 case SymbolKind::InstanceMethod:1269 if (Lang == SymbolLanguage::ObjC)1270 return CXIdxEntity_ObjCInstanceMethod;1271 return CXIdxEntity_CXXInstanceMethod;1272 case SymbolKind::ClassMethod: return CXIdxEntity_ObjCClassMethod;1273 case SymbolKind::StaticMethod: return CXIdxEntity_CXXStaticMethod;1274 case SymbolKind::InstanceProperty: return CXIdxEntity_ObjCProperty;1275 case SymbolKind::StaticProperty: return CXIdxEntity_CXXStaticVariable;1276 case SymbolKind::Namespace: return CXIdxEntity_CXXNamespace;1277 case SymbolKind::NamespaceAlias: return CXIdxEntity_CXXNamespaceAlias;1278 case SymbolKind::Constructor: return CXIdxEntity_CXXConstructor;1279 case SymbolKind::Destructor: return CXIdxEntity_CXXDestructor;1280 case SymbolKind::ConversionFunction: return CXIdxEntity_CXXConversionFunction;1281 case SymbolKind::Parameter: return CXIdxEntity_Variable;1282 case SymbolKind::Concept:1283 return CXIdxEntity_CXXConcept;1284 }1285 llvm_unreachable("invalid symbol kind");1286}1287 1288static CXIdxEntityCXXTemplateKind1289getEntityKindFromSymbolProperties(SymbolPropertySet K) {1290 if (K & (SymbolPropertySet)SymbolProperty::TemplatePartialSpecialization)1291 return CXIdxEntity_TemplatePartialSpecialization;1292 if (K & (SymbolPropertySet)SymbolProperty::TemplateSpecialization)1293 return CXIdxEntity_TemplateSpecialization;1294 if (K & (SymbolPropertySet)SymbolProperty::Generic)1295 return CXIdxEntity_Template;1296 return CXIdxEntity_NonTemplate;1297}1298 1299static CXIdxEntityLanguage getEntityLangFromSymbolLang(SymbolLanguage L) {1300 switch (L) {1301 case SymbolLanguage::C: return CXIdxEntityLang_C;1302 case SymbolLanguage::ObjC: return CXIdxEntityLang_ObjC;1303 case SymbolLanguage::CXX: return CXIdxEntityLang_CXX;1304 case SymbolLanguage::Swift: return CXIdxEntityLang_Swift;1305 }1306 llvm_unreachable("invalid symbol language");1307}1308