IndexingContext.cpp revision aca19be8731fc31cff68702de0dc7f30ce908979
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                                      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
411void 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
428void 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
440void 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
452void 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
460bool 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
469void 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
486void 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
494CXIdxEntity 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
523const 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
543const DeclContext *
544IndexingContext::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
563CXIdxContainer
564IndexingContext::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
572CXIdxFile 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
587CXIdxLoc 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
597void 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
627void 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
638void 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
645void 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
653void 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
660void 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
687CXCursor 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