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