blob: 24727fab2210cb53bb9f1c5bdea882fd267501a6 [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 Kyrtzidis7519c5e2011-11-11 00:23:36 +000098void IndexingContext::handleDecl(const NamedDecl *D,
99 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000100 DeclInfo &DInfo) {
101 if (!CB.indexDeclaration)
102 return;
103
104 StrAdapter SA(*this);
105 getEntityInfo(D, DInfo.CXEntInfo, SA);
106 DInfo.entityInfo = &DInfo.CXEntInfo;
107 DInfo.cursor = Cursor;
108 DInfo.loc = getIndexLoc(Loc);
109 DInfo.container = getIndexContainer(D);
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000110 DInfo.isImplicit = D->isImplicit();
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000111
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000112 CXIdxClientContainer clientCont = 0;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000113 CXIdxDeclOut DeclOut = { DInfo.isContainer ? &clientCont : 0 };
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000114 CB.indexDeclaration(ClientData, &DInfo, &DeclOut);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000115
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000116 if (DInfo.isContainer)
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000117 addContainerInMap(cast<DeclContext>(D), clientCont);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000118}
119
120void IndexingContext::handleObjCContainer(const ObjCContainerDecl *D,
121 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000122 ObjCContainerDeclInfo &ContDInfo) {
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000123 ContDInfo.ObjCContDeclInfo.declInfo = &ContDInfo;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000124 handleDecl(D, Loc, Cursor, ContDInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000125}
126
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000127void IndexingContext::handleFunction(const FunctionDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000128 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
129 D->isThisDeclarationADefinition());
130 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000131}
132
133void IndexingContext::handleVar(const VarDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000134 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
135 /*isContainer=*/false);
136 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000137}
138
139void IndexingContext::handleField(const FieldDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000140 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
141 /*isContainer=*/false);
142 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000143}
144
145void IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000146 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
147 /*isContainer=*/false);
148 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000149}
150
151void IndexingContext::handleTagDecl(const TagDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000152 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
153 D->isThisDeclarationADefinition());
154 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000155}
156
157void IndexingContext::handleTypedef(const TypedefDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000158 DeclInfo DInfo(!D->isFirstDeclaration(), /*isDefinition=*/true,
159 /*isContainer=*/false);
160 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000161}
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000162
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000163void IndexingContext::handleObjCClass(const ObjCClassDecl *D) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000164 const ObjCClassDecl::ObjCClassRef *Ref = D->getForwardDecl();
165 ObjCInterfaceDecl *IFaceD = Ref->getInterface();
166 SourceLocation Loc = Ref->getLocation();
167 bool isRedeclaration = IFaceD->getLocation() != Loc;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000168
169 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true, isRedeclaration,
170 /*isImplementation=*/false);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000171 handleObjCContainer(IFaceD, Loc, MakeCursorObjCClassRef(IFaceD, Loc, CXTU),
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000172 ContDInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000173}
174
175void IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000176 StrAdapter SA(*this);
177
178 CXIdxBaseClassInfo BaseClass;
179 CXIdxEntityInfo BaseEntity;
180 BaseClass.cursor = clang_getNullCursor();
181 if (ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
182 getEntityInfo(SuperD, BaseEntity, SA);
183 SourceLocation SuperLoc = D->getSuperClassLoc();
184 BaseClass.base = &BaseEntity;
185 BaseClass.cursor = MakeCursorObjCSuperClassRef(SuperD, SuperLoc, CXTU);
186 BaseClass.loc = getIndexLoc(SuperLoc);
187 }
188
189 ObjCProtocolListInfo ProtInfo(D->getReferencedProtocols(), *this, SA);
190
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000191 ObjCInterfaceDeclInfo InterInfo(D);
192 InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();
193 InterInfo.ObjCInterDeclInfo.containerInfo = &InterInfo.ObjCContDeclInfo;
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000194 InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass : 0;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000195 InterInfo.ObjCInterDeclInfo.protocols = &InterInfo.ObjCProtoListInfo;
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000196
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000197 handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000198}
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000199
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000200void IndexingContext::handleObjCImplementation(
201 const ObjCImplementationDecl *D) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000202 const ObjCInterfaceDecl *Class = D->getClassInterface();
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000203 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/false,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000204 /*isRedeclaration=*/!Class->isImplicitInterfaceDecl(),
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000205 /*isImplementation=*/true);
206 handleObjCContainer(D, D->getLocation(), getCursor(D), ContDInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000207}
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000208
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000209void IndexingContext::handleObjCForwardProtocol(const ObjCProtocolDecl *D,
210 SourceLocation Loc,
211 bool isRedeclaration) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000212 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true,
213 isRedeclaration,
214 /*isImplementation=*/false);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000215 handleObjCContainer(D, Loc, MakeCursorObjCProtocolRef(D, Loc, CXTU),
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000216 ContDInfo);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000217}
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000218
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000219void IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000220 StrAdapter SA(*this);
221 ObjCProtocolListInfo ProtListInfo(D->getReferencedProtocols(), *this, SA);
222
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000223 ObjCProtocolDeclInfo ProtInfo(D);
224 ProtInfo.ObjCProtoRefListInfo = ProtListInfo.getListInfo();
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000225
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000226 handleObjCContainer(D, D->getLocation(), getCursor(D), ProtInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000227}
228
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000229void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000230 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000231 CXIdxEntityInfo ClassEntity;
232 StrAdapter SA(*this);
233 getEntityInfo(D->getClassInterface(), ClassEntity, SA);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000234
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000235 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
236 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000237 handleObjCContainer(D, D->getLocation(), getCursor(D), CatDInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000238}
239
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000240void IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
241 const ObjCCategoryDecl *CatD = D->getCategoryDecl();
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000242 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000243 CXIdxEntityInfo ClassEntity;
244 StrAdapter SA(*this);
245 getEntityInfo(CatD->getClassInterface(), ClassEntity, SA);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000246
Argyrios Kyrtzidis3e429e72011-11-12 02:16:30 +0000247 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
248 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000249 handleObjCContainer(D, D->getLocation(), getCursor(D), CatDInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000250}
251
252void IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000253 DeclInfo DInfo(!D->isCanonicalDecl(), D->isThisDeclarationADefinition(),
254 D->isThisDeclarationADefinition());
255 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000256}
257
258void IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000259 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/false,
260 /*isContainer=*/false);
261 handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000262}
263
264void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
265 const NamedDecl *Parent,
266 const DeclContext *DC,
Argyrios Kyrtzidis0c7735e52011-10-18 15:50:50 +0000267 const Expr *E,
268 CXIdxEntityRefKind Kind) {
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000269 if (Loc.isInvalid())
270 return;
271 if (!CB.indexEntityReference)
272 return;
273 if (isNotFromSourceFile(D->getLocation()))
274 return;
275
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000276 StrAdapter SA(*this);
Benjamin Kramerf1b4e002011-10-28 13:37:11 +0000277 CXCursor Cursor = E ? MakeCXCursor(const_cast<Expr*>(E),
278 const_cast<Decl*>(cast<Decl>(DC)), CXTU)
279 : getRefCursor(D, Loc);
280
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000281 CXIdxEntityInfo RefEntity, ParentEntity;
282 getEntityInfo(D, RefEntity, SA);
283 getEntityInfo(Parent, ParentEntity, SA);
Benjamin Kramerf1b4e002011-10-28 13:37:11 +0000284 CXIdxEntityRefInfo Info = { Cursor,
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000285 getIndexLoc(Loc),
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000286 &RefEntity,
287 &ParentEntity,
Argyrios Kyrtzidis0c7735e52011-10-18 15:50:50 +0000288 getIndexContainerForDC(DC),
289 Kind };
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000290 CB.indexEntityReference(ClientData, &Info);
291}
292
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000293bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
294 if (Loc.isInvalid())
295 return true;
296 SourceManager &SM = Ctx->getSourceManager();
297 SourceLocation FileLoc = SM.getFileLoc(Loc);
298 FileID FID = SM.getFileID(FileLoc);
299 return SM.getFileEntryForID(FID) == 0;
300}
301
302void IndexingContext::addContainerInMap(const DeclContext *DC,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000303 CXIdxClientContainer container) {
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000304 assert(getScopedContext(DC) == DC);
305 ContainerMapTy::iterator I = ContainerMap.find(DC);
306 if (I == ContainerMap.end()) {
307 if (container)
308 ContainerMap[DC] = container;
309 return;
310 }
311 // Allow changing the container of a previously seen DeclContext so we
312 // can handle invalid user code, like a function re-definition.
313 if (container)
314 I->second = container;
315 else
316 ContainerMap.erase(I);
317}
318
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000319const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
320 assert(D);
321 D = cast<NamedDecl>(D->getCanonicalDecl());
322
323 if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(D)) {
324 if (Cat->IsClassExtension())
325 return getEntityDecl(Cat->getClassInterface());
326
327 } else if (const ObjCImplementationDecl *
328 ImplD = dyn_cast<ObjCImplementationDecl>(D)) {
329 return getEntityDecl(ImplD->getClassInterface());
330
331 } else if (const ObjCCategoryImplDecl *
332 CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {
333 return getEntityDecl(CatImplD->getCategoryDecl());
334 }
335
336 return D;
337}
338
339const DeclContext *
340IndexingContext::getScopedContext(const DeclContext *DC) const {
341 // Local contexts are ignored for indexing.
342 const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod();
343 if (FuncCtx)
344 return FuncCtx;
345
346 // We consider enums always scoped for indexing.
347 if (isa<TagDecl>(DC))
348 return DC;
349
350 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
351 if (NS->isAnonymousNamespace())
352 return getScopedContext(NS->getParent());
353 return NS;
354 }
355
356 return DC->getRedeclContext();
357}
358
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000359CXIdxClientContainer
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000360IndexingContext::getIndexContainerForDC(const DeclContext *DC) const {
361 DC = getScopedContext(DC);
362 ContainerMapTy::const_iterator I = ContainerMap.find(DC);
363// assert(I != ContainerMap.end() &&
364// "Failed to include a scoped context in the container map");
365 return I->second;
366}
367
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000368CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) {
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000369 if (!File)
370 return 0;
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000371
372 FileMapTy::iterator FI = FileMap.find(File);
373 if (FI != FileMap.end())
374 return FI->second;
375
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000376 return 0;
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000377}
378
379CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
380 CXIdxLoc idxLoc = { {0, 0}, 0 };
381 if (Loc.isInvalid())
382 return idxLoc;
383
384 idxLoc.ptr_data[0] = (void*)this;
385 idxLoc.int_data = Loc.getRawEncoding();
386 return idxLoc;
387}
388
389void IndexingContext::translateLoc(SourceLocation Loc,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000390 CXIdxClientFile *indexFile, CXFile *file,
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000391 unsigned *line, unsigned *column,
392 unsigned *offset) {
393 if (Loc.isInvalid())
394 return;
395
396 SourceManager &SM = Ctx->getSourceManager();
397 Loc = SM.getFileLoc(Loc);
398
399 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
400 FileID FID = LocInfo.first;
401 unsigned FileOffset = LocInfo.second;
402
403 if (FID.isInvalid())
404 return;
405
406 const FileEntry *FE = SM.getFileEntryForID(FID);
407 if (indexFile)
408 *indexFile = getIndexFile(FE);
409 if (file)
410 *file = (void *)FE;
411 if (line)
412 *line = SM.getLineNumber(FID, FileOffset);
413 if (column)
414 *column = SM.getColumnNumber(FID, FileOffset);
415 if (offset)
416 *offset = FileOffset;
417}
418
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000419void IndexingContext::getEntityInfo(const NamedDecl *D,
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000420 CXIdxEntityInfo &EntityInfo,
421 StrAdapter &SA) {
422 D = getEntityDecl(D);
423 EntityInfo.kind = CXIdxEntity_Unexposed;
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000424
425 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
426 switch (TD->getTagKind()) {
427 case TTK_Struct:
428 EntityInfo.kind = CXIdxEntity_Struct; break;
429 case TTK_Union:
430 EntityInfo.kind = CXIdxEntity_Union; break;
431 case TTK_Class:
432 EntityInfo.kind = CXIdxEntity_CXXClass; break;
433 case TTK_Enum:
434 EntityInfo.kind = CXIdxEntity_Enum; break;
435 }
436
437 } else {
438 switch (D->getKind()) {
439 case Decl::Typedef:
440 EntityInfo.kind = CXIdxEntity_Typedef; break;
441 case Decl::Function:
442 EntityInfo.kind = CXIdxEntity_Function; break;
443 case Decl::Var:
444 EntityInfo.kind = CXIdxEntity_Variable; break;
445 case Decl::Field:
446 EntityInfo.kind = CXIdxEntity_Field; break;
447 case Decl::EnumConstant:
448 EntityInfo.kind = CXIdxEntity_EnumConstant; break;
449 case Decl::ObjCInterface:
450 EntityInfo.kind = CXIdxEntity_ObjCClass; break;
451 case Decl::ObjCProtocol:
452 EntityInfo.kind = CXIdxEntity_ObjCProtocol; break;
453 case Decl::ObjCCategory:
454 EntityInfo.kind = CXIdxEntity_ObjCCategory; break;
455 case Decl::ObjCMethod:
Argyrios Kyrtzidis86acd722011-11-14 22:39:19 +0000456 if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
457 EntityInfo.kind = CXIdxEntity_ObjCInstanceMethod;
458 else
459 EntityInfo.kind = CXIdxEntity_ObjCClassMethod;
460 break;
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000461 case Decl::ObjCProperty:
462 EntityInfo.kind = CXIdxEntity_ObjCProperty; break;
463 case Decl::ObjCIvar:
464 EntityInfo.kind = CXIdxEntity_ObjCIvar; break;
465 default:
466 break;
467 }
468 }
469
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000470 if (IdentifierInfo *II = D->getIdentifier()) {
471 EntityInfo.name = SA.toCStr(II->getName());
472
473 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000474 EntityInfo.name = 0; // anonymous record/namespace.
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000475
476 } else {
477 unsigned Begin = SA.getCurSize();
478 {
479 llvm::raw_svector_ostream OS(SA.getBuffer());
480 D->printName(OS);
481 }
482 EntityInfo.name = SA.getCStr(Begin);
483 }
484
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000485 {
486 unsigned Begin = SA.getCurSize();
487 bool Ignore = getDeclCursorUSR(D, SA.getBuffer());
488 if (Ignore) {
489 EntityInfo.USR = "";
490 } else {
491 EntityInfo.USR = SA.getCStr(Begin);
492 }
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000493 }
494}
495
496CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
497 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
498 return MakeCursorTypeRef(TD, Loc, CXTU);
499 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
500 return MakeCursorObjCClassRef(ID, Loc, CXTU);
501 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
502 return MakeCursorObjCProtocolRef(PD, Loc, CXTU);
503
504 //assert(0 && "not yet");
505 return clang_getNullCursor();
506}