IndexingContext.cpp revision dd93c596cd95e1b96031ff47efe0a5095ff3d7f1
1//===- CIndexHigh.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 "CXTranslationUnit.h" 12#include "CIndexDiagnostic.h" 13 14#include "clang/Frontend/ASTUnit.h" 15#include "clang/AST/DeclObjC.h" 16 17using namespace clang; 18using namespace cxindex; 19using namespace cxcursor; 20 21const char *IndexingContext::StrAdapter::toCStr(StringRef Str) { 22 if (Str.empty()) 23 return ""; 24 if (Str.data()[Str.size()] == '\0') 25 return Str.data(); 26 Scratch += Str; 27 Scratch.push_back('\0'); 28 return Scratch.data() + (Scratch.size() - Str.size() - 1); 29} 30 31void IndexingContext::setASTContext(ASTContext &ctx) { 32 Ctx = &ctx; 33 static_cast<ASTUnit*>(CXTU->TUData)->setASTContext(&ctx); 34} 35 36void IndexingContext::enteredMainFile(const FileEntry *File) { 37 if (File && CB.enteredMainFile) { 38 CXIdxClientFile idxFile = CB.enteredMainFile(ClientData, (CXFile)File, 0); 39 FileMap[File] = idxFile; 40 } 41} 42 43void IndexingContext::ppIncludedFile(SourceLocation hashLoc, 44 StringRef filename, 45 const FileEntry *File, 46 bool isImport, bool isAngled) { 47 if (!CB.ppIncludedFile) 48 return; 49 50 StrAdapter SA(*this); 51 CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc), 52 SA.toCStr(filename), 53 (CXFile)File, 54 isImport, isAngled }; 55 CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info); 56 FileMap[File] = idxFile; 57} 58 59void IndexingContext::ppMacroDefined(SourceLocation Loc, StringRef Name, 60 SourceLocation DefBegin, unsigned Length, 61 const void *OpaqueMacro) { 62 if (!CB.ppMacroDefined) 63 return; 64 65 StrAdapter SA(*this); 66 CXIdxMacroInfo MacroInfo = { getIndexLoc(Loc), SA.toCStr(Name) }; 67 CXIdxMacroDefinedInfo Info = { &MacroInfo, 68 getIndexLoc(DefBegin), Length }; 69 CXIdxClientMacro idxMacro = CB.ppMacroDefined(ClientData, &Info); 70 MacroMap[OpaqueMacro] = idxMacro; 71} 72 73void IndexingContext::ppMacroUndefined(SourceLocation Loc, StringRef Name, 74 const void *OpaqueMacro) { 75 if (!CB.ppMacroUndefined) 76 return; 77 78 StrAdapter SA(*this); 79 CXIdxMacroUndefinedInfo Info = { getIndexLoc(Loc), 80 SA.toCStr(Name), 0 }; 81 CB.ppMacroUndefined(ClientData, &Info); 82} 83 84void IndexingContext::ppMacroExpanded(SourceLocation Loc, StringRef Name, 85 const void *OpaqueMacro) { 86 if (!CB.ppMacroExpanded) 87 return; 88 89 StrAdapter SA(*this); 90 CXIdxMacroExpandedInfo Info = { getIndexLoc(Loc), 91 SA.toCStr(Name), 0 }; 92 CB.ppMacroExpanded(ClientData, &Info); 93} 94 95void IndexingContext::invokeStartedTranslationUnit() { 96 CXIdxClientContainer idxCont = 0; 97 if (CB.startedTranslationUnit) 98 idxCont = CB.startedTranslationUnit(ClientData, 0); 99 addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont); 100} 101 102void IndexingContext::invokeFinishedTranslationUnit() { 103 endContainer(Ctx->getTranslationUnitDecl()); 104} 105 106void IndexingContext::handleDiagnostic(const StoredDiagnostic &StoredDiag) { 107 if (!CB.diagnostic) 108 return; 109 110 CXStoredDiagnostic CXDiag(StoredDiag, Ctx->getLangOptions()); 111 CB.diagnostic(ClientData, &CXDiag, 0); 112} 113 114void IndexingContext::handleDecl(const NamedDecl *D, 115 SourceLocation Loc, CXCursor Cursor, 116 bool isRedeclaration, bool isDefinition, 117 DeclInfo &DInfo) { 118 if (!CB.indexDeclaration) 119 return; 120 121 StrAdapter SA(*this); 122 getEntityInfo(D, DInfo.CXEntInfo, SA); 123 DInfo.entityInfo = &DInfo.CXEntInfo; 124 DInfo.cursor = Cursor; 125 DInfo.loc = getIndexLoc(Loc); 126 DInfo.container = getIndexContainer(D); 127 DInfo.isRedeclaration = isRedeclaration; 128 DInfo.isDefinition = isDefinition; 129 130 CXIdxClientEntity 131 clientEnt = CB.indexDeclaration(ClientData, &DInfo); 132 133 if (!isRedeclaration) 134 addEntityInMap(D, clientEnt); 135} 136 137void IndexingContext::handleObjCContainer(const ObjCContainerDecl *D, 138 SourceLocation Loc, CXCursor Cursor, 139 bool isForwardRef, 140 bool isRedeclaration, 141 bool isImplementation, 142 ObjCContainerDeclInfo &ContDInfo) { 143 ContDInfo.CXObjCContDeclInfo.declInfo = &ContDInfo; 144 if (isForwardRef) 145 ContDInfo.CXObjCContDeclInfo.kind = CXIdxObjCContainer_ForwardRef; 146 else if (isImplementation) 147 ContDInfo.CXObjCContDeclInfo.kind = CXIdxObjCContainer_Implementation; 148 else 149 ContDInfo.CXObjCContDeclInfo.kind = CXIdxObjCContainer_Interface; 150 151 handleDecl(D, Loc, Cursor, 152 isRedeclaration, /*isDefinition=*/!isForwardRef, ContDInfo); 153} 154 155void IndexingContext::handleFunction(const FunctionDecl *D) { 156 DeclInfo DInfo; 157 handleDecl(D, D->getLocation(), getCursor(D), 158 !D->isFirstDeclaration(), D->isThisDeclarationADefinition(), 159 DInfo); 160} 161 162void IndexingContext::handleVar(const VarDecl *D) { 163 DeclInfo DInfo; 164 handleDecl(D, D->getLocation(), getCursor(D), 165 !D->isFirstDeclaration(), D->isThisDeclarationADefinition(), 166 DInfo); 167} 168 169void IndexingContext::handleField(const FieldDecl *D) { 170 DeclInfo DInfo; 171 handleDecl(D, D->getLocation(), getCursor(D), 172 /*isRedeclaration=*/false, /*isDefinition=*/false, DInfo); 173} 174 175void IndexingContext::handleEnumerator(const EnumConstantDecl *D) { 176 DeclInfo DInfo; 177 handleDecl(D, D->getLocation(), getCursor(D), 178 /*isRedeclaration=*/false, /*isDefinition=*/true, DInfo); 179} 180 181void IndexingContext::handleTagDecl(const TagDecl *D) { 182 TagDeclInfo TagDInfo; 183 TagDInfo.CXTagDeclInfo.declInfo = &TagDInfo; 184 TagDInfo.CXTagDeclInfo.isAnonymous = D->getIdentifier() == 0; 185 handleDecl(D, D->getLocation(), getCursor(D), 186 !D->isFirstDeclaration(), D->isThisDeclarationADefinition(), 187 TagDInfo); 188} 189 190void IndexingContext::handleTypedef(const TypedefDecl *D) { 191 DeclInfo DInfo; 192 handleDecl(D, D->getLocation(), getCursor(D), 193 !D->isFirstDeclaration(), /*isDefinition=*/true, DInfo); 194} 195 196void IndexingContext::handleObjCClass(const ObjCClassDecl *D) { 197 ObjCContainerDeclInfo ContDInfo; 198 const ObjCClassDecl::ObjCClassRef *Ref = D->getForwardDecl(); 199 ObjCInterfaceDecl *IFaceD = Ref->getInterface(); 200 SourceLocation Loc = Ref->getLocation(); 201 bool isRedeclaration = IFaceD->getLocation() != Loc; 202 handleObjCContainer(IFaceD, Loc, MakeCursorObjCClassRef(IFaceD, Loc, CXTU), 203 /*isForwardRef=*/true, isRedeclaration, 204 /*isImplementation=*/false, ContDInfo); 205} 206 207void IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) { 208 ObjCContainerDeclInfo ContDInfo; 209 handleObjCContainer(D, D->getLocation(), getCursor(D), 210 /*isForwardRef=*/false, 211 /*isRedeclaration=*/D->isInitiallyForwardDecl(), 212 /*isImplementation=*/false, ContDInfo); 213} 214 215void IndexingContext::handleObjCImplementation( 216 const ObjCImplementationDecl *D) { 217 ObjCContainerDeclInfo ContDInfo; 218 const ObjCInterfaceDecl *Class = D->getClassInterface(); 219 handleObjCContainer(Class, D->getLocation(), getCursor(D), 220 /*isForwardRef=*/false, 221 /*isRedeclaration=*/!Class->isImplicitInterfaceDecl(), 222 /*isImplementation=*/true, ContDInfo); 223} 224 225void IndexingContext::handleObjCForwardProtocol(const ObjCProtocolDecl *D, 226 SourceLocation Loc, 227 bool isRedeclaration) { 228 ObjCContainerDeclInfo ContDInfo; 229 handleObjCContainer(D, Loc, MakeCursorObjCProtocolRef(D, Loc, CXTU), 230 /*isForwardRef=*/true, 231 isRedeclaration, 232 /*isImplementation=*/false, ContDInfo); 233} 234 235void IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) { 236 ObjCContainerDeclInfo ContDInfo; 237 handleObjCContainer(D, D->getLocation(), getCursor(D), 238 /*isForwardRef=*/false, 239 /*isRedeclaration=*/D->isInitiallyForwardDecl(), 240 /*isImplementation=*/false, ContDInfo); 241} 242 243void IndexingContext::defineObjCInterface(const ObjCInterfaceDecl *D) { 244 if (!CB.defineObjCClass) 245 return; 246 247 StrAdapter SA(*this); 248 CXIdxObjCBaseClassInfo BaseClass; 249 CXIdxEntityInfo BaseEntity; 250 if (D->getSuperClass()) { 251 getEntityInfo(D->getSuperClass(), BaseEntity, SA); 252 BaseClass.objcClass = &BaseEntity; 253 BaseClass.loc = getIndexLoc(D->getSuperClassLoc()); 254 } 255 256 SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos; 257 SmallVector<CXIdxEntityInfo, 4> ProtEntities; 258 ObjCInterfaceDecl::protocol_loc_iterator LI = D->protocol_loc_begin(); 259 for (ObjCInterfaceDecl::protocol_iterator 260 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) { 261 SourceLocation Loc = *LI; 262 ObjCProtocolDecl *PD = *I; 263 ProtEntities.push_back(CXIdxEntityInfo()); 264 getEntityInfo(PD, ProtEntities.back(), SA); 265 CXIdxObjCProtocolRefInfo ProtInfo = { 0, getIndexLoc(Loc) }; 266 ProtInfos.push_back(ProtInfo); 267 } 268 269 for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i) 270 ProtInfos[i].protocol = &ProtEntities[i]; 271 272 SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots; 273 for (unsigned i = 0, e = Prots.size(); i != e; ++i) 274 Prots.push_back(&ProtInfos[i]); 275 276 CXIdxEntityInfo ClassEntity; 277 getEntityInfo(D, ClassEntity, SA); 278 CXIdxObjCClassDefineInfo Info = { getCursor(D), 279 &ClassEntity, 280 getIndexContainerForDC(D), 281 D->getSuperClass() ? &BaseClass : 0, 282 Prots.data(), 283 static_cast<unsigned>(Prots.size()) }; 284 CB.defineObjCClass(ClientData, &Info); 285} 286 287void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) { 288 ObjCCategoryDeclInfo CatDInfo; 289 CXIdxEntityInfo ClassEntity; 290 StrAdapter SA(*this); 291 getEntityInfo(D->getClassInterface(), ClassEntity, SA); 292 293 CatDInfo.CXObjCCatDeclInfo.containerInfo = &CatDInfo.CXObjCContDeclInfo; 294 CatDInfo.CXObjCCatDeclInfo.objcClass = &ClassEntity; 295 handleObjCContainer(D, D->getLocation(), getCursor(D), 296 /*isForwardRef=*/false, 297 /*isRedeclaration=*/false, 298 /*isImplementation=*/false, CatDInfo); 299} 300 301void IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) { 302 const ObjCCategoryDecl *CatD = D->getCategoryDecl(); 303 ObjCCategoryDeclInfo CatDInfo; 304 CXIdxEntityInfo ClassEntity; 305 StrAdapter SA(*this); 306 getEntityInfo(CatD->getClassInterface(), ClassEntity, SA); 307 308 CatDInfo.CXObjCCatDeclInfo.containerInfo = &CatDInfo.CXObjCContDeclInfo; 309 CatDInfo.CXObjCCatDeclInfo.objcClass = &ClassEntity; 310 handleObjCContainer(CatD, D->getLocation(), getCursor(D), 311 /*isForwardRef=*/false, 312 /*isRedeclaration=*/true, 313 /*isImplementation=*/true, CatDInfo); 314} 315 316void IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) { 317 DeclInfo DInfo; 318 handleDecl(D, D->getLocation(), getCursor(D), 319 !D->isCanonicalDecl(), D->isThisDeclarationADefinition(), 320 DInfo); 321} 322 323void IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) { 324 DeclInfo DInfo; 325 handleDecl(D, D->getLocation(), getCursor(D), 326 /*isRedeclaration=*/false, /*isDefinition=*/false, 327 DInfo); 328} 329 330void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc, 331 const NamedDecl *Parent, 332 const DeclContext *DC, 333 const Expr *E, 334 CXIdxEntityRefKind Kind) { 335 if (Loc.isInvalid()) 336 return; 337 if (!CB.indexEntityReference) 338 return; 339 if (isNotFromSourceFile(D->getLocation())) 340 return; 341 342 StrAdapter SA(*this); 343 CXCursor Cursor = E ? MakeCXCursor(const_cast<Expr*>(E), 344 const_cast<Decl*>(cast<Decl>(DC)), CXTU) 345 : getRefCursor(D, Loc); 346 347 CXIdxEntityInfo RefEntity, ParentEntity; 348 getEntityInfo(D, RefEntity, SA); 349 getEntityInfo(Parent, ParentEntity, SA); 350 CXIdxEntityRefInfo Info = { Cursor, 351 getIndexLoc(Loc), 352 &RefEntity, 353 &ParentEntity, 354 getIndexContainerForDC(DC), 355 Kind }; 356 CB.indexEntityReference(ClientData, &Info); 357} 358 359void IndexingContext::startContainer(const NamedDecl *D, bool isStmtBody, 360 const DeclContext *DC) { 361 if (!CB.startedContainer) 362 return; 363 364 if (!DC) 365 DC = cast<DeclContext>(D); 366 367 StrAdapter SA(*this); 368 CXIdxEntityInfo Entity; 369 getEntityInfo(D, Entity, SA); 370 CXIdxContainerInfo Info; 371 Info.entity = &Entity; 372 Info.cursor = getCursor(D); 373 Info.loc = getIndexLoc(D->getLocation()); 374 Info.isObjCImpl = isa<ObjCImplDecl>(D); 375 376 CXIdxClientContainer clientCont = CB.startedContainer(ClientData, &Info); 377 addContainerInMap(DC, clientCont); 378} 379 380void IndexingContext::endContainer(const DeclContext *DC) { 381 if (CB.endedContainer) { 382 CXIdxEndContainerInfo Info = { getIndexContainerForDC(DC), 383 getIndexLoc(cast<Decl>(DC)->getLocEnd()) }; 384 CB.endedContainer(ClientData, &Info); 385 } 386} 387 388bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const { 389 if (Loc.isInvalid()) 390 return true; 391 SourceManager &SM = Ctx->getSourceManager(); 392 SourceLocation FileLoc = SM.getFileLoc(Loc); 393 FileID FID = SM.getFileID(FileLoc); 394 return SM.getFileEntryForID(FID) == 0; 395} 396 397void IndexingContext::addContainerInMap(const DeclContext *DC, 398 CXIdxClientContainer container) { 399 assert(getScopedContext(DC) == DC); 400 ContainerMapTy::iterator I = ContainerMap.find(DC); 401 if (I == ContainerMap.end()) { 402 if (container) 403 ContainerMap[DC] = container; 404 return; 405 } 406 // Allow changing the container of a previously seen DeclContext so we 407 // can handle invalid user code, like a function re-definition. 408 if (container) 409 I->second = container; 410 else 411 ContainerMap.erase(I); 412} 413 414void IndexingContext::addEntityInMap(const NamedDecl *D, 415 CXIdxClientEntity entity) { 416 assert(getEntityDecl(D) == D && 417 "Tried to add a non-entity (canonical) decl"); 418 assert(EntityMap.find(D) == EntityMap.end()); 419 if (entity || D->isFromASTFile()) 420 EntityMap[D] = entity; 421} 422 423CXIdxClientEntity IndexingContext::getClientEntity(const NamedDecl *D) { 424 if (!D) 425 return 0; 426 D = getEntityDecl(D); 427 EntityMapTy::const_iterator I = EntityMap.find(D); 428 if (I != EntityMap.end()) 429 return I->second; 430 431 if (!D->isFromASTFile()) { 432 //assert(0 && "Entity not in map"); 433 return 0; 434 } 435 436 StrAdapter SA(*this); 437 438 CXIdxClientEntity idxEntity = 0; 439 if (CB.importedEntity) { 440 CXIdxEntityInfo EntityInfo; 441 getEntityInfo(D, EntityInfo, SA); 442 CXIdxImportedEntityInfo Info = { &EntityInfo, 443 getCursor(D), 444 getIndexLoc(D->getLocation()), 445 /*CXIdxASTFile*/0 }; 446 idxEntity = CB.importedEntity(ClientData, &Info); 447 } 448 addEntityInMap(D, idxEntity); 449 return idxEntity; 450} 451 452const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const { 453 assert(D); 454 D = cast<NamedDecl>(D->getCanonicalDecl()); 455 456 if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(D)) { 457 if (Cat->IsClassExtension()) 458 return getEntityDecl(Cat->getClassInterface()); 459 460 } else if (const ObjCImplementationDecl * 461 ImplD = dyn_cast<ObjCImplementationDecl>(D)) { 462 return getEntityDecl(ImplD->getClassInterface()); 463 464 } else if (const ObjCCategoryImplDecl * 465 CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) { 466 return getEntityDecl(CatImplD->getCategoryDecl()); 467 } 468 469 return D; 470} 471 472const DeclContext * 473IndexingContext::getScopedContext(const DeclContext *DC) const { 474 // Local contexts are ignored for indexing. 475 const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod(); 476 if (FuncCtx) 477 return FuncCtx; 478 479 // We consider enums always scoped for indexing. 480 if (isa<TagDecl>(DC)) 481 return DC; 482 483 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 484 if (NS->isAnonymousNamespace()) 485 return getScopedContext(NS->getParent()); 486 return NS; 487 } 488 489 return DC->getRedeclContext(); 490} 491 492CXIdxClientContainer 493IndexingContext::getIndexContainerForDC(const DeclContext *DC) const { 494 DC = getScopedContext(DC); 495 ContainerMapTy::const_iterator I = ContainerMap.find(DC); 496// assert(I != ContainerMap.end() && 497// "Failed to include a scoped context in the container map"); 498 return I->second; 499} 500 501CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) { 502 if (!File) 503 return 0; 504 505 FileMapTy::iterator FI = FileMap.find(File); 506 if (FI != FileMap.end()) 507 return FI->second; 508 509 return 0; 510} 511 512CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const { 513 CXIdxLoc idxLoc = { {0, 0}, 0 }; 514 if (Loc.isInvalid()) 515 return idxLoc; 516 517 idxLoc.ptr_data[0] = (void*)this; 518 idxLoc.int_data = Loc.getRawEncoding(); 519 return idxLoc; 520} 521 522void IndexingContext::translateLoc(SourceLocation Loc, 523 CXIdxClientFile *indexFile, CXFile *file, 524 unsigned *line, unsigned *column, 525 unsigned *offset) { 526 if (Loc.isInvalid()) 527 return; 528 529 SourceManager &SM = Ctx->getSourceManager(); 530 Loc = SM.getFileLoc(Loc); 531 532 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); 533 FileID FID = LocInfo.first; 534 unsigned FileOffset = LocInfo.second; 535 536 if (FID.isInvalid()) 537 return; 538 539 const FileEntry *FE = SM.getFileEntryForID(FID); 540 if (indexFile) 541 *indexFile = getIndexFile(FE); 542 if (file) 543 *file = (void *)FE; 544 if (line) 545 *line = SM.getLineNumber(FID, FileOffset); 546 if (column) 547 *column = SM.getColumnNumber(FID, FileOffset); 548 if (offset) 549 *offset = FileOffset; 550} 551 552void IndexingContext::getEntityInfo(const NamedDecl *D, 553 CXIdxEntityInfo &EntityInfo, 554 StrAdapter &SA) { 555 D = getEntityDecl(D); 556 EntityInfo.kind = CXIdxEntity_Unexposed; 557 EntityInfo.clientEntity = getClientEntity(D); 558 559 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) { 560 switch (TD->getTagKind()) { 561 case TTK_Struct: 562 EntityInfo.kind = CXIdxEntity_Struct; break; 563 case TTK_Union: 564 EntityInfo.kind = CXIdxEntity_Union; break; 565 case TTK_Class: 566 EntityInfo.kind = CXIdxEntity_CXXClass; break; 567 case TTK_Enum: 568 EntityInfo.kind = CXIdxEntity_Enum; break; 569 } 570 571 } else { 572 switch (D->getKind()) { 573 case Decl::Typedef: 574 EntityInfo.kind = CXIdxEntity_Typedef; break; 575 case Decl::Function: 576 EntityInfo.kind = CXIdxEntity_Function; break; 577 case Decl::Var: 578 EntityInfo.kind = CXIdxEntity_Variable; break; 579 case Decl::Field: 580 EntityInfo.kind = CXIdxEntity_Field; break; 581 case Decl::EnumConstant: 582 EntityInfo.kind = CXIdxEntity_EnumConstant; break; 583 case Decl::ObjCInterface: 584 EntityInfo.kind = CXIdxEntity_ObjCClass; break; 585 case Decl::ObjCProtocol: 586 EntityInfo.kind = CXIdxEntity_ObjCProtocol; break; 587 case Decl::ObjCCategory: 588 EntityInfo.kind = CXIdxEntity_ObjCCategory; break; 589 case Decl::ObjCMethod: 590 EntityInfo.kind = CXIdxEntity_ObjCMethod; break; 591 case Decl::ObjCProperty: 592 EntityInfo.kind = CXIdxEntity_ObjCProperty; break; 593 case Decl::ObjCIvar: 594 EntityInfo.kind = CXIdxEntity_ObjCIvar; break; 595 default: 596 break; 597 } 598 } 599 600 if (IdentifierInfo *II = D->getIdentifier()) { 601 EntityInfo.name = SA.toCStr(II->getName()); 602 603 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) { 604 EntityInfo.name = 0; // anonymous record/namespace. 605 606 } else { 607 unsigned Begin = SA.getCurSize(); 608 { 609 llvm::raw_svector_ostream OS(SA.getBuffer()); 610 D->printName(OS); 611 } 612 EntityInfo.name = SA.getCStr(Begin); 613 } 614 615 { 616 unsigned Begin = SA.getCurSize(); 617 bool Ignore = getDeclCursorUSR(D, SA.getBuffer()); 618 if (Ignore) { 619 EntityInfo.USR = ""; 620 } else { 621 EntityInfo.USR = SA.getCStr(Begin); 622 } 623 } 624} 625 626CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) { 627 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 628 return MakeCursorTypeRef(TD, Loc, CXTU); 629 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) 630 return MakeCursorObjCClassRef(ID, Loc, CXTU); 631 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) 632 return MakeCursorObjCProtocolRef(PD, Loc, CXTU); 633 634 //assert(0 && "not yet"); 635 return clang_getNullCursor(); 636} 637