IndexingContext.cpp revision 4e7064fa7e344e8f87a5b8457e96dfdd252c4a9e
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                                    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