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 17 using namespace clang; 18 using namespace cxindex; 19 using namespace cxcursor; 20 21 const 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 31 void IndexingContext::setASTContext(ASTContext &ctx) { 32 Ctx = &ctx; 33 static_cast<ASTUnit*>(CXTU->TUData)->setASTContext(&ctx); 34 } 35 36 void IndexingContext::ppIncludedFile(SourceLocation hashLoc, 37 StringRef filename, 38 const FileEntry *File, 39 bool isImport, bool isAngled) { 40 if (!CB.ppIncludedFile) 41 return; 42 43 StrAdapter SA(this); 44 CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc), 45 SA.toCStr(filename), 46 getIndexFile(File), 47 isImport, isAngled }; 48 CB.ppIncludedFile(ClientData, &Info); 49 } 50 51 void IndexingContext::ppMacroDefined(SourceLocation Loc, StringRef Name, 52 SourceLocation DefBegin, unsigned Length, 53 const void *OpaqueMacro) { 54 if (!CB.ppMacroDefined) 55 return; 56 57 StrAdapter SA(this); 58 CXIdxMacroInfo MacroInfo = { getIndexLoc(Loc), SA.toCStr(Name) }; 59 CXIdxMacroDefinedInfo Info = { &MacroInfo, 60 getIndexLoc(DefBegin), Length }; 61 CXIdxMacro idxMacro = CB.ppMacroDefined(ClientData, &Info); 62 MacroMap[OpaqueMacro] = idxMacro; 63 } 64 65 void IndexingContext::ppMacroUndefined(SourceLocation Loc, StringRef Name, 66 const void *OpaqueMacro) { 67 if (!CB.ppMacroUndefined) 68 return; 69 70 StrAdapter SA(this); 71 CXIdxMacroUndefinedInfo Info = { getIndexLoc(Loc), 72 SA.toCStr(Name), 0 }; 73 CB.ppMacroUndefined(ClientData, &Info); 74 } 75 76 void IndexingContext::ppMacroExpanded(SourceLocation Loc, StringRef Name, 77 const void *OpaqueMacro) { 78 if (!CB.ppMacroExpanded) 79 return; 80 81 StrAdapter SA(this); 82 CXIdxMacroExpandedInfo Info = { getIndexLoc(Loc), 83 SA.toCStr(Name), 0 }; 84 CB.ppMacroExpanded(ClientData, &Info); 85 } 86 87 void IndexingContext::invokeStartedTranslationUnit() { 88 CXIdxContainer idxCont = 0; 89 if (CB.startedTranslationUnit) 90 idxCont = CB.startedTranslationUnit(ClientData, 0); 91 addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont); 92 } 93 94 void IndexingContext::invokeFinishedTranslationUnit() { 95 invokeEndedContainer(Ctx->getTranslationUnitDecl()); 96 } 97 98 void IndexingContext::handleDiagnostic(const StoredDiagnostic &StoredDiag) { 99 if (!CB.diagnostic) 100 return; 101 102 CXStoredDiagnostic CXDiag(StoredDiag, Ctx->getLangOptions()); 103 CB.diagnostic(ClientData, &CXDiag, 0); 104 } 105 106 void IndexingContext::handleFunction(const FunctionDecl *D) { 107 StrAdapter SA(this); 108 109 if (D->isFirstDeclaration()) { 110 CXIdxEntity idxEntity = 0; 111 if (CB.indexFunction) { 112 CXIdxEntityInfo EntityInfo; 113 CXIdxIndexedDeclInfo DeclInfo; 114 CXIdxIndexedEntityInfo IdxEntityInfo; 115 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 116 CXIdxFunctionInfo Info = { &IdxEntityInfo, 117 D->isThisDeclarationADefinition() }; 118 119 idxEntity = CB.indexFunction(ClientData, &Info); 120 } 121 122 addEntityInMap(D, idxEntity); 123 124 } else { 125 if (CB.indexFunctionRedeclaration) { 126 CXIdxIndexedDeclInfo DeclInfo; 127 CXIdxIndexedRedeclInfo RedeclInfo; 128 getIndexedRedeclInfo(D, RedeclInfo, DeclInfo); 129 CXIdxFunctionRedeclInfo Info = { &RedeclInfo, 130 D->isThisDeclarationADefinition() }; 131 132 CB.indexFunctionRedeclaration(ClientData, &Info); 133 } 134 } 135 } 136 137 void IndexingContext::handleVar(const VarDecl *D) { 138 StrAdapter SA(this); 139 140 if (D->isFirstDeclaration()) { 141 CXIdxEntity idxEntity = 0; 142 if (CB.indexVariable) { 143 CXIdxEntityInfo EntityInfo; 144 CXIdxIndexedDeclInfo DeclInfo; 145 CXIdxIndexedEntityInfo IdxEntityInfo; 146 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 147 CXIdxVariableInfo Info = { &IdxEntityInfo, 148 D->isThisDeclarationADefinition() }; 149 150 idxEntity = CB.indexVariable(ClientData, &Info); 151 } 152 153 addEntityInMap(D, idxEntity); 154 155 } else { 156 if (CB.indexVariableRedeclaration) { 157 CXIdxIndexedDeclInfo DeclInfo; 158 CXIdxIndexedRedeclInfo RedeclInfo; 159 getIndexedRedeclInfo(D, RedeclInfo, DeclInfo); 160 CXIdxVariableRedeclInfo Info = { &RedeclInfo, 161 D->isThisDeclarationADefinition() }; 162 163 CB.indexVariableRedeclaration(ClientData, &Info); 164 } 165 } 166 } 167 168 void IndexingContext::handleField(const FieldDecl *D) { 169 StrAdapter SA(this); 170 171 CXIdxEntity idxEntity = 0; 172 if (CB.indexTypedef) { 173 CXIdxEntityInfo EntityInfo; 174 CXIdxIndexedDeclInfo DeclInfo; 175 CXIdxIndexedEntityInfo IdxEntityInfo; 176 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 177 CXIdxFieldInfo Info = { &IdxEntityInfo }; 178 179 idxEntity = CB.indexField(ClientData, &Info); 180 } 181 182 addEntityInMap(D, idxEntity); 183 } 184 185 void IndexingContext::handleEnumerator(const EnumConstantDecl *D) { 186 StrAdapter SA(this); 187 188 CXIdxEntity idxEntity = 0; 189 if (CB.indexTypedef) { 190 CXIdxEntityInfo EntityInfo; 191 CXIdxIndexedDeclInfo DeclInfo; 192 CXIdxIndexedEntityInfo IdxEntityInfo; 193 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 194 CXIdxEnumeratorInfo Info = { &IdxEntityInfo }; 195 196 idxEntity = CB.indexEnumerator(ClientData, &Info); 197 } 198 199 addEntityInMap(D, idxEntity); 200 } 201 202 void IndexingContext::handleTagDecl(const TagDecl *D) { 203 StrAdapter SA(this); 204 205 if (D->isFirstDeclaration()) { 206 CXIdxEntity idxEntity = 0; 207 if (CB.indexTagType) { 208 CXIdxEntityInfo EntityInfo; 209 CXIdxIndexedDeclInfo DeclInfo; 210 CXIdxIndexedEntityInfo IdxEntityInfo; 211 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 212 CXIdxTagTypeInfo Info = { &IdxEntityInfo, 213 D->isThisDeclarationADefinition(), 214 D->getIdentifier() == 0}; 215 216 idxEntity = CB.indexTagType(ClientData, &Info); 217 } 218 219 addEntityInMap(D, idxEntity); 220 221 } else { 222 if (CB.indexTagTypeRedeclaration) { 223 CXIdxIndexedDeclInfo DeclInfo; 224 CXIdxIndexedRedeclInfo RedeclInfo; 225 getIndexedRedeclInfo(D, RedeclInfo, DeclInfo); 226 CXIdxTagTypeRedeclInfo Info = { &RedeclInfo, 227 D->isThisDeclarationADefinition() }; 228 229 CB.indexTagTypeRedeclaration(ClientData, &Info); 230 } 231 } 232 } 233 234 void IndexingContext::handleTypedef(const TypedefDecl *D) { 235 StrAdapter SA(this); 236 237 CXIdxEntity idxEntity = 0; 238 if (CB.indexTypedef) { 239 CXIdxEntityInfo EntityInfo; 240 CXIdxIndexedDeclInfo DeclInfo; 241 CXIdxIndexedEntityInfo IdxEntityInfo; 242 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 243 CXIdxTypedefInfo Info = { &IdxEntityInfo }; 244 245 idxEntity = CB.indexTypedef(ClientData, &Info); 246 } 247 248 addEntityInMap(D, idxEntity); 249 } 250 251 void IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) { 252 StrAdapter SA(this); 253 254 CXIdxEntity idxEntity = 0; 255 if (CB.indexObjCClass) { 256 CXIdxEntityInfo EntityInfo; 257 CXIdxIndexedDeclInfo DeclInfo; 258 CXIdxIndexedEntityInfo IdxEntityInfo; 259 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 260 CXIdxObjCClassInfo Info = { &IdxEntityInfo, 261 D->isForwardDecl() }; 262 263 idxEntity = CB.indexObjCClass(ClientData, &Info); 264 } 265 266 addEntityInMap(D, idxEntity); 267 } 268 269 void IndexingContext::defineObjCInterface(const ObjCInterfaceDecl *D) { 270 if (!CB.defineObjCClass) 271 return; 272 273 CXIdxObjCBaseClassInfo BaseClass = { getIndexEntity(D->getSuperClass()), 274 getIndexLoc(D->getSuperClassLoc()) }; 275 if (D->getSuperClass()) { 276 BaseClass.objcClass = getIndexEntity(D->getSuperClass()); 277 BaseClass.loc = getIndexLoc(D->getSuperClassLoc()); 278 } 279 280 SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos; 281 ObjCInterfaceDecl::protocol_loc_iterator LI = D->protocol_loc_begin(); 282 for (ObjCInterfaceDecl::protocol_iterator 283 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) { 284 SourceLocation Loc = *LI; 285 ObjCProtocolDecl *PD = *I; 286 CXIdxObjCProtocolRefInfo ProtInfo = { getIndexEntity(PD), 287 getIndexLoc(Loc) }; 288 ProtInfos.push_back(ProtInfo); 289 } 290 291 SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots; 292 for (unsigned i = 0, e = Prots.size(); i != e; ++i) 293 Prots.push_back(&ProtInfos[i]); 294 295 CXIdxObjCClassDefineInfo Info = { getCursor(D), 296 getIndexEntity(D), 297 getIndexContainerForDC(D), 298 D->getSuperClass() ? &BaseClass : 0, 299 Prots.data(), 300 static_cast<unsigned>(Prots.size()) }; 301 CB.defineObjCClass(ClientData, &Info); 302 } 303 304 void IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) { 305 StrAdapter SA(this); 306 307 CXIdxEntity idxEntity = 0; 308 if (CB.indexObjCProtocol) { 309 CXIdxEntityInfo EntityInfo; 310 CXIdxIndexedDeclInfo DeclInfo; 311 CXIdxIndexedEntityInfo IdxEntityInfo; 312 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 313 CXIdxObjCProtocolInfo Info = { &IdxEntityInfo, 314 D->isForwardDecl() }; 315 316 idxEntity = CB.indexObjCProtocol(ClientData, &Info); 317 } 318 319 addEntityInMap(D, idxEntity); 320 } 321 322 void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) { 323 StrAdapter SA(this); 324 325 CXIdxEntity idxEntity = 0; 326 if (CB.indexObjCCategory) { 327 CXIdxEntityInfo EntityInfo; 328 CXIdxIndexedDeclInfo DeclInfo; 329 CXIdxIndexedEntityInfo IdxEntityInfo; 330 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 331 CXIdxObjCCategoryInfo Info = { &IdxEntityInfo, 332 getIndexEntity(D->getClassInterface()) }; 333 334 idxEntity = CB.indexObjCCategory(ClientData, &Info); 335 } 336 337 addEntityInMap(D, idxEntity); 338 } 339 340 void IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) { 341 StrAdapter SA(this); 342 343 if (D->isCanonicalDecl()) { 344 CXIdxEntity idxEntity = 0; 345 if (CB.indexObjCMethod) { 346 CXIdxEntityInfo EntityInfo; 347 CXIdxIndexedDeclInfo DeclInfo; 348 CXIdxIndexedEntityInfo IdxEntityInfo; 349 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 350 CXIdxObjCMethodInfo Info = { &IdxEntityInfo, 351 D->isThisDeclarationADefinition() }; 352 353 idxEntity = CB.indexObjCMethod(ClientData, &Info); 354 } 355 356 addEntityInMap(D, idxEntity); 357 358 } else { 359 if (CB.indexObjCMethodRedeclaration) { 360 CXIdxIndexedRedeclInfo RedeclInfo; 361 CXIdxIndexedDeclInfo DeclInfo; 362 getIndexedRedeclInfo(D, RedeclInfo, DeclInfo); 363 CXIdxObjCMethodRedeclInfo Info = { &RedeclInfo, 364 D->isThisDeclarationADefinition() }; 365 366 CB.indexObjCMethodRedeclaration(ClientData, &Info); 367 } 368 } 369 } 370 371 void IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) { 372 StrAdapter SA(this); 373 374 CXIdxEntity idxEntity = 0; 375 if (CB.indexObjCProperty) { 376 CXIdxEntityInfo EntityInfo; 377 CXIdxIndexedDeclInfo DeclInfo; 378 CXIdxIndexedEntityInfo IdxEntityInfo; 379 getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA); 380 CXIdxObjCPropertyInfo Info = { &IdxEntityInfo }; 381 382 idxEntity = CB.indexObjCProperty(ClientData, &Info); 383 } 384 385 addEntityInMap(D, idxEntity); 386 } 387 388 void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc, 389 const NamedDecl *Parent, 390 const DeclContext *DC, 391 const Expr *E, 392 CXIdxEntityRefKind Kind) { 393 if (Loc.isInvalid()) 394 return; 395 if (!CB.indexEntityReference) 396 return; 397 if (isNotFromSourceFile(D->getLocation())) 398 return; 399 400 CXIdxEntityRefInfo Info = { E ? MakeCXCursor((Stmt*)E, 401 (Decl*)cast<Decl>(DC), CXTU) 402 : getRefCursor(D, Loc), 403 getIndexLoc(Loc), 404 getIndexEntity(D), 405 getIndexEntity(Parent), 406 getIndexContainerForDC(DC), 407 Kind }; 408 CB.indexEntityReference(ClientData, &Info); 409 } 410 411 void IndexingContext::invokeStartedStatementBody(const NamedDecl *D, 412 const DeclContext *DC) { 413 const Stmt *Body = cast<Decl>(DC)->getBody(); 414 assert(Body); 415 416 CXIdxContainer idxCont = 0; 417 if (CB.startedStatementBody) { 418 CXIdxContainerInfo ContainerInfo; 419 getContainerInfo(D, ContainerInfo); 420 CXIdxStmtBodyInfo Info = { &ContainerInfo, 421 getIndexLoc(Body->getLocStart()) }; 422 423 idxCont = CB.startedStatementBody(ClientData, &Info); 424 } 425 addContainerInMap(DC, idxCont); 426 } 427 428 void IndexingContext::invokeStartedTagTypeDefinition(const TagDecl *D) { 429 CXIdxContainer idxCont = 0; 430 if (CB.startedTagTypeDefinition) { 431 CXIdxContainerInfo ContainerInfo; 432 getContainerInfo(D, ContainerInfo); 433 CXIdxTagTypeDefinitionInfo Info = { &ContainerInfo }; 434 435 idxCont = CB.startedTagTypeDefinition(ClientData, &Info); 436 } 437 addContainerInMap(D, idxCont); 438 } 439 440 void IndexingContext::invokeStartedObjCContainer(const ObjCContainerDecl *D) { 441 CXIdxContainer idxCont = 0; 442 if (CB.startedObjCContainer) { 443 CXIdxContainerInfo ContainerInfo; 444 getContainerInfo(D, ContainerInfo); 445 CXIdxObjCContainerInfo Info = { &ContainerInfo }; 446 447 idxCont = CB.startedObjCContainer(ClientData, &Info); 448 } 449 addContainerInMap(D, idxCont); 450 } 451 452 void IndexingContext::invokeEndedContainer(const DeclContext *DC) { 453 if (CB.endedContainer) { 454 CXIdxEndContainerInfo Info = { getIndexContainerForDC(DC), 455 getIndexLoc(cast<Decl>(DC)->getLocEnd()) }; 456 CB.endedContainer(ClientData, &Info); 457 } 458 } 459 460 bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const { 461 if (Loc.isInvalid()) 462 return true; 463 SourceManager &SM = Ctx->getSourceManager(); 464 SourceLocation FileLoc = SM.getFileLoc(Loc); 465 FileID FID = SM.getFileID(FileLoc); 466 return SM.getFileEntryForID(FID) == 0; 467 } 468 469 void IndexingContext::addContainerInMap(const DeclContext *DC, 470 CXIdxContainer container) { 471 assert(getScopedContext(DC) == DC); 472 ContainerMapTy::iterator I = ContainerMap.find(DC); 473 if (I == ContainerMap.end()) { 474 if (container) 475 ContainerMap[DC] = container; 476 return; 477 } 478 // Allow changing the container of a previously seen DeclContext so we 479 // can handle invalid user code, like a function re-definition. 480 if (container) 481 I->second = container; 482 else 483 ContainerMap.erase(I); 484 } 485 486 void IndexingContext::addEntityInMap(const NamedDecl *D, CXIdxEntity entity) { 487 assert(getEntityDecl(D) == D && 488 "Tried to add a non-entity (canonical) decl"); 489 assert(EntityMap.find(D) == EntityMap.end()); 490 if (entity || D->isFromASTFile()) 491 EntityMap[D] = entity; 492 } 493 494 CXIdxEntity IndexingContext::getIndexEntity(const NamedDecl *D) { 495 if (!D) 496 return 0; 497 D = getEntityDecl(D); 498 EntityMapTy::const_iterator I = EntityMap.find(D); 499 if (I != EntityMap.end()) 500 return I->second; 501 502 if (!D->isFromASTFile()) { 503 //assert(0 && "Entity not in map"); 504 return 0; 505 } 506 507 StrAdapter SA(this); 508 509 CXIdxEntity idxEntity = 0; 510 if (CB.importedEntity) { 511 CXIdxEntityInfo EntityInfo; 512 getEntityInfo(D, EntityInfo, SA); 513 CXIdxImportedEntityInfo Info = { &EntityInfo, 514 getCursor(D), 515 getIndexLoc(D->getLocation()), 516 /*CXIdxASTFile*/0 }; 517 idxEntity = CB.importedEntity(ClientData, &Info); 518 } 519 addEntityInMap(D, idxEntity); 520 return idxEntity; 521 } 522 523 const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const { 524 assert(D); 525 D = cast<NamedDecl>(D->getCanonicalDecl()); 526 527 if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(D)) { 528 if (Cat->IsClassExtension()) 529 return getEntityDecl(Cat->getClassInterface()); 530 531 } else if (const ObjCImplementationDecl * 532 ImplD = dyn_cast<ObjCImplementationDecl>(D)) { 533 return getEntityDecl(ImplD->getClassInterface()); 534 535 } else if (const ObjCCategoryImplDecl * 536 CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) { 537 return getEntityDecl(CatImplD->getCategoryDecl()); 538 } 539 540 return D; 541 } 542 543 const DeclContext * 544 IndexingContext::getScopedContext(const DeclContext *DC) const { 545 // Local contexts are ignored for indexing. 546 const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod(); 547 if (FuncCtx) 548 return FuncCtx; 549 550 // We consider enums always scoped for indexing. 551 if (isa<TagDecl>(DC)) 552 return DC; 553 554 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 555 if (NS->isAnonymousNamespace()) 556 return getScopedContext(NS->getParent()); 557 return NS; 558 } 559 560 return DC->getRedeclContext(); 561 } 562 563 CXIdxContainer 564 IndexingContext::getIndexContainerForDC(const DeclContext *DC) const { 565 DC = getScopedContext(DC); 566 ContainerMapTy::const_iterator I = ContainerMap.find(DC); 567 // assert(I != ContainerMap.end() && 568 // "Failed to include a scoped context in the container map"); 569 return I->second; 570 } 571 572 CXIdxFile IndexingContext::getIndexFile(const FileEntry *File) { 573 if (!File) 574 return 0; 575 if (!CB.recordFile) 576 return 0; 577 578 FileMapTy::iterator FI = FileMap.find(File); 579 if (FI != FileMap.end()) 580 return FI->second; 581 582 CXIdxFile idxFile = CB.recordFile(ClientData, (CXFile)File, 0); 583 FileMap[File] = idxFile; 584 return idxFile; 585 } 586 587 CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const { 588 CXIdxLoc idxLoc = { {0, 0}, 0 }; 589 if (Loc.isInvalid()) 590 return idxLoc; 591 592 idxLoc.ptr_data[0] = (void*)this; 593 idxLoc.int_data = Loc.getRawEncoding(); 594 return idxLoc; 595 } 596 597 void IndexingContext::translateLoc(SourceLocation Loc, 598 CXIdxFile *indexFile, CXFile *file, 599 unsigned *line, unsigned *column, 600 unsigned *offset) { 601 if (Loc.isInvalid()) 602 return; 603 604 SourceManager &SM = Ctx->getSourceManager(); 605 Loc = SM.getFileLoc(Loc); 606 607 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); 608 FileID FID = LocInfo.first; 609 unsigned FileOffset = LocInfo.second; 610 611 if (FID.isInvalid()) 612 return; 613 614 const FileEntry *FE = SM.getFileEntryForID(FID); 615 if (indexFile) 616 *indexFile = getIndexFile(FE); 617 if (file) 618 *file = (void *)FE; 619 if (line) 620 *line = SM.getLineNumber(FID, FileOffset); 621 if (column) 622 *column = SM.getColumnNumber(FID, FileOffset); 623 if (offset) 624 *offset = FileOffset; 625 } 626 627 void IndexingContext::getIndexedEntityInfo(const NamedDecl *D, 628 CXIdxIndexedEntityInfo &IdxEntityInfo, 629 CXIdxEntityInfo &EntityInfo, 630 CXIdxIndexedDeclInfo &IdxDeclInfo, 631 StrAdapter &SA) { 632 getEntityInfo(D, EntityInfo, SA); 633 getIndexedDeclInfo(D, IdxDeclInfo); 634 IdxEntityInfo.entityInfo = &EntityInfo; 635 IdxEntityInfo.declInfo = &IdxDeclInfo; 636 } 637 638 void IndexingContext::getIndexedDeclInfo(const NamedDecl *D, 639 CXIdxIndexedDeclInfo &IdxDeclInfo) { 640 IdxDeclInfo.cursor = getCursor(D); 641 IdxDeclInfo.loc = getIndexLoc(D->getLocation()); 642 IdxDeclInfo.container = getIndexContainer(D); 643 } 644 645 void IndexingContext::getIndexedRedeclInfo(const NamedDecl *D, 646 CXIdxIndexedRedeclInfo &RedeclInfo, 647 CXIdxIndexedDeclInfo &IdxDeclInfo) { 648 getIndexedDeclInfo(D, IdxDeclInfo); 649 RedeclInfo.declInfo = &IdxDeclInfo; 650 RedeclInfo.entity = getIndexEntity(D); 651 } 652 653 void IndexingContext::getContainerInfo(const NamedDecl *D, 654 CXIdxContainerInfo &ContainerInfo) { 655 ContainerInfo.cursor = getCursor(D); 656 ContainerInfo.loc = getIndexLoc(D->getLocation()); 657 ContainerInfo.entity = getIndexEntity(D); 658 } 659 660 void IndexingContext::getEntityInfo(const NamedDecl *D, 661 CXIdxEntityInfo &EntityInfo, 662 StrAdapter &SA) { 663 if (IdentifierInfo *II = D->getIdentifier()) { 664 EntityInfo.name = SA.toCStr(II->getName()); 665 666 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) { 667 EntityInfo.name = 0; 668 669 } else { 670 unsigned Begin = SA.getCurSize(); 671 { 672 llvm::raw_svector_ostream OS(SA.getBuffer()); 673 D->printName(OS); 674 } 675 EntityInfo.name = SA.getCStr(Begin); 676 } 677 678 unsigned Begin = SA.getCurSize(); 679 bool Ignore = getDeclCursorUSR(D, SA.getBuffer()); 680 if (Ignore) { 681 EntityInfo.USR = ""; 682 } else { 683 EntityInfo.USR = SA.getCStr(Begin); 684 } 685 } 686 687 CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) { 688 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 689 return MakeCursorTypeRef(TD, Loc, CXTU); 690 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) 691 return MakeCursorObjCClassRef(ID, Loc, CXTU); 692 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) 693 return MakeCursorObjCProtocolRef(PD, Loc, CXTU); 694 695 //assert(0 && "not yet"); 696 return clang_getNullCursor(); 697 } 698