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