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