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