xref: /minix3/external/bsd/llvm/dist/clang/tools/libclang/IndexingContext.cpp (revision eda6f5931d42c77e1480347b1fc3eef2f8d33806)
1 //===- IndexingContext.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 "CIndexDiagnostic.h"
12 #include "CXTranslationUnit.h"
13 #include "clang/AST/Attr.h"
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/DeclTemplate.h"
16 #include "clang/Frontend/ASTUnit.h"
17 
18 using namespace clang;
19 using namespace cxindex;
20 using namespace cxcursor;
21 
22 IndexingContext::ObjCProtocolListInfo::ObjCProtocolListInfo(
23                                     const ObjCProtocolList &ProtList,
24                                     IndexingContext &IdxCtx,
25                                     ScratchAlloc &SA) {
26   ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
27   for (ObjCInterfaceDecl::protocol_iterator
28          I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
29     SourceLocation Loc = *LI;
30     ObjCProtocolDecl *PD = *I;
31     ProtEntities.push_back(EntityInfo());
32     IdxCtx.getEntityInfo(PD, ProtEntities.back(), SA);
33     CXIdxObjCProtocolRefInfo ProtInfo = { 0,
34                                 MakeCursorObjCProtocolRef(PD, Loc, IdxCtx.CXTU),
35                                 IdxCtx.getIndexLoc(Loc) };
36     ProtInfos.push_back(ProtInfo);
37 
38     if (IdxCtx.shouldSuppressRefs())
39       IdxCtx.markEntityOccurrenceInFile(PD, Loc);
40   }
41 
42   for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)
43     ProtInfos[i].protocol = &ProtEntities[i];
44 
45   for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)
46     Prots.push_back(&ProtInfos[i]);
47 }
48 
49 
50 IBOutletCollectionInfo::IBOutletCollectionInfo(
51                                           const IBOutletCollectionInfo &other)
52   : AttrInfo(CXIdxAttr_IBOutletCollection, other.cursor, other.loc, other.A) {
53 
54   IBCollInfo.attrInfo = this;
55   IBCollInfo.classCursor = other.IBCollInfo.classCursor;
56   IBCollInfo.classLoc = other.IBCollInfo.classLoc;
57   if (other.IBCollInfo.objcClass) {
58     ClassInfo = other.ClassInfo;
59     IBCollInfo.objcClass = &ClassInfo;
60   } else
61     IBCollInfo.objcClass = 0;
62 }
63 
64 AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
65   : SA(IdxCtx), ref_cnt(0) {
66 
67   if (!D->hasAttrs())
68     return;
69 
70   for (AttrVec::const_iterator AttrI = D->attr_begin(), AttrE = D->attr_end();
71          AttrI != AttrE; ++AttrI) {
72     const Attr *A = *AttrI;
73     CXCursor C = MakeCXCursor(A, D, IdxCtx.CXTU);
74     CXIdxLoc Loc =  IdxCtx.getIndexLoc(A->getLocation());
75     switch (C.kind) {
76     default:
77       Attrs.push_back(AttrInfo(CXIdxAttr_Unexposed, C, Loc, A));
78       break;
79     case CXCursor_IBActionAttr:
80       Attrs.push_back(AttrInfo(CXIdxAttr_IBAction, C, Loc, A));
81       break;
82     case CXCursor_IBOutletAttr:
83       Attrs.push_back(AttrInfo(CXIdxAttr_IBOutlet, C, Loc, A));
84       break;
85     case CXCursor_IBOutletCollectionAttr:
86       IBCollAttrs.push_back(IBOutletCollectionInfo(C, Loc, A));
87       break;
88     }
89   }
90 
91   for (unsigned i = 0, e = IBCollAttrs.size(); i != e; ++i) {
92     IBOutletCollectionInfo &IBInfo = IBCollAttrs[i];
93     CXAttrs.push_back(&IBInfo);
94 
95     const IBOutletCollectionAttr *
96       IBAttr = cast<IBOutletCollectionAttr>(IBInfo.A);
97     SourceLocation InterfaceLocStart =
98         IBAttr->getInterfaceLoc()->getTypeLoc().getLocStart();
99     IBInfo.IBCollInfo.attrInfo = &IBInfo;
100     IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(InterfaceLocStart);
101     IBInfo.IBCollInfo.objcClass = 0;
102     IBInfo.IBCollInfo.classCursor = clang_getNullCursor();
103     QualType Ty = IBAttr->getInterface();
104     if (const ObjCObjectType *ObjectTy = Ty->getAs<ObjCObjectType>()) {
105       if (const ObjCInterfaceDecl *InterD = ObjectTy->getInterface()) {
106         IdxCtx.getEntityInfo(InterD, IBInfo.ClassInfo, SA);
107         IBInfo.IBCollInfo.objcClass = &IBInfo.ClassInfo;
108         IBInfo.IBCollInfo.classCursor =
109             MakeCursorObjCClassRef(InterD, InterfaceLocStart, IdxCtx.CXTU);
110       }
111     }
112   }
113 
114   for (unsigned i = 0, e = Attrs.size(); i != e; ++i)
115     CXAttrs.push_back(&Attrs[i]);
116 }
117 
118 IntrusiveRefCntPtr<AttrListInfo>
119 AttrListInfo::create(const Decl *D, IndexingContext &IdxCtx) {
120   ScratchAlloc SA(IdxCtx);
121   AttrListInfo *attrs = SA.allocate<AttrListInfo>();
122   return new (attrs) AttrListInfo(D, IdxCtx);
123 }
124 
125 IndexingContext::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
126                                    IndexingContext &IdxCtx,
127                                    ScratchAlloc &SA) {
128   for (CXXRecordDecl::base_class_const_iterator
129          I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
130     const CXXBaseSpecifier &Base = *I;
131     BaseEntities.push_back(EntityInfo());
132     const NamedDecl *BaseD = 0;
133     QualType T = Base.getType();
134     SourceLocation Loc = getBaseLoc(Base);
135 
136     if (const TypedefType *TDT = T->getAs<TypedefType>()) {
137       BaseD = TDT->getDecl();
138     } else if (const TemplateSpecializationType *
139           TST = T->getAs<TemplateSpecializationType>()) {
140       BaseD = TST->getTemplateName().getAsTemplateDecl();
141     } else if (const RecordType *RT = T->getAs<RecordType>()) {
142       BaseD = RT->getDecl();
143     }
144 
145     if (BaseD)
146       IdxCtx.getEntityInfo(BaseD, BaseEntities.back(), SA);
147     CXIdxBaseClassInfo BaseInfo = { 0,
148                          MakeCursorCXXBaseSpecifier(&Base, IdxCtx.CXTU),
149                          IdxCtx.getIndexLoc(Loc) };
150     BaseInfos.push_back(BaseInfo);
151   }
152 
153   for (unsigned i = 0, e = BaseInfos.size(); i != e; ++i) {
154     if (BaseEntities[i].name && BaseEntities[i].USR)
155       BaseInfos[i].base = &BaseEntities[i];
156   }
157 
158   for (unsigned i = 0, e = BaseInfos.size(); i != e; ++i)
159     CXBases.push_back(&BaseInfos[i]);
160 }
161 
162 SourceLocation IndexingContext::CXXBasesListInfo::getBaseLoc(
163                                            const CXXBaseSpecifier &Base) const {
164   SourceLocation Loc = Base.getSourceRange().getBegin();
165   TypeLoc TL;
166   if (Base.getTypeSourceInfo())
167     TL = Base.getTypeSourceInfo()->getTypeLoc();
168   if (TL.isNull())
169     return Loc;
170 
171   if (QualifiedTypeLoc QL = TL.getAs<QualifiedTypeLoc>())
172     TL = QL.getUnqualifiedLoc();
173 
174   if (ElaboratedTypeLoc EL = TL.getAs<ElaboratedTypeLoc>())
175     return EL.getNamedTypeLoc().getBeginLoc();
176   if (DependentNameTypeLoc DL = TL.getAs<DependentNameTypeLoc>())
177     return DL.getNameLoc();
178   if (DependentTemplateSpecializationTypeLoc DTL =
179           TL.getAs<DependentTemplateSpecializationTypeLoc>())
180     return DTL.getTemplateNameLoc();
181 
182   return Loc;
183 }
184 
185 const char *ScratchAlloc::toCStr(StringRef Str) {
186   if (Str.empty())
187     return "";
188   if (Str.data()[Str.size()] == '\0')
189     return Str.data();
190   return copyCStr(Str);
191 }
192 
193 const char *ScratchAlloc::copyCStr(StringRef Str) {
194   char *buf = IdxCtx.StrScratch.Allocate<char>(Str.size() + 1);
195   std::uninitialized_copy(Str.begin(), Str.end(), buf);
196   buf[Str.size()] = '\0';
197   return buf;
198 }
199 
200 void IndexingContext::setASTContext(ASTContext &ctx) {
201   Ctx = &ctx;
202   cxtu::getASTUnit(CXTU)->setASTContext(&ctx);
203 }
204 
205 void IndexingContext::setPreprocessor(Preprocessor &PP) {
206   cxtu::getASTUnit(CXTU)->setPreprocessor(&PP);
207 }
208 
209 bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
210   assert(D);
211 
212   if (!D->getParentFunctionOrMethod())
213     return false;
214 
215   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
216     switch (ND->getFormalLinkage()) {
217     case NoLinkage:
218     case VisibleNoLinkage:
219     case InternalLinkage:
220       return true;
221     case UniqueExternalLinkage:
222       llvm_unreachable("Not a sema linkage");
223     case ExternalLinkage:
224       return false;
225     }
226   }
227 
228   return true;
229 }
230 
231 bool IndexingContext::shouldAbort() {
232   if (!CB.abortQuery)
233     return false;
234   return CB.abortQuery(ClientData, 0);
235 }
236 
237 void IndexingContext::enteredMainFile(const FileEntry *File) {
238   if (File && CB.enteredMainFile) {
239     CXIdxClientFile idxFile =
240       CB.enteredMainFile(ClientData,
241                          static_cast<CXFile>(const_cast<FileEntry *>(File)), 0);
242     FileMap[File] = idxFile;
243   }
244 }
245 
246 void IndexingContext::ppIncludedFile(SourceLocation hashLoc,
247                                      StringRef filename,
248                                      const FileEntry *File,
249                                      bool isImport, bool isAngled,
250                                      bool isModuleImport) {
251   if (!CB.ppIncludedFile)
252     return;
253 
254   ScratchAlloc SA(*this);
255   CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
256                                  SA.toCStr(filename),
257                                  static_cast<CXFile>(
258                                    const_cast<FileEntry *>(File)),
259                                  isImport, isAngled, isModuleImport };
260   CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info);
261   FileMap[File] = idxFile;
262 }
263 
264 void IndexingContext::importedModule(const ImportDecl *ImportD) {
265   if (!CB.importedASTFile)
266     return;
267 
268   Module *Mod = ImportD->getImportedModule();
269   if (!Mod)
270     return;
271   std::string ModuleName = Mod->getFullModuleName();
272 
273   CXIdxImportedASTFileInfo Info = {
274                                     static_cast<CXFile>(
275                                     const_cast<FileEntry *>(Mod->getASTFile())),
276                                     Mod,
277                                     getIndexLoc(ImportD->getLocation()),
278                                     ImportD->isImplicit()
279                                   };
280   CXIdxClientASTFile astFile = CB.importedASTFile(ClientData, &Info);
281   (void)astFile;
282 }
283 
284 void IndexingContext::importedPCH(const FileEntry *File) {
285   if (!CB.importedASTFile)
286     return;
287 
288   CXIdxImportedASTFileInfo Info = {
289                                     static_cast<CXFile>(
290                                       const_cast<FileEntry *>(File)),
291                                     /*module=*/NULL,
292                                     getIndexLoc(SourceLocation()),
293                                     /*isImplicit=*/false
294                                   };
295   CXIdxClientASTFile astFile = CB.importedASTFile(ClientData, &Info);
296   (void)astFile;
297 }
298 
299 void IndexingContext::startedTranslationUnit() {
300   CXIdxClientContainer idxCont = 0;
301   if (CB.startedTranslationUnit)
302     idxCont = CB.startedTranslationUnit(ClientData, 0);
303   addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
304 }
305 
306 void IndexingContext::handleDiagnosticSet(CXDiagnostic CXDiagSet) {
307   if (!CB.diagnostic)
308     return;
309 
310   CB.diagnostic(ClientData, CXDiagSet, 0);
311 }
312 
313 bool IndexingContext::handleDecl(const NamedDecl *D,
314                                  SourceLocation Loc, CXCursor Cursor,
315                                  DeclInfo &DInfo,
316                                  const DeclContext *LexicalDC) {
317   if (!CB.indexDeclaration || !D)
318     return false;
319   if (D->isImplicit() && shouldIgnoreIfImplicit(D))
320     return false;
321 
322   ScratchAlloc SA(*this);
323   getEntityInfo(D, DInfo.EntInfo, SA);
324   if ((!shouldIndexFunctionLocalSymbols() && !DInfo.EntInfo.USR)
325       || Loc.isInvalid())
326     return false;
327 
328   if (!LexicalDC)
329     LexicalDC = D->getLexicalDeclContext();
330 
331   if (shouldSuppressRefs())
332     markEntityOccurrenceInFile(D, Loc);
333 
334   DInfo.entityInfo = &DInfo.EntInfo;
335   DInfo.cursor = Cursor;
336   DInfo.loc = getIndexLoc(Loc);
337   DInfo.isImplicit = D->isImplicit();
338 
339   DInfo.attributes = DInfo.EntInfo.attributes;
340   DInfo.numAttributes = DInfo.EntInfo.numAttributes;
341 
342   getContainerInfo(D->getDeclContext(), DInfo.SemanticContainer);
343   DInfo.semanticContainer = &DInfo.SemanticContainer;
344 
345   if (LexicalDC == D->getDeclContext()) {
346     DInfo.lexicalContainer = &DInfo.SemanticContainer;
347   } else if (isTemplateImplicitInstantiation(D)) {
348     // Implicit instantiations have the lexical context of where they were
349     // instantiated first. We choose instead the semantic context because:
350     // 1) at the time that we see the instantiation we have not seen the
351     //   function where it occurred yet.
352     // 2) the lexical context of the first instantiation is not useful
353     //   information anyway.
354     DInfo.lexicalContainer = &DInfo.SemanticContainer;
355   } else {
356     getContainerInfo(LexicalDC, DInfo.LexicalContainer);
357     DInfo.lexicalContainer = &DInfo.LexicalContainer;
358   }
359 
360   if (DInfo.isContainer) {
361     getContainerInfo(getEntityContainer(D), DInfo.DeclAsContainer);
362     DInfo.declAsContainer = &DInfo.DeclAsContainer;
363   }
364 
365   CB.indexDeclaration(ClientData, &DInfo);
366   return true;
367 }
368 
369 bool IndexingContext::handleObjCContainer(const ObjCContainerDecl *D,
370                                           SourceLocation Loc, CXCursor Cursor,
371                                           ObjCContainerDeclInfo &ContDInfo) {
372   ContDInfo.ObjCContDeclInfo.declInfo = &ContDInfo;
373   return handleDecl(D, Loc, Cursor, ContDInfo);
374 }
375 
376 bool IndexingContext::handleFunction(const FunctionDecl *D) {
377   bool isDef = D->isThisDeclarationADefinition();
378   bool isContainer = isDef;
379   bool isSkipped = false;
380   if (D->hasSkippedBody()) {
381     isSkipped = true;
382     isDef = true;
383     isContainer = false;
384   }
385 
386   DeclInfo DInfo(!D->isFirstDecl(), isDef, isContainer);
387   if (isSkipped)
388     DInfo.flags |= CXIdxDeclFlag_Skipped;
389   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
390 }
391 
392 bool IndexingContext::handleVar(const VarDecl *D) {
393   DeclInfo DInfo(!D->isFirstDecl(), D->isThisDeclarationADefinition(),
394                  /*isContainer=*/false);
395   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
396 }
397 
398 bool IndexingContext::handleField(const FieldDecl *D) {
399   DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
400                  /*isContainer=*/false);
401   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
402 }
403 
404 bool IndexingContext::handleMSProperty(const MSPropertyDecl *D) {
405   DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
406                  /*isContainer=*/false);
407   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
408 }
409 
410 bool IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
411   DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
412                  /*isContainer=*/false);
413   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
414 }
415 
416 bool IndexingContext::handleTagDecl(const TagDecl *D) {
417   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(D))
418     return handleCXXRecordDecl(CXXRD, D);
419 
420   DeclInfo DInfo(!D->isFirstDecl(), D->isThisDeclarationADefinition(),
421                  D->isThisDeclarationADefinition());
422   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
423 }
424 
425 bool IndexingContext::handleTypedefName(const TypedefNameDecl *D) {
426   DeclInfo DInfo(!D->isFirstDecl(), /*isDefinition=*/true,
427                  /*isContainer=*/false);
428   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
429 }
430 
431 bool IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
432   // For @class forward declarations, suppress them the same way as references.
433   if (!D->isThisDeclarationADefinition()) {
434     if (shouldSuppressRefs() && markEntityOccurrenceInFile(D, D->getLocation()))
435       return false; // already occurred.
436 
437     // FIXME: This seems like the wrong definition for redeclaration.
438     bool isRedeclaration = D->hasDefinition() || D->getPreviousDecl();
439     ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true, isRedeclaration,
440                                     /*isImplementation=*/false);
441     return handleObjCContainer(D, D->getLocation(),
442                                MakeCursorObjCClassRef(D, D->getLocation(),
443                                                       CXTU),
444                                ContDInfo);
445   }
446 
447   ScratchAlloc SA(*this);
448 
449   CXIdxBaseClassInfo BaseClass;
450   EntityInfo BaseEntity;
451   BaseClass.cursor = clang_getNullCursor();
452   if (ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
453     getEntityInfo(SuperD, BaseEntity, SA);
454     SourceLocation SuperLoc = D->getSuperClassLoc();
455     BaseClass.base = &BaseEntity;
456     BaseClass.cursor = MakeCursorObjCSuperClassRef(SuperD, SuperLoc, CXTU);
457     BaseClass.loc = getIndexLoc(SuperLoc);
458 
459     if (shouldSuppressRefs())
460       markEntityOccurrenceInFile(SuperD, SuperLoc);
461   }
462 
463   ObjCProtocolList EmptyProtoList;
464   ObjCProtocolListInfo ProtInfo(D->isThisDeclarationADefinition()
465                                   ? D->getReferencedProtocols()
466                                   : EmptyProtoList,
467                                 *this, SA);
468 
469   ObjCInterfaceDeclInfo InterInfo(D);
470   InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();
471   InterInfo.ObjCInterDeclInfo.containerInfo = &InterInfo.ObjCContDeclInfo;
472   InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass : 0;
473   InterInfo.ObjCInterDeclInfo.protocols = &InterInfo.ObjCProtoListInfo;
474 
475   return handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);
476 }
477 
478 bool IndexingContext::handleObjCImplementation(
479                                               const ObjCImplementationDecl *D) {
480   ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/false,
481                       /*isRedeclaration=*/true,
482                       /*isImplementation=*/true);
483   return handleObjCContainer(D, D->getLocation(), getCursor(D), ContDInfo);
484 }
485 
486 bool IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
487   if (!D->isThisDeclarationADefinition()) {
488     if (shouldSuppressRefs() && markEntityOccurrenceInFile(D, D->getLocation()))
489       return false; // already occurred.
490 
491     // FIXME: This seems like the wrong definition for redeclaration.
492     bool isRedeclaration = D->hasDefinition() || D->getPreviousDecl();
493     ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true,
494                                     isRedeclaration,
495                                     /*isImplementation=*/false);
496     return handleObjCContainer(D, D->getLocation(),
497                                MakeCursorObjCProtocolRef(D, D->getLocation(),
498                                                          CXTU),
499                                ContDInfo);
500   }
501 
502   ScratchAlloc SA(*this);
503   ObjCProtocolList EmptyProtoList;
504   ObjCProtocolListInfo ProtListInfo(D->isThisDeclarationADefinition()
505                                       ? D->getReferencedProtocols()
506                                       : EmptyProtoList,
507                                     *this, SA);
508 
509   ObjCProtocolDeclInfo ProtInfo(D);
510   ProtInfo.ObjCProtoRefListInfo = ProtListInfo.getListInfo();
511 
512   return handleObjCContainer(D, D->getLocation(), getCursor(D), ProtInfo);
513 }
514 
515 bool IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
516   ScratchAlloc SA(*this);
517 
518   ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
519   EntityInfo ClassEntity;
520   const ObjCInterfaceDecl *IFaceD = D->getClassInterface();
521   SourceLocation ClassLoc = D->getLocation();
522   SourceLocation CategoryLoc = D->IsClassExtension() ? ClassLoc
523                                                      : D->getCategoryNameLoc();
524   getEntityInfo(IFaceD, ClassEntity, SA);
525 
526   if (shouldSuppressRefs())
527     markEntityOccurrenceInFile(IFaceD, ClassLoc);
528 
529   ObjCProtocolListInfo ProtInfo(D->getReferencedProtocols(), *this, SA);
530 
531   CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
532   if (IFaceD) {
533     CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
534     CatDInfo.ObjCCatDeclInfo.classCursor =
535         MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
536   } else {
537     CatDInfo.ObjCCatDeclInfo.objcClass = 0;
538     CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
539   }
540   CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
541   CatDInfo.ObjCProtoListInfo = ProtInfo.getListInfo();
542   CatDInfo.ObjCCatDeclInfo.protocols = &CatDInfo.ObjCProtoListInfo;
543 
544   return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
545 }
546 
547 bool IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
548   ScratchAlloc SA(*this);
549 
550   const ObjCCategoryDecl *CatD = D->getCategoryDecl();
551   ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);
552   EntityInfo ClassEntity;
553   const ObjCInterfaceDecl *IFaceD = CatD->getClassInterface();
554   SourceLocation ClassLoc = D->getLocation();
555   SourceLocation CategoryLoc = D->getCategoryNameLoc();
556   getEntityInfo(IFaceD, ClassEntity, SA);
557 
558   if (shouldSuppressRefs())
559     markEntityOccurrenceInFile(IFaceD, ClassLoc);
560 
561   CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
562   if (IFaceD) {
563     CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
564     CatDInfo.ObjCCatDeclInfo.classCursor =
565         MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
566   } else {
567     CatDInfo.ObjCCatDeclInfo.objcClass = 0;
568     CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
569   }
570   CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
571   CatDInfo.ObjCCatDeclInfo.protocols = 0;
572 
573   return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
574 }
575 
576 bool IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
577   bool isDef = D->isThisDeclarationADefinition();
578   bool isContainer = isDef;
579   bool isSkipped = false;
580   if (D->hasSkippedBody()) {
581     isSkipped = true;
582     isDef = true;
583     isContainer = false;
584   }
585 
586   DeclInfo DInfo(!D->isCanonicalDecl(), isDef, isContainer);
587   if (isSkipped)
588     DInfo.flags |= CXIdxDeclFlag_Skipped;
589   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
590 }
591 
592 bool IndexingContext::handleSynthesizedObjCProperty(
593                                                 const ObjCPropertyImplDecl *D) {
594   ObjCPropertyDecl *PD = D->getPropertyDecl();
595   return handleReference(PD, D->getLocation(), getCursor(D), 0, D->getDeclContext());
596 }
597 
598 bool IndexingContext::handleSynthesizedObjCMethod(const ObjCMethodDecl *D,
599                                                   SourceLocation Loc,
600                                                  const DeclContext *LexicalDC) {
601   DeclInfo DInfo(/*isRedeclaration=*/true, /*isDefinition=*/true,
602                  /*isContainer=*/false);
603   return handleDecl(D, Loc, getCursor(D), DInfo, LexicalDC);
604 }
605 
606 bool IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
607   ScratchAlloc SA(*this);
608 
609   ObjCPropertyDeclInfo DInfo;
610   EntityInfo GetterEntity;
611   EntityInfo SetterEntity;
612 
613   DInfo.ObjCPropDeclInfo.declInfo = &DInfo;
614 
615   if (ObjCMethodDecl *Getter = D->getGetterMethodDecl()) {
616     getEntityInfo(Getter, GetterEntity, SA);
617     DInfo.ObjCPropDeclInfo.getter = &GetterEntity;
618   } else {
619     DInfo.ObjCPropDeclInfo.getter = 0;
620   }
621   if (ObjCMethodDecl *Setter = D->getSetterMethodDecl()) {
622     getEntityInfo(Setter, SetterEntity, SA);
623     DInfo.ObjCPropDeclInfo.setter = &SetterEntity;
624   } else {
625     DInfo.ObjCPropDeclInfo.setter = 0;
626   }
627 
628   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
629 }
630 
631 bool IndexingContext::handleNamespace(const NamespaceDecl *D) {
632   DeclInfo DInfo(/*isRedeclaration=*/!D->isOriginalNamespace(),
633                  /*isDefinition=*/true,
634                  /*isContainer=*/true);
635   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
636 }
637 
638 bool IndexingContext::handleClassTemplate(const ClassTemplateDecl *D) {
639   return handleCXXRecordDecl(D->getTemplatedDecl(), D);
640 }
641 
642 bool IndexingContext::handleFunctionTemplate(const FunctionTemplateDecl *D) {
643   DeclInfo DInfo(/*isRedeclaration=*/!D->isCanonicalDecl(),
644                  /*isDefinition=*/D->isThisDeclarationADefinition(),
645                  /*isContainer=*/D->isThisDeclarationADefinition());
646   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
647 }
648 
649 bool IndexingContext::handleTypeAliasTemplate(const TypeAliasTemplateDecl *D) {
650   DeclInfo DInfo(/*isRedeclaration=*/!D->isCanonicalDecl(),
651                  /*isDefinition=*/true, /*isContainer=*/false);
652   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
653 }
654 
655 bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
656                                       const NamedDecl *Parent,
657                                       const DeclContext *DC,
658                                       const Expr *E,
659                                       CXIdxEntityRefKind Kind) {
660   if (!D)
661     return false;
662 
663   CXCursor Cursor = E ? MakeCXCursor(E, cast<Decl>(DC), CXTU)
664                       : getRefCursor(D, Loc);
665   return handleReference(D, Loc, Cursor, Parent, DC, E, Kind);
666 }
667 
668 bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
669                                       CXCursor Cursor,
670                                       const NamedDecl *Parent,
671                                       const DeclContext *DC,
672                                       const Expr *E,
673                                       CXIdxEntityRefKind Kind) {
674   if (!CB.indexEntityReference)
675     return false;
676 
677   if (!D)
678     return false;
679   if (Loc.isInvalid())
680     return false;
681   if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
682     return false;
683   if (isNotFromSourceFile(D->getLocation()))
684     return false;
685   if (D->isImplicit() && shouldIgnoreIfImplicit(D))
686     return false;
687 
688   if (shouldSuppressRefs()) {
689     if (markEntityOccurrenceInFile(D, Loc))
690       return false; // already occurred.
691   }
692 
693   ScratchAlloc SA(*this);
694   EntityInfo RefEntity, ParentEntity;
695   getEntityInfo(D, RefEntity, SA);
696   if (!RefEntity.USR)
697     return false;
698 
699   getEntityInfo(Parent, ParentEntity, SA);
700 
701   ContainerInfo Container;
702   getContainerInfo(DC, Container);
703 
704   CXIdxEntityRefInfo Info = { Kind,
705                               Cursor,
706                               getIndexLoc(Loc),
707                               &RefEntity,
708                               Parent ? &ParentEntity : 0,
709                               &Container };
710   CB.indexEntityReference(ClientData, &Info);
711   return true;
712 }
713 
714 bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
715   if (Loc.isInvalid())
716     return true;
717   SourceManager &SM = Ctx->getSourceManager();
718   SourceLocation FileLoc = SM.getFileLoc(Loc);
719   FileID FID = SM.getFileID(FileLoc);
720   return SM.getFileEntryForID(FID) == 0;
721 }
722 
723 void IndexingContext::addContainerInMap(const DeclContext *DC,
724                                         CXIdxClientContainer container) {
725   if (!DC)
726     return;
727 
728   ContainerMapTy::iterator I = ContainerMap.find(DC);
729   if (I == ContainerMap.end()) {
730     if (container)
731       ContainerMap[DC] = container;
732     return;
733   }
734   // Allow changing the container of a previously seen DeclContext so we
735   // can handle invalid user code, like a function re-definition.
736   if (container)
737     I->second = container;
738   else
739     ContainerMap.erase(I);
740 }
741 
742 CXIdxClientEntity IndexingContext::getClientEntity(const Decl *D) const {
743   if (!D)
744     return 0;
745   EntityMapTy::const_iterator I = EntityMap.find(D);
746   if (I == EntityMap.end())
747     return 0;
748   return I->second;
749 }
750 
751 void IndexingContext::setClientEntity(const Decl *D, CXIdxClientEntity client) {
752   if (!D)
753     return;
754   EntityMap[D] = client;
755 }
756 
757 bool IndexingContext::handleCXXRecordDecl(const CXXRecordDecl *RD,
758                                           const NamedDecl *OrigD) {
759   if (RD->isThisDeclarationADefinition()) {
760     ScratchAlloc SA(*this);
761     CXXClassDeclInfo CXXDInfo(/*isRedeclaration=*/!OrigD->isCanonicalDecl(),
762                            /*isDefinition=*/RD->isThisDeclarationADefinition());
763     CXXBasesListInfo BaseList(RD, *this, SA);
764     CXXDInfo.CXXClassInfo.declInfo = &CXXDInfo;
765     CXXDInfo.CXXClassInfo.bases = BaseList.getBases();
766     CXXDInfo.CXXClassInfo.numBases = BaseList.getNumBases();
767 
768     if (shouldSuppressRefs()) {
769       // Go through bases and mark them as referenced.
770       for (unsigned i = 0, e = BaseList.getNumBases(); i != e; ++i) {
771         const CXIdxBaseClassInfo *baseInfo = BaseList.getBases()[i];
772         if (baseInfo->base) {
773           const NamedDecl *BaseD = BaseList.BaseEntities[i].Dcl;
774           SourceLocation
775             Loc = SourceLocation::getFromRawEncoding(baseInfo->loc.int_data);
776           markEntityOccurrenceInFile(BaseD, Loc);
777         }
778       }
779     }
780 
781     return handleDecl(OrigD, OrigD->getLocation(), getCursor(OrigD), CXXDInfo);
782   }
783 
784   DeclInfo DInfo(/*isRedeclaration=*/!OrigD->isCanonicalDecl(),
785                  /*isDefinition=*/RD->isThisDeclarationADefinition(),
786                  /*isContainer=*/RD->isThisDeclarationADefinition());
787   return handleDecl(OrigD, OrigD->getLocation(), getCursor(OrigD), DInfo);
788 }
789 
790 bool IndexingContext::markEntityOccurrenceInFile(const NamedDecl *D,
791                                                  SourceLocation Loc) {
792   if (!D || Loc.isInvalid())
793     return true;
794 
795   SourceManager &SM = Ctx->getSourceManager();
796   D = getEntityDecl(D);
797 
798   std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SM.getFileLoc(Loc));
799   FileID FID = LocInfo.first;
800   if (FID.isInvalid())
801     return true;
802 
803   const FileEntry *FE = SM.getFileEntryForID(FID);
804   if (!FE)
805     return true;
806   RefFileOccurence RefOccur(FE, D);
807   std::pair<llvm::DenseSet<RefFileOccurence>::iterator, bool>
808   res = RefFileOccurences.insert(RefOccur);
809   if (!res.second)
810     return true; // already in map.
811 
812   return false;
813 }
814 
815 const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
816   assert(D);
817   D = cast<NamedDecl>(D->getCanonicalDecl());
818 
819   if (const ObjCImplementationDecl *
820                ImplD = dyn_cast<ObjCImplementationDecl>(D)) {
821     return getEntityDecl(ImplD->getClassInterface());
822 
823   } else if (const ObjCCategoryImplDecl *
824                CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {
825     return getEntityDecl(CatImplD->getCategoryDecl());
826   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
827     if (FunctionTemplateDecl *TemplD = FD->getDescribedFunctionTemplate())
828       return getEntityDecl(TemplD);
829   } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
830     if (ClassTemplateDecl *TemplD = RD->getDescribedClassTemplate())
831       return getEntityDecl(TemplD);
832   }
833 
834   return D;
835 }
836 
837 const DeclContext *
838 IndexingContext::getEntityContainer(const Decl *D) const {
839   const DeclContext *DC = dyn_cast<DeclContext>(D);
840   if (DC)
841     return DC;
842 
843   if (const ClassTemplateDecl *ClassTempl = dyn_cast<ClassTemplateDecl>(D)) {
844     DC = ClassTempl->getTemplatedDecl();
845   } else if (const FunctionTemplateDecl *
846           FuncTempl = dyn_cast<FunctionTemplateDecl>(D)) {
847     DC = FuncTempl->getTemplatedDecl();
848   }
849 
850   return DC;
851 }
852 
853 CXIdxClientContainer
854 IndexingContext::getClientContainerForDC(const DeclContext *DC) const {
855   if (!DC)
856     return 0;
857 
858   ContainerMapTy::const_iterator I = ContainerMap.find(DC);
859   if (I == ContainerMap.end())
860     return 0;
861 
862   return I->second;
863 }
864 
865 CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) {
866   if (!File)
867     return 0;
868 
869   FileMapTy::iterator FI = FileMap.find(File);
870   if (FI != FileMap.end())
871     return FI->second;
872 
873   return 0;
874 }
875 
876 CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
877   CXIdxLoc idxLoc =  { {0, 0}, 0 };
878   if (Loc.isInvalid())
879     return idxLoc;
880 
881   idxLoc.ptr_data[0] = const_cast<IndexingContext *>(this);
882   idxLoc.int_data = Loc.getRawEncoding();
883   return idxLoc;
884 }
885 
886 void IndexingContext::translateLoc(SourceLocation Loc,
887                                    CXIdxClientFile *indexFile, CXFile *file,
888                                    unsigned *line, unsigned *column,
889                                    unsigned *offset) {
890   if (Loc.isInvalid())
891     return;
892 
893   SourceManager &SM = Ctx->getSourceManager();
894   Loc = SM.getFileLoc(Loc);
895 
896   std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
897   FileID FID = LocInfo.first;
898   unsigned FileOffset = LocInfo.second;
899 
900   if (FID.isInvalid())
901     return;
902 
903   const FileEntry *FE = SM.getFileEntryForID(FID);
904   if (indexFile)
905     *indexFile = getIndexFile(FE);
906   if (file)
907     *file = const_cast<FileEntry *>(FE);
908   if (line)
909     *line = SM.getLineNumber(FID, FileOffset);
910   if (column)
911     *column = SM.getColumnNumber(FID, FileOffset);
912   if (offset)
913     *offset = FileOffset;
914 }
915 
916 void IndexingContext::getEntityInfo(const NamedDecl *D,
917                                     EntityInfo &EntityInfo,
918                                     ScratchAlloc &SA) {
919   if (!D)
920     return;
921 
922   D = getEntityDecl(D);
923   EntityInfo.cursor = getCursor(D);
924   EntityInfo.Dcl = D;
925   EntityInfo.IndexCtx = this;
926   EntityInfo.kind = CXIdxEntity_Unexposed;
927   EntityInfo.templateKind = CXIdxEntity_NonTemplate;
928   EntityInfo.lang = CXIdxEntityLang_C;
929 
930   if (D->hasAttrs()) {
931     EntityInfo.AttrList = AttrListInfo::create(D, *this);
932     EntityInfo.attributes = EntityInfo.AttrList->getAttrs();
933     EntityInfo.numAttributes = EntityInfo.AttrList->getNumAttrs();
934   }
935 
936   if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
937     switch (TD->getTagKind()) {
938     case TTK_Struct:
939       EntityInfo.kind = CXIdxEntity_Struct; break;
940     case TTK_Union:
941       EntityInfo.kind = CXIdxEntity_Union; break;
942     case TTK_Class:
943       EntityInfo.kind = CXIdxEntity_CXXClass;
944       EntityInfo.lang = CXIdxEntityLang_CXX;
945       break;
946     case TTK_Interface:
947       EntityInfo.kind = CXIdxEntity_CXXInterface;
948       EntityInfo.lang = CXIdxEntityLang_CXX;
949       break;
950     case TTK_Enum:
951       EntityInfo.kind = CXIdxEntity_Enum; break;
952     }
953 
954     if (const CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(D))
955       if (!CXXRec->isCLike())
956         EntityInfo.lang = CXIdxEntityLang_CXX;
957 
958     if (isa<ClassTemplatePartialSpecializationDecl>(D)) {
959       EntityInfo.templateKind = CXIdxEntity_TemplatePartialSpecialization;
960     } else if (isa<ClassTemplateSpecializationDecl>(D)) {
961       EntityInfo.templateKind = CXIdxEntity_TemplateSpecialization;
962     }
963 
964   } else {
965     switch (D->getKind()) {
966     case Decl::Typedef:
967       EntityInfo.kind = CXIdxEntity_Typedef; break;
968     case Decl::Function:
969       EntityInfo.kind = CXIdxEntity_Function;
970       break;
971     case Decl::ParmVar:
972       EntityInfo.kind = CXIdxEntity_Variable;
973       break;
974     case Decl::Var:
975       EntityInfo.kind = CXIdxEntity_Variable;
976       if (isa<CXXRecordDecl>(D->getDeclContext())) {
977         EntityInfo.kind = CXIdxEntity_CXXStaticVariable;
978         EntityInfo.lang = CXIdxEntityLang_CXX;
979       }
980       break;
981     case Decl::Field:
982       EntityInfo.kind = CXIdxEntity_Field;
983       if (const CXXRecordDecl *
984             CXXRec = dyn_cast<CXXRecordDecl>(D->getDeclContext())) {
985         // FIXME: isPOD check is not sufficient, a POD can contain methods,
986         // we want a isCStructLike check.
987         if (!CXXRec->isPOD())
988           EntityInfo.lang = CXIdxEntityLang_CXX;
989       }
990       break;
991     case Decl::EnumConstant:
992       EntityInfo.kind = CXIdxEntity_EnumConstant; break;
993     case Decl::ObjCInterface:
994       EntityInfo.kind = CXIdxEntity_ObjCClass;
995       EntityInfo.lang = CXIdxEntityLang_ObjC;
996       break;
997     case Decl::ObjCProtocol:
998       EntityInfo.kind = CXIdxEntity_ObjCProtocol;
999       EntityInfo.lang = CXIdxEntityLang_ObjC;
1000       break;
1001     case Decl::ObjCCategory:
1002       EntityInfo.kind = CXIdxEntity_ObjCCategory;
1003       EntityInfo.lang = CXIdxEntityLang_ObjC;
1004       break;
1005     case Decl::ObjCMethod:
1006       if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
1007         EntityInfo.kind = CXIdxEntity_ObjCInstanceMethod;
1008       else
1009         EntityInfo.kind = CXIdxEntity_ObjCClassMethod;
1010       EntityInfo.lang = CXIdxEntityLang_ObjC;
1011       break;
1012     case Decl::ObjCProperty:
1013       EntityInfo.kind = CXIdxEntity_ObjCProperty;
1014       EntityInfo.lang = CXIdxEntityLang_ObjC;
1015       break;
1016     case Decl::ObjCIvar:
1017       EntityInfo.kind = CXIdxEntity_ObjCIvar;
1018       EntityInfo.lang = CXIdxEntityLang_ObjC;
1019       break;
1020     case Decl::Namespace:
1021       EntityInfo.kind = CXIdxEntity_CXXNamespace;
1022       EntityInfo.lang = CXIdxEntityLang_CXX;
1023       break;
1024     case Decl::NamespaceAlias:
1025       EntityInfo.kind = CXIdxEntity_CXXNamespaceAlias;
1026       EntityInfo.lang = CXIdxEntityLang_CXX;
1027       break;
1028     case Decl::CXXConstructor:
1029       EntityInfo.kind = CXIdxEntity_CXXConstructor;
1030       EntityInfo.lang = CXIdxEntityLang_CXX;
1031       break;
1032     case Decl::CXXDestructor:
1033       EntityInfo.kind = CXIdxEntity_CXXDestructor;
1034       EntityInfo.lang = CXIdxEntityLang_CXX;
1035       break;
1036     case Decl::CXXConversion:
1037       EntityInfo.kind = CXIdxEntity_CXXConversionFunction;
1038       EntityInfo.lang = CXIdxEntityLang_CXX;
1039       break;
1040     case Decl::CXXMethod: {
1041       const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
1042       if (MD->isStatic())
1043         EntityInfo.kind = CXIdxEntity_CXXStaticMethod;
1044       else
1045         EntityInfo.kind = CXIdxEntity_CXXInstanceMethod;
1046       EntityInfo.lang = CXIdxEntityLang_CXX;
1047       break;
1048     }
1049     case Decl::ClassTemplate:
1050       EntityInfo.kind = CXIdxEntity_CXXClass;
1051       EntityInfo.templateKind = CXIdxEntity_Template;
1052       break;
1053     case Decl::FunctionTemplate:
1054       EntityInfo.kind = CXIdxEntity_Function;
1055       EntityInfo.templateKind = CXIdxEntity_Template;
1056       if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
1057                            cast<FunctionTemplateDecl>(D)->getTemplatedDecl())) {
1058         if (isa<CXXConstructorDecl>(MD))
1059           EntityInfo.kind = CXIdxEntity_CXXConstructor;
1060         else if (isa<CXXDestructorDecl>(MD))
1061           EntityInfo.kind = CXIdxEntity_CXXDestructor;
1062         else if (isa<CXXConversionDecl>(MD))
1063           EntityInfo.kind = CXIdxEntity_CXXConversionFunction;
1064         else {
1065           if (MD->isStatic())
1066             EntityInfo.kind = CXIdxEntity_CXXStaticMethod;
1067           else
1068             EntityInfo.kind = CXIdxEntity_CXXInstanceMethod;
1069         }
1070       }
1071       break;
1072     case Decl::TypeAliasTemplate:
1073       EntityInfo.kind = CXIdxEntity_CXXTypeAlias;
1074       EntityInfo.templateKind = CXIdxEntity_Template;
1075       break;
1076     case Decl::TypeAlias:
1077       EntityInfo.kind = CXIdxEntity_CXXTypeAlias;
1078       EntityInfo.lang = CXIdxEntityLang_CXX;
1079       break;
1080     default:
1081       break;
1082     }
1083   }
1084 
1085   if (EntityInfo.kind == CXIdxEntity_Unexposed)
1086     return;
1087 
1088   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1089     if (FD->getTemplatedKind() ==
1090           FunctionDecl::TK_FunctionTemplateSpecialization)
1091       EntityInfo.templateKind = CXIdxEntity_TemplateSpecialization;
1092   }
1093 
1094   if (EntityInfo.templateKind != CXIdxEntity_NonTemplate)
1095     EntityInfo.lang = CXIdxEntityLang_CXX;
1096 
1097   if (IdentifierInfo *II = D->getIdentifier()) {
1098     EntityInfo.name = SA.toCStr(II->getName());
1099 
1100   } else if (isa<TagDecl>(D) || isa<FieldDecl>(D) || isa<NamespaceDecl>(D)) {
1101     EntityInfo.name = 0; // anonymous tag/field/namespace.
1102 
1103   } else {
1104     SmallString<256> StrBuf;
1105     {
1106       llvm::raw_svector_ostream OS(StrBuf);
1107       D->printName(OS);
1108     }
1109     EntityInfo.name = SA.copyCStr(StrBuf.str());
1110   }
1111 
1112   {
1113     SmallString<512> StrBuf;
1114     bool Ignore = getDeclCursorUSR(D, StrBuf);
1115     if (Ignore) {
1116       EntityInfo.USR = 0;
1117     } else {
1118       EntityInfo.USR = SA.copyCStr(StrBuf.str());
1119     }
1120   }
1121 }
1122 
1123 void IndexingContext::getContainerInfo(const DeclContext *DC,
1124                                        ContainerInfo &ContInfo) {
1125   ContInfo.cursor = getCursor(cast<Decl>(DC));
1126   ContInfo.DC = DC;
1127   ContInfo.IndexCtx = this;
1128 }
1129 
1130 CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
1131   if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
1132     return MakeCursorTypeRef(TD, Loc, CXTU);
1133   if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
1134     return MakeCursorObjCClassRef(ID, Loc, CXTU);
1135   if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
1136     return MakeCursorObjCProtocolRef(PD, Loc, CXTU);
1137   if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
1138     return MakeCursorTemplateRef(Template, Loc, CXTU);
1139   if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(D))
1140     return MakeCursorNamespaceRef(Namespace, Loc, CXTU);
1141   if (const NamespaceAliasDecl *Namespace = dyn_cast<NamespaceAliasDecl>(D))
1142     return MakeCursorNamespaceRef(Namespace, Loc, CXTU);
1143   if (const FieldDecl *Field = dyn_cast<FieldDecl>(D))
1144     return MakeCursorMemberRef(Field, Loc, CXTU);
1145   if (const VarDecl *Var = dyn_cast<VarDecl>(D))
1146     return MakeCursorVariableRef(Var, Loc, CXTU);
1147 
1148   return clang_getNullCursor();
1149 }
1150 
1151 bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) {
1152   if (isa<ObjCInterfaceDecl>(D))
1153     return false;
1154   if (isa<ObjCCategoryDecl>(D))
1155     return false;
1156   if (isa<ObjCIvarDecl>(D))
1157     return false;
1158   if (isa<ObjCMethodDecl>(D))
1159     return false;
1160   if (isa<ImportDecl>(D))
1161     return false;
1162   return true;
1163 }
1164 
1165 bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
1166   if (const ClassTemplateSpecializationDecl *
1167         SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1168     return SD->getSpecializationKind() == TSK_ImplicitInstantiation;
1169   }
1170   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1171     return FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation;
1172   }
1173   return false;
1174 }
1175