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