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