blob: 3ecc560d35013fdbf552ef57ceb76276c61fc721 [file] [log] [blame]
Argyrios Kyrtzidisdc199a32011-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 Kyrtzidis3e429e72011-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 Kyrtzidisdc199a32011-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 Kyrtzidis7519c5e2011-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 Kyrtzidisdc199a32011-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 Kyrtzidis7519c5e2011-11-11 00:23:36 +000074 StrAdapter SA(*this);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000075 CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
76 SA.toCStr(filename),
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000077 (CXFile)File,
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000078 isImport, isAngled };
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000079 CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info);
80 FileMap[File] = idxFile;
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000081}
82
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +000083void IndexingContext::startedTranslationUnit() {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000084 CXIdxClientContainer idxCont = 0;
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000085 if (CB.startedTranslationUnit)
86 idxCont = CB.startedTranslationUnit(ClientData, 0);
87 addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
88}
89
Argyrios Kyrtzidisdc199a32011-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 Kyrtzidisd992e142011-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 Kyrtzidis7519c5e2011-11-11 00:23:36 +0000105void IndexingContext::handleDecl(const NamedDecl *D,
106 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000107 DeclInfo &DInfo) {
108 if (!CB.indexDeclaration)
109 return;
110
111 StrAdapter SA(*this);
112 getEntityInfo(D, DInfo.CXEntInfo, SA);
113 DInfo.entityInfo = &DInfo.CXEntInfo;
114 DInfo.cursor = Cursor;
115 DInfo.loc = getIndexLoc(Loc);
116 DInfo.container = getIndexContainer(D);
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000117 DInfo.isImplicit = D->isImplicit();
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000118
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000119 CXIdxClientContainer clientCont = 0;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000120 CXIdxDeclOut DeclOut = { DInfo.isContainer ? &clientCont : 0 };
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000121 CB.indexDeclaration(ClientData, &DInfo, &DeclOut);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000122
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000123 if (DInfo.isContainer)
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000124 addContainerInMap(cast<DeclContext>(D), clientCont);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000125}
126
127void IndexingContext::handleObjCContainer(const ObjCContainerDecl *D,
128 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000129 ObjCContainerDeclInfo &ContDInfo) {
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000130 ContDInfo.ObjCContDeclInfo.declInfo = &ContDInfo;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000131 handleDecl(D, Loc, Cursor, ContDInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000132}
133
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000134void IndexingContext::handleFunction(const FunctionDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000135 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
136 D->isThisDeclarationADefinition());
137 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000138}
139
140void IndexingContext::handleVar(const VarDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000141 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
142 /*isContainer=*/false);
143 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000144}
145
146void IndexingContext::handleField(const FieldDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000147 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
148 /*isContainer=*/false);
149 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000150}
151
152void IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000153 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
154 /*isContainer=*/false);
155 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000156}
157
158void IndexingContext::handleTagDecl(const TagDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000159 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
160 D->isThisDeclarationADefinition());
161 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000162}
163
164void IndexingContext::handleTypedef(const TypedefDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000165 DeclInfo DInfo(!D->isFirstDeclaration(), /*isDefinition=*/true,
166 /*isContainer=*/false);
167 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000168}
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000169
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000170void IndexingContext::handleObjCClass(const ObjCClassDecl *D) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000171 const ObjCClassDecl::ObjCClassRef *Ref = D->getForwardDecl();
172 ObjCInterfaceDecl *IFaceD = Ref->getInterface();
173 SourceLocation Loc = Ref->getLocation();
174 bool isRedeclaration = IFaceD->getLocation() != Loc;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000175
176 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true, isRedeclaration,
177 /*isImplementation=*/false);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000178 handleObjCContainer(IFaceD, Loc, MakeCursorObjCClassRef(IFaceD, Loc, CXTU),
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000179 ContDInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000180}
181
182void IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000183 StrAdapter SA(*this);
184
185 CXIdxBaseClassInfo BaseClass;
186 CXIdxEntityInfo BaseEntity;
187 BaseClass.cursor = clang_getNullCursor();
188 if (ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
189 getEntityInfo(SuperD, BaseEntity, SA);
190 SourceLocation SuperLoc = D->getSuperClassLoc();
191 BaseClass.base = &BaseEntity;
192 BaseClass.cursor = MakeCursorObjCSuperClassRef(SuperD, SuperLoc, CXTU);
193 BaseClass.loc = getIndexLoc(SuperLoc);
194 }
195
196 ObjCProtocolListInfo ProtInfo(D->getReferencedProtocols(), *this, SA);
197
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000198 ObjCInterfaceDeclInfo InterInfo(D);
199 InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();
200 InterInfo.ObjCInterDeclInfo.containerInfo = &InterInfo.ObjCContDeclInfo;
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000201 InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass : 0;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000202 InterInfo.ObjCInterDeclInfo.protocols = &InterInfo.ObjCProtoListInfo;
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000203
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000204 handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000205}
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000206
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000207void IndexingContext::handleObjCImplementation(
208 const ObjCImplementationDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000209 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/false,
Argyrios Kyrtzidis233f12d2011-11-15 06:20:24 +0000210 /*isRedeclaration=*/true,
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000211 /*isImplementation=*/true);
212 handleObjCContainer(D, D->getLocation(), getCursor(D), ContDInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000213}
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000214
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000215void IndexingContext::handleObjCForwardProtocol(const ObjCProtocolDecl *D,
216 SourceLocation Loc,
217 bool isRedeclaration) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000218 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true,
219 isRedeclaration,
220 /*isImplementation=*/false);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000221 handleObjCContainer(D, Loc, MakeCursorObjCProtocolRef(D, Loc, CXTU),
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000222 ContDInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000223}
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000224
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000225void IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000226 StrAdapter SA(*this);
227 ObjCProtocolListInfo ProtListInfo(D->getReferencedProtocols(), *this, SA);
228
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000229 ObjCProtocolDeclInfo ProtInfo(D);
230 ProtInfo.ObjCProtoRefListInfo = ProtListInfo.getListInfo();
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000231
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000232 handleObjCContainer(D, D->getLocation(), getCursor(D), ProtInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000233}
234
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000235void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000236 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000237 CXIdxEntityInfo ClassEntity;
238 StrAdapter SA(*this);
Argyrios Kyrtzidisd992e142011-11-15 06:20:16 +0000239 const ObjCInterfaceDecl *IFaceD = D->getClassInterface();
240 SourceLocation ClassLoc = D->getLocation();
241 SourceLocation CategoryLoc = D->getCategoryNameLoc();
Argyrios Kyrtzidise4acd232011-11-16 02:34:59 +0000242 getEntityInfo(IFaceD, ClassEntity, SA);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000243
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000244 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
Argyrios Kyrtzidise4acd232011-11-16 02:34:59 +0000245 if (IFaceD) {
246 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
247 CatDInfo.ObjCCatDeclInfo.classCursor =
248 MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
249 } else {
250 CatDInfo.ObjCCatDeclInfo.objcClass = 0;
251 CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
252 }
Argyrios Kyrtzidisd992e142011-11-15 06:20:16 +0000253 CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
254 handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000255}
256
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000257void IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
258 const ObjCCategoryDecl *CatD = D->getCategoryDecl();
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000259 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000260 CXIdxEntityInfo ClassEntity;
261 StrAdapter SA(*this);
262 getEntityInfo(CatD->getClassInterface(), ClassEntity, SA);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000263
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000264 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
265 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000266 handleObjCContainer(D, D->getLocation(), getCursor(D), CatDInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000267}
268
269void IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000270 DeclInfo DInfo(!D->isCanonicalDecl(), D->isThisDeclarationADefinition(),
271 D->isThisDeclarationADefinition());
272 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000273}
274
275void IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000276 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/false,
277 /*isContainer=*/false);
278 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000279}
280
281void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
282 const NamedDecl *Parent,
283 const DeclContext *DC,
Argyrios Kyrtzidis0c7735e52011-10-18 15:50:50 +0000284 const Expr *E,
285 CXIdxEntityRefKind Kind) {
Argyrios Kyrtzidisd7b87902011-11-16 02:35:01 +0000286 if (!D)
287 return;
288 if (D->getParentFunctionOrMethod())
289 return;
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000290 if (Loc.isInvalid())
291 return;
292 if (!CB.indexEntityReference)
293 return;
294 if (isNotFromSourceFile(D->getLocation()))
295 return;
296
Argyrios Kyrtzidise4acd232011-11-16 02:34:59 +0000297 D = getEntityDecl(D);
298
299 if (onlyOneRefPerFile()) {
300 SourceManager &SM = Ctx->getSourceManager();
301 SourceLocation FileLoc = SM.getFileLoc(Loc);
302
303 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
304 FileID FID = LocInfo.first;
305 if (FID.isInvalid())
306 return;
307
308 const FileEntry *FE = SM.getFileEntryForID(FID);
309 if (!FE)
310 return;
311 RefFileOccurence RefOccur(FE, D);
312 std::pair<llvm::DenseSet<RefFileOccurence>::iterator, bool>
313 res = RefFileOccurences.insert(RefOccur);
314 if (!res.second)
315 return; // already in map.
316 }
317
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000318 StrAdapter SA(*this);
Benjamin Kramerf1b4e002011-10-28 13:37:11 +0000319 CXCursor Cursor = E ? MakeCXCursor(const_cast<Expr*>(E),
320 const_cast<Decl*>(cast<Decl>(DC)), CXTU)
321 : getRefCursor(D, Loc);
322
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000323 CXIdxEntityInfo RefEntity, ParentEntity;
324 getEntityInfo(D, RefEntity, SA);
325 getEntityInfo(Parent, ParentEntity, SA);
Benjamin Kramerf1b4e002011-10-28 13:37:11 +0000326 CXIdxEntityRefInfo Info = { Cursor,
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000327 getIndexLoc(Loc),
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000328 &RefEntity,
Argyrios Kyrtzidise4acd232011-11-16 02:34:59 +0000329 Parent ? &ParentEntity : 0,
Argyrios Kyrtzidis0c7735e52011-10-18 15:50:50 +0000330 getIndexContainerForDC(DC),
331 Kind };
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000332 CB.indexEntityReference(ClientData, &Info);
333}
334
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000335bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
336 if (Loc.isInvalid())
337 return true;
338 SourceManager &SM = Ctx->getSourceManager();
339 SourceLocation FileLoc = SM.getFileLoc(Loc);
340 FileID FID = SM.getFileID(FileLoc);
341 return SM.getFileEntryForID(FID) == 0;
342}
343
344void IndexingContext::addContainerInMap(const DeclContext *DC,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000345 CXIdxClientContainer container) {
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000346 assert(getScopedContext(DC) == DC);
347 ContainerMapTy::iterator I = ContainerMap.find(DC);
348 if (I == ContainerMap.end()) {
349 if (container)
350 ContainerMap[DC] = container;
351 return;
352 }
353 // Allow changing the container of a previously seen DeclContext so we
354 // can handle invalid user code, like a function re-definition.
355 if (container)
356 I->second = container;
357 else
358 ContainerMap.erase(I);
359}
360
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000361const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
362 assert(D);
363 D = cast<NamedDecl>(D->getCanonicalDecl());
364
365 if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(D)) {
366 if (Cat->IsClassExtension())
367 return getEntityDecl(Cat->getClassInterface());
368
369 } else if (const ObjCImplementationDecl *
370 ImplD = dyn_cast<ObjCImplementationDecl>(D)) {
371 return getEntityDecl(ImplD->getClassInterface());
372
373 } else if (const ObjCCategoryImplDecl *
374 CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {
375 return getEntityDecl(CatImplD->getCategoryDecl());
376 }
377
378 return D;
379}
380
381const DeclContext *
382IndexingContext::getScopedContext(const DeclContext *DC) const {
383 // Local contexts are ignored for indexing.
384 const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod();
385 if (FuncCtx)
386 return FuncCtx;
387
388 // We consider enums always scoped for indexing.
389 if (isa<TagDecl>(DC))
390 return DC;
391
392 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
393 if (NS->isAnonymousNamespace())
394 return getScopedContext(NS->getParent());
395 return NS;
396 }
397
398 return DC->getRedeclContext();
399}
400
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000401CXIdxClientContainer
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000402IndexingContext::getIndexContainerForDC(const DeclContext *DC) const {
403 DC = getScopedContext(DC);
404 ContainerMapTy::const_iterator I = ContainerMap.find(DC);
405// assert(I != ContainerMap.end() &&
406// "Failed to include a scoped context in the container map");
407 return I->second;
408}
409
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000410CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) {
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000411 if (!File)
412 return 0;
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000413
414 FileMapTy::iterator FI = FileMap.find(File);
415 if (FI != FileMap.end())
416 return FI->second;
417
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000418 return 0;
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000419}
420
421CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
422 CXIdxLoc idxLoc = { {0, 0}, 0 };
423 if (Loc.isInvalid())
424 return idxLoc;
425
426 idxLoc.ptr_data[0] = (void*)this;
427 idxLoc.int_data = Loc.getRawEncoding();
428 return idxLoc;
429}
430
431void IndexingContext::translateLoc(SourceLocation Loc,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000432 CXIdxClientFile *indexFile, CXFile *file,
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000433 unsigned *line, unsigned *column,
434 unsigned *offset) {
435 if (Loc.isInvalid())
436 return;
437
438 SourceManager &SM = Ctx->getSourceManager();
439 Loc = SM.getFileLoc(Loc);
440
441 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
442 FileID FID = LocInfo.first;
443 unsigned FileOffset = LocInfo.second;
444
445 if (FID.isInvalid())
446 return;
447
448 const FileEntry *FE = SM.getFileEntryForID(FID);
449 if (indexFile)
450 *indexFile = getIndexFile(FE);
451 if (file)
452 *file = (void *)FE;
453 if (line)
454 *line = SM.getLineNumber(FID, FileOffset);
455 if (column)
456 *column = SM.getColumnNumber(FID, FileOffset);
457 if (offset)
458 *offset = FileOffset;
459}
460
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000461void IndexingContext::getEntityInfo(const NamedDecl *D,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000462 CXIdxEntityInfo &EntityInfo,
463 StrAdapter &SA) {
Argyrios Kyrtzidise4acd232011-11-16 02:34:59 +0000464 if (!D)
465 return;
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000466 D = getEntityDecl(D);
467 EntityInfo.kind = CXIdxEntity_Unexposed;
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000468
469 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
470 switch (TD->getTagKind()) {
471 case TTK_Struct:
472 EntityInfo.kind = CXIdxEntity_Struct; break;
473 case TTK_Union:
474 EntityInfo.kind = CXIdxEntity_Union; break;
475 case TTK_Class:
476 EntityInfo.kind = CXIdxEntity_CXXClass; break;
477 case TTK_Enum:
478 EntityInfo.kind = CXIdxEntity_Enum; break;
479 }
480
481 } else {
482 switch (D->getKind()) {
483 case Decl::Typedef:
484 EntityInfo.kind = CXIdxEntity_Typedef; break;
485 case Decl::Function:
486 EntityInfo.kind = CXIdxEntity_Function; break;
487 case Decl::Var:
488 EntityInfo.kind = CXIdxEntity_Variable; break;
489 case Decl::Field:
490 EntityInfo.kind = CXIdxEntity_Field; break;
491 case Decl::EnumConstant:
492 EntityInfo.kind = CXIdxEntity_EnumConstant; break;
493 case Decl::ObjCInterface:
494 EntityInfo.kind = CXIdxEntity_ObjCClass; break;
495 case Decl::ObjCProtocol:
496 EntityInfo.kind = CXIdxEntity_ObjCProtocol; break;
497 case Decl::ObjCCategory:
498 EntityInfo.kind = CXIdxEntity_ObjCCategory; break;
499 case Decl::ObjCMethod:
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000500 if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
501 EntityInfo.kind = CXIdxEntity_ObjCInstanceMethod;
502 else
503 EntityInfo.kind = CXIdxEntity_ObjCClassMethod;
504 break;
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000505 case Decl::ObjCProperty:
506 EntityInfo.kind = CXIdxEntity_ObjCProperty; break;
507 case Decl::ObjCIvar:
508 EntityInfo.kind = CXIdxEntity_ObjCIvar; break;
509 default:
510 break;
511 }
512 }
513
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000514 if (IdentifierInfo *II = D->getIdentifier()) {
515 EntityInfo.name = SA.toCStr(II->getName());
516
517 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000518 EntityInfo.name = 0; // anonymous record/namespace.
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000519
520 } else {
521 unsigned Begin = SA.getCurSize();
522 {
523 llvm::raw_svector_ostream OS(SA.getBuffer());
524 D->printName(OS);
525 }
526 EntityInfo.name = SA.getCStr(Begin);
527 }
528
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000529 {
530 unsigned Begin = SA.getCurSize();
531 bool Ignore = getDeclCursorUSR(D, SA.getBuffer());
532 if (Ignore) {
533 EntityInfo.USR = "";
534 } else {
535 EntityInfo.USR = SA.getCStr(Begin);
536 }
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000537 }
538}
539
540CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
541 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
542 return MakeCursorTypeRef(TD, Loc, CXTU);
543 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
544 return MakeCursorObjCClassRef(ID, Loc, CXTU);
545 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
546 return MakeCursorObjCProtocolRef(PD, Loc, CXTU);
547
548 //assert(0 && "not yet");
549 return clang_getNullCursor();
550}