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