blob: f63fd3f103f1d418d628ac5ef35c368994e525c5 [file] [log] [blame]
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +00001//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "IndexingContext.h"
11#include "CXTranslationUnit.h"
12#include "CIndexDiagnostic.h"
13
14#include "clang/Frontend/ASTUnit.h"
15#include "clang/AST/DeclObjC.h"
16
17using namespace clang;
18using namespace cxindex;
19using namespace cxcursor;
20
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +000021IndexingContext::ObjCProtocolListInfo::ObjCProtocolListInfo(
22 const ObjCProtocolList &ProtList,
23 IndexingContext &IdxCtx,
24 StrAdapter &SA) {
25 ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
26 for (ObjCInterfaceDecl::protocol_iterator
27 I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
28 SourceLocation Loc = *LI;
29 ObjCProtocolDecl *PD = *I;
30 ProtEntities.push_back(CXIdxEntityInfo());
31 IdxCtx.getEntityInfo(PD, ProtEntities.back(), SA);
32 CXIdxObjCProtocolRefInfo ProtInfo = { 0,
33 MakeCursorObjCProtocolRef(PD, Loc, IdxCtx.CXTU),
34 IdxCtx.getIndexLoc(Loc) };
35 ProtInfos.push_back(ProtInfo);
36 }
37
38 for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)
39 ProtInfos[i].protocol = &ProtEntities[i];
40
41 for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)
42 Prots.push_back(&ProtInfos[i]);
43}
44
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000045const char *IndexingContext::StrAdapter::toCStr(StringRef Str) {
46 if (Str.empty())
47 return "";
48 if (Str.data()[Str.size()] == '\0')
49 return Str.data();
50 Scratch += Str;
51 Scratch.push_back('\0');
52 return Scratch.data() + (Scratch.size() - Str.size() - 1);
53}
54
55void IndexingContext::setASTContext(ASTContext &ctx) {
56 Ctx = &ctx;
57 static_cast<ASTUnit*>(CXTU->TUData)->setASTContext(&ctx);
58}
59
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000060void IndexingContext::enteredMainFile(const FileEntry *File) {
61 if (File && CB.enteredMainFile) {
62 CXIdxClientFile idxFile = CB.enteredMainFile(ClientData, (CXFile)File, 0);
63 FileMap[File] = idxFile;
64 }
65}
66
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000067void IndexingContext::ppIncludedFile(SourceLocation hashLoc,
68 StringRef filename,
69 const FileEntry *File,
70 bool isImport, bool isAngled) {
71 if (!CB.ppIncludedFile)
72 return;
73
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000074 StrAdapter SA(*this);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000075 CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
76 SA.toCStr(filename),
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000077 (CXFile)File,
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000078 isImport, isAngled };
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000079 CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info);
80 FileMap[File] = idxFile;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000081}
82
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +000083void IndexingContext::startedTranslationUnit() {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000084 CXIdxClientContainer idxCont = 0;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000085 if (CB.startedTranslationUnit)
86 idxCont = CB.startedTranslationUnit(ClientData, 0);
87 addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
88}
89
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000090void IndexingContext::handleDiagnostic(const StoredDiagnostic &StoredDiag) {
91 if (!CB.diagnostic)
92 return;
93
94 CXStoredDiagnostic CXDiag(StoredDiag, Ctx->getLangOptions());
95 CB.diagnostic(ClientData, &CXDiag, 0);
96}
97
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +000098void IndexingContext::handleDiagnostic(CXDiagnostic CXDiag) {
99 if (!CB.diagnostic)
100 return;
101
102 CB.diagnostic(ClientData, CXDiag, 0);
103}
104
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000105void IndexingContext::handleDecl(const NamedDecl *D,
106 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000107 DeclInfo &DInfo) {
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000108 if (!CB.indexDeclaration || !D)
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000109 return;
110
111 StrAdapter SA(*this);
112 getEntityInfo(D, DInfo.CXEntInfo, SA);
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000113 if (!DInfo.CXEntInfo.USR || Loc.isInvalid())
114 return;
115
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000116 DInfo.entityInfo = &DInfo.CXEntInfo;
117 DInfo.cursor = Cursor;
118 DInfo.loc = getIndexLoc(Loc);
119 DInfo.container = getIndexContainer(D);
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000120 DInfo.isImplicit = D->isImplicit();
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000121
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000122 CXIdxClientContainer clientCont = 0;
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000123 CXIdxDeclOut DeclOut = { DInfo.isContainer ? &clientCont : 0 };
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000124 CB.indexDeclaration(ClientData, &DInfo, &DeclOut);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000125
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000126 if (DInfo.isContainer)
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000127 addContainerInMap(cast<DeclContext>(D), clientCont);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000128}
129
130void IndexingContext::handleObjCContainer(const ObjCContainerDecl *D,
131 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000132 ObjCContainerDeclInfo &ContDInfo) {
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000133 ContDInfo.ObjCContDeclInfo.declInfo = &ContDInfo;
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000134 handleDecl(D, Loc, Cursor, ContDInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000135}
136
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000137void IndexingContext::handleFunction(const FunctionDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000138 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
139 D->isThisDeclarationADefinition());
140 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000141}
142
143void IndexingContext::handleVar(const VarDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000144 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
145 /*isContainer=*/false);
146 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000147}
148
149void IndexingContext::handleField(const FieldDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000150 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
151 /*isContainer=*/false);
152 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000153}
154
155void IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000156 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
157 /*isContainer=*/false);
158 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000159}
160
161void IndexingContext::handleTagDecl(const TagDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000162 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
163 D->isThisDeclarationADefinition());
164 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000165}
166
167void IndexingContext::handleTypedef(const TypedefDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000168 DeclInfo DInfo(!D->isFirstDeclaration(), /*isDefinition=*/true,
169 /*isContainer=*/false);
170 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000171}
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000172
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000173void IndexingContext::handleObjCClass(const ObjCClassDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000174 const ObjCClassDecl::ObjCClassRef *Ref = D->getForwardDecl();
175 ObjCInterfaceDecl *IFaceD = Ref->getInterface();
176 SourceLocation Loc = Ref->getLocation();
177 bool isRedeclaration = IFaceD->getLocation() != Loc;
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000178
179 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true, isRedeclaration,
180 /*isImplementation=*/false);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000181 handleObjCContainer(IFaceD, Loc, MakeCursorObjCClassRef(IFaceD, Loc, CXTU),
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000182 ContDInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000183}
184
185void IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000186 StrAdapter SA(*this);
187
188 CXIdxBaseClassInfo BaseClass;
189 CXIdxEntityInfo BaseEntity;
190 BaseClass.cursor = clang_getNullCursor();
191 if (ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
192 getEntityInfo(SuperD, BaseEntity, SA);
193 SourceLocation SuperLoc = D->getSuperClassLoc();
194 BaseClass.base = &BaseEntity;
195 BaseClass.cursor = MakeCursorObjCSuperClassRef(SuperD, SuperLoc, CXTU);
196 BaseClass.loc = getIndexLoc(SuperLoc);
197 }
198
199 ObjCProtocolListInfo ProtInfo(D->getReferencedProtocols(), *this, SA);
200
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000201 ObjCInterfaceDeclInfo InterInfo(D);
202 InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();
203 InterInfo.ObjCInterDeclInfo.containerInfo = &InterInfo.ObjCContDeclInfo;
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000204 InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass : 0;
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000205 InterInfo.ObjCInterDeclInfo.protocols = &InterInfo.ObjCProtoListInfo;
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000206
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000207 handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000208}
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000209
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000210void IndexingContext::handleObjCImplementation(
211 const ObjCImplementationDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000212 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/false,
Argyrios Kyrtzidise7bbab92011-11-15 06:20:24 +0000213 /*isRedeclaration=*/true,
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000214 /*isImplementation=*/true);
215 handleObjCContainer(D, D->getLocation(), getCursor(D), ContDInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000216}
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000217
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000218void IndexingContext::handleObjCForwardProtocol(const ObjCProtocolDecl *D,
219 SourceLocation Loc,
220 bool isRedeclaration) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000221 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true,
222 isRedeclaration,
223 /*isImplementation=*/false);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000224 handleObjCContainer(D, Loc, MakeCursorObjCProtocolRef(D, Loc, CXTU),
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000225 ContDInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000226}
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000227
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000228void IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000229 StrAdapter SA(*this);
230 ObjCProtocolListInfo ProtListInfo(D->getReferencedProtocols(), *this, SA);
231
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000232 ObjCProtocolDeclInfo ProtInfo(D);
233 ProtInfo.ObjCProtoRefListInfo = ProtListInfo.getListInfo();
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000234
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000235 handleObjCContainer(D, D->getLocation(), getCursor(D), ProtInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000236}
237
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000238void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000239 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000240 CXIdxEntityInfo ClassEntity;
241 StrAdapter SA(*this);
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000242 const ObjCInterfaceDecl *IFaceD = D->getClassInterface();
243 SourceLocation ClassLoc = D->getLocation();
244 SourceLocation CategoryLoc = D->getCategoryNameLoc();
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000245 getEntityInfo(IFaceD, ClassEntity, SA);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000246
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000247 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000248 if (IFaceD) {
249 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
250 CatDInfo.ObjCCatDeclInfo.classCursor =
251 MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
252 } else {
253 CatDInfo.ObjCCatDeclInfo.objcClass = 0;
254 CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
255 }
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000256 CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
257 handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000258}
259
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000260void IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
261 const ObjCCategoryDecl *CatD = D->getCategoryDecl();
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000262 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000263 CXIdxEntityInfo ClassEntity;
264 StrAdapter SA(*this);
Argyrios Kyrtzidis3e340a62011-11-16 02:35:05 +0000265 const ObjCInterfaceDecl *IFaceD = CatD->getClassInterface();
266 SourceLocation ClassLoc = D->getLocation();
267 SourceLocation CategoryLoc = ClassLoc; //FIXME: D->getCategoryNameLoc();
268 getEntityInfo(IFaceD, ClassEntity, SA);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000269
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000270 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
Argyrios Kyrtzidis3e340a62011-11-16 02:35:05 +0000271 if (IFaceD) {
272 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
273 CatDInfo.ObjCCatDeclInfo.classCursor =
274 MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
275 } else {
276 CatDInfo.ObjCCatDeclInfo.objcClass = 0;
277 CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
278 }
279 CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
280 handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000281}
282
283void IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000284 DeclInfo DInfo(!D->isCanonicalDecl(), D->isThisDeclarationADefinition(),
285 D->isThisDeclarationADefinition());
286 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000287}
288
289void IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000290 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/false,
291 /*isContainer=*/false);
292 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000293}
294
295void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
296 const NamedDecl *Parent,
297 const DeclContext *DC,
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +0000298 const Expr *E,
299 CXIdxEntityRefKind Kind) {
Argyrios Kyrtzidisd6c82092011-11-16 02:35:01 +0000300 if (!D)
301 return;
302 if (D->getParentFunctionOrMethod())
303 return;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000304 if (Loc.isInvalid())
305 return;
306 if (!CB.indexEntityReference)
307 return;
308 if (isNotFromSourceFile(D->getLocation()))
309 return;
310
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000311 D = getEntityDecl(D);
312
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000313 StrAdapter SA(*this);
314 CXIdxEntityInfo RefEntity, ParentEntity;
315 getEntityInfo(D, RefEntity, SA);
316 if (!RefEntity.USR)
317 return;
318
319 getEntityInfo(Parent, ParentEntity, SA);
320
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000321 if (onlyOneRefPerFile()) {
322 SourceManager &SM = Ctx->getSourceManager();
323 SourceLocation FileLoc = SM.getFileLoc(Loc);
324
325 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
326 FileID FID = LocInfo.first;
327 if (FID.isInvalid())
328 return;
329
330 const FileEntry *FE = SM.getFileEntryForID(FID);
331 if (!FE)
332 return;
333 RefFileOccurence RefOccur(FE, D);
334 std::pair<llvm::DenseSet<RefFileOccurence>::iterator, bool>
335 res = RefFileOccurences.insert(RefOccur);
336 if (!res.second)
337 return; // already in map.
338 }
339
Benjamin Kramer854625f2011-10-28 13:37:11 +0000340 CXCursor Cursor = E ? MakeCXCursor(const_cast<Expr*>(E),
341 const_cast<Decl*>(cast<Decl>(DC)), CXTU)
342 : getRefCursor(D, Loc);
Benjamin Kramer854625f2011-10-28 13:37:11 +0000343 CXIdxEntityRefInfo Info = { Cursor,
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000344 getIndexLoc(Loc),
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000345 &RefEntity,
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000346 Parent ? &ParentEntity : 0,
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +0000347 getIndexContainerForDC(DC),
348 Kind };
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000349 CB.indexEntityReference(ClientData, &Info);
350}
351
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000352bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
353 if (Loc.isInvalid())
354 return true;
355 SourceManager &SM = Ctx->getSourceManager();
356 SourceLocation FileLoc = SM.getFileLoc(Loc);
357 FileID FID = SM.getFileID(FileLoc);
358 return SM.getFileEntryForID(FID) == 0;
359}
360
361void IndexingContext::addContainerInMap(const DeclContext *DC,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000362 CXIdxClientContainer container) {
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000363 assert(getScopedContext(DC) == DC);
364 ContainerMapTy::iterator I = ContainerMap.find(DC);
365 if (I == ContainerMap.end()) {
366 if (container)
367 ContainerMap[DC] = container;
368 return;
369 }
370 // Allow changing the container of a previously seen DeclContext so we
371 // can handle invalid user code, like a function re-definition.
372 if (container)
373 I->second = container;
374 else
375 ContainerMap.erase(I);
376}
377
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000378const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
379 assert(D);
380 D = cast<NamedDecl>(D->getCanonicalDecl());
381
382 if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(D)) {
383 if (Cat->IsClassExtension())
384 return getEntityDecl(Cat->getClassInterface());
385
386 } else if (const ObjCImplementationDecl *
387 ImplD = dyn_cast<ObjCImplementationDecl>(D)) {
388 return getEntityDecl(ImplD->getClassInterface());
389
390 } else if (const ObjCCategoryImplDecl *
391 CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {
392 return getEntityDecl(CatImplD->getCategoryDecl());
393 }
394
395 return D;
396}
397
398const DeclContext *
399IndexingContext::getScopedContext(const DeclContext *DC) const {
400 // Local contexts are ignored for indexing.
401 const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod();
402 if (FuncCtx)
403 return FuncCtx;
404
405 // We consider enums always scoped for indexing.
406 if (isa<TagDecl>(DC))
407 return DC;
408
409 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
410 if (NS->isAnonymousNamespace())
411 return getScopedContext(NS->getParent());
412 return NS;
413 }
414
415 return DC->getRedeclContext();
416}
417
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000418CXIdxClientContainer
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000419IndexingContext::getIndexContainerForDC(const DeclContext *DC) const {
420 DC = getScopedContext(DC);
421 ContainerMapTy::const_iterator I = ContainerMap.find(DC);
Argyrios Kyrtzidis3e340a62011-11-16 02:35:05 +0000422 if (I == ContainerMap.end())
423 return 0;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000424// assert(I != ContainerMap.end() &&
425// "Failed to include a scoped context in the container map");
426 return I->second;
427}
428
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000429CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) {
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000430 if (!File)
431 return 0;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000432
433 FileMapTy::iterator FI = FileMap.find(File);
434 if (FI != FileMap.end())
435 return FI->second;
436
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000437 return 0;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000438}
439
440CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
441 CXIdxLoc idxLoc = { {0, 0}, 0 };
442 if (Loc.isInvalid())
443 return idxLoc;
444
445 idxLoc.ptr_data[0] = (void*)this;
446 idxLoc.int_data = Loc.getRawEncoding();
447 return idxLoc;
448}
449
450void IndexingContext::translateLoc(SourceLocation Loc,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000451 CXIdxClientFile *indexFile, CXFile *file,
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000452 unsigned *line, unsigned *column,
453 unsigned *offset) {
454 if (Loc.isInvalid())
455 return;
456
457 SourceManager &SM = Ctx->getSourceManager();
458 Loc = SM.getFileLoc(Loc);
459
460 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
461 FileID FID = LocInfo.first;
462 unsigned FileOffset = LocInfo.second;
463
464 if (FID.isInvalid())
465 return;
466
467 const FileEntry *FE = SM.getFileEntryForID(FID);
468 if (indexFile)
469 *indexFile = getIndexFile(FE);
470 if (file)
471 *file = (void *)FE;
472 if (line)
473 *line = SM.getLineNumber(FID, FileOffset);
474 if (column)
475 *column = SM.getColumnNumber(FID, FileOffset);
476 if (offset)
477 *offset = FileOffset;
478}
479
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000480void IndexingContext::getEntityInfo(const NamedDecl *D,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000481 CXIdxEntityInfo &EntityInfo,
482 StrAdapter &SA) {
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000483 if (!D)
484 return;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000485 D = getEntityDecl(D);
486 EntityInfo.kind = CXIdxEntity_Unexposed;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000487
488 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
489 switch (TD->getTagKind()) {
490 case TTK_Struct:
491 EntityInfo.kind = CXIdxEntity_Struct; break;
492 case TTK_Union:
493 EntityInfo.kind = CXIdxEntity_Union; break;
494 case TTK_Class:
495 EntityInfo.kind = CXIdxEntity_CXXClass; break;
496 case TTK_Enum:
497 EntityInfo.kind = CXIdxEntity_Enum; break;
498 }
499
500 } else {
501 switch (D->getKind()) {
502 case Decl::Typedef:
503 EntityInfo.kind = CXIdxEntity_Typedef; break;
504 case Decl::Function:
505 EntityInfo.kind = CXIdxEntity_Function; break;
506 case Decl::Var:
507 EntityInfo.kind = CXIdxEntity_Variable; break;
508 case Decl::Field:
509 EntityInfo.kind = CXIdxEntity_Field; break;
510 case Decl::EnumConstant:
511 EntityInfo.kind = CXIdxEntity_EnumConstant; break;
512 case Decl::ObjCInterface:
513 EntityInfo.kind = CXIdxEntity_ObjCClass; break;
514 case Decl::ObjCProtocol:
515 EntityInfo.kind = CXIdxEntity_ObjCProtocol; break;
516 case Decl::ObjCCategory:
517 EntityInfo.kind = CXIdxEntity_ObjCCategory; break;
518 case Decl::ObjCMethod:
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000519 if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
520 EntityInfo.kind = CXIdxEntity_ObjCInstanceMethod;
521 else
522 EntityInfo.kind = CXIdxEntity_ObjCClassMethod;
523 break;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000524 case Decl::ObjCProperty:
525 EntityInfo.kind = CXIdxEntity_ObjCProperty; break;
526 case Decl::ObjCIvar:
527 EntityInfo.kind = CXIdxEntity_ObjCIvar; break;
528 default:
529 break;
530 }
531 }
532
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000533 if (IdentifierInfo *II = D->getIdentifier()) {
534 EntityInfo.name = SA.toCStr(II->getName());
535
536 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000537 EntityInfo.name = 0; // anonymous record/namespace.
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000538
539 } else {
540 unsigned Begin = SA.getCurSize();
541 {
542 llvm::raw_svector_ostream OS(SA.getBuffer());
543 D->printName(OS);
544 }
545 EntityInfo.name = SA.getCStr(Begin);
546 }
547
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000548 {
549 unsigned Begin = SA.getCurSize();
550 bool Ignore = getDeclCursorUSR(D, SA.getBuffer());
551 if (Ignore) {
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000552 EntityInfo.USR = 0;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000553 } else {
554 EntityInfo.USR = SA.getCStr(Begin);
555 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000556 }
557}
558
559CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
560 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
561 return MakeCursorTypeRef(TD, Loc, CXTU);
562 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
563 return MakeCursorObjCClassRef(ID, Loc, CXTU);
564 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
565 return MakeCursorObjCProtocolRef(PD, Loc, CXTU);
566
567 //assert(0 && "not yet");
568 return clang_getNullCursor();
569}