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