IndexingContext.cpp revision 3de2fc4e42f8d58f061af3ac8bb7d57e8d86a23b
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::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 51void 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 65void 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 76void 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 87void IndexingContext::invokeStartedTranslationUnit() { 88 CXIdxContainer idxCont = 0; 89 if (CB.startedTranslationUnit) 90 idxCont = CB.startedTranslationUnit(ClientData, 0); 91 addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont); 92} 93 94void IndexingContext::invokeFinishedTranslationUnit() { 95 invokeEndedContainer(Ctx->getTranslationUnitDecl()); 96} 97 98void 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 106void 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 137void 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 168void 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 185void 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 202void 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 234void 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 251void 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 269void 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 304void 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 322void 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 340void 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 371void 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 388void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc, 389 const NamedDecl *Parent, 390 const DeclContext *DC, 391 const Expr *E) { 392 if (Loc.isInvalid()) 393 return; 394 if (!CB.indexEntityReference) 395 return; 396 if (isNotFromSourceFile(D->getLocation())) 397 return; 398 399 CXIdxEntityRefInfo Info = { E ? MakeCXCursor((Stmt*)E, 400 (Decl*)cast<Decl>(DC), CXTU) 401 : getRefCursor(D, Loc), 402 getIndexLoc(Loc), 403 getIndexEntity(D), 404 getIndexEntity(Parent), 405 getIndexContainerForDC(DC) }; 406 CB.indexEntityReference(ClientData, &Info); 407} 408 409void IndexingContext::invokeStartedStatementBody(const NamedDecl *D, 410 const DeclContext *DC) { 411 const Stmt *Body = cast<Decl>(DC)->getBody(); 412 assert(Body); 413 414 CXIdxContainer idxCont = 0; 415 if (CB.startedStatementBody) { 416 CXIdxContainerInfo ContainerInfo; 417 getContainerInfo(D, ContainerInfo); 418 CXIdxStmtBodyInfo Info = { &ContainerInfo, 419 getIndexLoc(Body->getLocStart()) }; 420 421 idxCont = CB.startedStatementBody(ClientData, &Info); 422 } 423 addContainerInMap(DC, idxCont); 424} 425 426void IndexingContext::invokeStartedTagTypeDefinition(const TagDecl *D) { 427 CXIdxContainer idxCont = 0; 428 if (CB.startedTagTypeDefinition) { 429 CXIdxContainerInfo ContainerInfo; 430 getContainerInfo(D, ContainerInfo); 431 CXIdxTagTypeDefinitionInfo Info = { &ContainerInfo }; 432 433 idxCont = CB.startedTagTypeDefinition(ClientData, &Info); 434 } 435 addContainerInMap(D, idxCont); 436} 437 438void IndexingContext::invokeStartedObjCContainer(const ObjCContainerDecl *D) { 439 CXIdxContainer idxCont = 0; 440 if (CB.startedObjCContainer) { 441 CXIdxContainerInfo ContainerInfo; 442 getContainerInfo(D, ContainerInfo); 443 CXIdxObjCContainerInfo Info = { &ContainerInfo }; 444 445 idxCont = CB.startedObjCContainer(ClientData, &Info); 446 } 447 addContainerInMap(D, idxCont); 448} 449 450void IndexingContext::invokeEndedContainer(const DeclContext *DC) { 451 if (CB.endedContainer) { 452 CXIdxEndContainerInfo Info = { getIndexContainerForDC(DC), 453 getIndexLoc(cast<Decl>(DC)->getLocEnd()) }; 454 CB.endedContainer(ClientData, &Info); 455 } 456} 457 458bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const { 459 if (Loc.isInvalid()) 460 return true; 461 SourceManager &SM = Ctx->getSourceManager(); 462 SourceLocation FileLoc = SM.getFileLoc(Loc); 463 FileID FID = SM.getFileID(FileLoc); 464 return SM.getFileEntryForID(FID) == 0; 465} 466 467void IndexingContext::addContainerInMap(const DeclContext *DC, 468 CXIdxContainer container) { 469 assert(getScopedContext(DC) == DC); 470 ContainerMapTy::iterator I = ContainerMap.find(DC); 471 if (I == ContainerMap.end()) { 472 if (container) 473 ContainerMap[DC] = container; 474 return; 475 } 476 // Allow changing the container of a previously seen DeclContext so we 477 // can handle invalid user code, like a function re-definition. 478 if (container) 479 I->second = container; 480 else 481 ContainerMap.erase(I); 482} 483 484void IndexingContext::addEntityInMap(const NamedDecl *D, CXIdxEntity entity) { 485 assert(getEntityDecl(D) == D && 486 "Tried to add a non-entity (canonical) decl"); 487 assert(EntityMap.find(D) == EntityMap.end()); 488 if (entity || D->isFromASTFile()) 489 EntityMap[D] = entity; 490} 491 492CXIdxEntity IndexingContext::getIndexEntity(const NamedDecl *D) { 493 if (!D) 494 return 0; 495 D = getEntityDecl(D); 496 EntityMapTy::const_iterator I = EntityMap.find(D); 497 if (I != EntityMap.end()) 498 return I->second; 499 500 if (!D->isFromASTFile()) { 501 //assert(0 && "Entity not in map"); 502 return 0; 503 } 504 505 StrAdapter SA(this); 506 507 CXIdxEntity idxEntity = 0; 508 if (CB.importedEntity) { 509 CXIdxEntityInfo EntityInfo; 510 getEntityInfo(D, EntityInfo, SA); 511 CXIdxImportedEntityInfo Info = { &EntityInfo, 512 getCursor(D), 513 getIndexLoc(D->getLocation()), 514 /*CXIdxASTFile*/0 }; 515 idxEntity = CB.importedEntity(ClientData, &Info); 516 } 517 addEntityInMap(D, idxEntity); 518 return idxEntity; 519} 520 521const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const { 522 assert(D); 523 D = cast<NamedDecl>(D->getCanonicalDecl()); 524 525 if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(D)) { 526 if (Cat->IsClassExtension()) 527 return getEntityDecl(Cat->getClassInterface()); 528 529 } else if (const ObjCImplementationDecl * 530 ImplD = dyn_cast<ObjCImplementationDecl>(D)) { 531 return getEntityDecl(ImplD->getClassInterface()); 532 533 } else if (const ObjCCategoryImplDecl * 534 CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) { 535 return getEntityDecl(CatImplD->getCategoryDecl()); 536 } 537 538 return D; 539} 540 541const DeclContext * 542IndexingContext::getScopedContext(const DeclContext *DC) const { 543 // Local contexts are ignored for indexing. 544 const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod(); 545 if (FuncCtx) 546 return FuncCtx; 547 548 // We consider enums always scoped for indexing. 549 if (isa<TagDecl>(DC)) 550 return DC; 551 552 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 553 if (NS->isAnonymousNamespace()) 554 return getScopedContext(NS->getParent()); 555 return NS; 556 } 557 558 return DC->getRedeclContext(); 559} 560 561CXIdxContainer 562IndexingContext::getIndexContainerForDC(const DeclContext *DC) const { 563 DC = getScopedContext(DC); 564 ContainerMapTy::const_iterator I = ContainerMap.find(DC); 565// assert(I != ContainerMap.end() && 566// "Failed to include a scoped context in the container map"); 567 return I->second; 568} 569 570CXIdxFile IndexingContext::getIndexFile(const FileEntry *File) { 571 if (!File) 572 return 0; 573 if (!CB.recordFile) 574 return 0; 575 576 FileMapTy::iterator FI = FileMap.find(File); 577 if (FI != FileMap.end()) 578 return FI->second; 579 580 CXIdxFile idxFile = CB.recordFile(ClientData, (CXFile)File, 0); 581 FileMap[File] = idxFile; 582 return idxFile; 583} 584 585CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const { 586 CXIdxLoc idxLoc = { {0, 0}, 0 }; 587 if (Loc.isInvalid()) 588 return idxLoc; 589 590 idxLoc.ptr_data[0] = (void*)this; 591 idxLoc.int_data = Loc.getRawEncoding(); 592 return idxLoc; 593} 594 595void IndexingContext::translateLoc(SourceLocation Loc, 596 CXIdxFile *indexFile, CXFile *file, 597 unsigned *line, unsigned *column, 598 unsigned *offset) { 599 if (Loc.isInvalid()) 600 return; 601 602 SourceManager &SM = Ctx->getSourceManager(); 603 Loc = SM.getFileLoc(Loc); 604 605 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); 606 FileID FID = LocInfo.first; 607 unsigned FileOffset = LocInfo.second; 608 609 if (FID.isInvalid()) 610 return; 611 612 const FileEntry *FE = SM.getFileEntryForID(FID); 613 if (indexFile) 614 *indexFile = getIndexFile(FE); 615 if (file) 616 *file = (void *)FE; 617 if (line) 618 *line = SM.getLineNumber(FID, FileOffset); 619 if (column) 620 *column = SM.getColumnNumber(FID, FileOffset); 621 if (offset) 622 *offset = FileOffset; 623} 624 625void IndexingContext::getIndexedEntityInfo(const NamedDecl *D, 626 CXIdxIndexedEntityInfo &IdxEntityInfo, 627 CXIdxEntityInfo &EntityInfo, 628 CXIdxIndexedDeclInfo &IdxDeclInfo, 629 StrAdapter &SA) { 630 getEntityInfo(D, EntityInfo, SA); 631 getIndexedDeclInfo(D, IdxDeclInfo); 632 IdxEntityInfo.entityInfo = &EntityInfo; 633 IdxEntityInfo.declInfo = &IdxDeclInfo; 634} 635 636void IndexingContext::getIndexedDeclInfo(const NamedDecl *D, 637 CXIdxIndexedDeclInfo &IdxDeclInfo) { 638 IdxDeclInfo.cursor = getCursor(D); 639 IdxDeclInfo.loc = getIndexLoc(D->getLocation()); 640 IdxDeclInfo.container = getIndexContainer(D); 641} 642 643void IndexingContext::getIndexedRedeclInfo(const NamedDecl *D, 644 CXIdxIndexedRedeclInfo &RedeclInfo, 645 CXIdxIndexedDeclInfo &IdxDeclInfo) { 646 getIndexedDeclInfo(D, IdxDeclInfo); 647 RedeclInfo.declInfo = &IdxDeclInfo; 648 RedeclInfo.entity = getIndexEntity(D); 649} 650 651void IndexingContext::getContainerInfo(const NamedDecl *D, 652 CXIdxContainerInfo &ContainerInfo) { 653 ContainerInfo.cursor = getCursor(D); 654 ContainerInfo.loc = getIndexLoc(D->getLocation()); 655 ContainerInfo.entity = getIndexEntity(D); 656} 657 658void IndexingContext::getEntityInfo(const NamedDecl *D, 659 CXIdxEntityInfo &EntityInfo, 660 StrAdapter &SA) { 661 if (IdentifierInfo *II = D->getIdentifier()) { 662 EntityInfo.name = SA.toCStr(II->getName()); 663 664 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) { 665 EntityInfo.name = 0; 666 667 } else { 668 unsigned Begin = SA.getCurSize(); 669 { 670 llvm::raw_svector_ostream OS(SA.getBuffer()); 671 D->printName(OS); 672 } 673 EntityInfo.name = SA.getCStr(Begin); 674 } 675 676 unsigned Begin = SA.getCurSize(); 677 bool Ignore = getDeclCursorUSR(D, SA.getBuffer()); 678 if (Ignore) { 679 EntityInfo.USR = ""; 680 } else { 681 EntityInfo.USR = SA.getCStr(Begin); 682 } 683} 684 685CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) { 686 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D)) 687 return MakeCursorTypeRef(TD, Loc, CXTU); 688 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) 689 return MakeCursorObjCClassRef(ID, Loc, CXTU); 690 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) 691 return MakeCursorObjCProtocolRef(PD, Loc, CXTU); 692 693 //assert(0 && "not yet"); 694 return clang_getNullCursor(); 695} 696