blob: d31ccdf0615de1ecb5ca32f481ae327fa02291e1 [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"
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000016#include "clang/AST/DeclTemplate.h"
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000017
18using namespace clang;
19using namespace cxindex;
20using namespace cxcursor;
21
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +000022IndexingContext::ObjCProtocolListInfo::ObjCProtocolListInfo(
23 const ObjCProtocolList &ProtList,
24 IndexingContext &IdxCtx,
25 StrAdapter &SA) {
26 ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
27 for (ObjCInterfaceDecl::protocol_iterator
28 I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
29 SourceLocation Loc = *LI;
30 ObjCProtocolDecl *PD = *I;
31 ProtEntities.push_back(CXIdxEntityInfo());
32 IdxCtx.getEntityInfo(PD, ProtEntities.back(), SA);
33 CXIdxObjCProtocolRefInfo ProtInfo = { 0,
34 MakeCursorObjCProtocolRef(PD, Loc, IdxCtx.CXTU),
35 IdxCtx.getIndexLoc(Loc) };
36 ProtInfos.push_back(ProtInfo);
37 }
38
39 for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)
40 ProtInfos[i].protocol = &ProtEntities[i];
41
42 for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)
43 Prots.push_back(&ProtInfos[i]);
44}
45
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000046IndexingContext::AttrListInfo::AttrListInfo(const Decl *D,
47 IndexingContext &IdxCtx,
48 StrAdapter &SA) {
49 for (AttrVec::const_iterator AttrI = D->attr_begin(), AttrE = D->attr_end();
50 AttrI != AttrE; ++AttrI) {
51 const Attr *A = *AttrI;
52 CXCursor C = MakeCXCursor(A, const_cast<Decl *>(D), IdxCtx.CXTU);
53 CXIdxLoc Loc = IdxCtx.getIndexLoc(A->getLocation());
54 switch (C.kind) {
55 default:
56 Attrs.push_back(AttrInfo(CXIdxAttr_Unexposed, C, Loc, A));
57 break;
58 case CXCursor_IBActionAttr:
59 Attrs.push_back(AttrInfo(CXIdxAttr_IBAction, C, Loc, A));
60 break;
61 case CXCursor_IBOutletAttr:
62 Attrs.push_back(AttrInfo(CXIdxAttr_IBOutlet, C, Loc, A));
63 break;
64 case CXCursor_IBOutletCollectionAttr:
65 IBCollAttrs.push_back(IBOutletCollectionInfo(C, Loc, A));
66 break;
67 }
68 }
69
70 for (unsigned i = 0, e = IBCollAttrs.size(); i != e; ++i) {
71 IBOutletCollectionInfo &IBInfo = IBCollAttrs[i];
72 CXAttrs.push_back(&IBInfo);
73
74 const IBOutletCollectionAttr *
75 IBAttr = cast<IBOutletCollectionAttr>(IBInfo.A);
76 IBInfo.IBCollInfo.attrInfo = &IBInfo;
77 IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(IBAttr->getInterfaceLoc());
78 IBInfo.IBCollInfo.objcClass = 0;
79 IBInfo.IBCollInfo.classCursor = clang_getNullCursor();
80 QualType Ty = IBAttr->getInterface();
81 if (const ObjCInterfaceType *InterTy = Ty->getAs<ObjCInterfaceType>()) {
82 if (const ObjCInterfaceDecl *InterD = InterTy->getInterface()) {
83 IdxCtx.getEntityInfo(InterD, IBInfo.CXClassInfo, SA);
84 IBInfo.IBCollInfo.objcClass = &IBInfo.CXClassInfo;
85 IBInfo.IBCollInfo.classCursor = MakeCursorObjCClassRef(InterD,
86 IBAttr->getInterfaceLoc(), IdxCtx.CXTU);
87 }
88 }
89 }
90
91 for (unsigned i = 0, e = Attrs.size(); i != e; ++i)
92 CXAttrs.push_back(&Attrs[i]);
93}
94
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000095const char *IndexingContext::StrAdapter::toCStr(StringRef Str) {
96 if (Str.empty())
97 return "";
98 if (Str.data()[Str.size()] == '\0')
99 return Str.data();
100 Scratch += Str;
101 Scratch.push_back('\0');
102 return Scratch.data() + (Scratch.size() - Str.size() - 1);
103}
104
105void IndexingContext::setASTContext(ASTContext &ctx) {
106 Ctx = &ctx;
107 static_cast<ASTUnit*>(CXTU->TUData)->setASTContext(&ctx);
108}
109
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000110bool IndexingContext::shouldAbort() {
111 if (!CB.abortQuery)
112 return false;
113 return CB.abortQuery(ClientData, 0);
114}
115
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000116void IndexingContext::enteredMainFile(const FileEntry *File) {
117 if (File && CB.enteredMainFile) {
118 CXIdxClientFile idxFile = CB.enteredMainFile(ClientData, (CXFile)File, 0);
119 FileMap[File] = idxFile;
120 }
121}
122
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000123void IndexingContext::ppIncludedFile(SourceLocation hashLoc,
124 StringRef filename,
125 const FileEntry *File,
126 bool isImport, bool isAngled) {
127 if (!CB.ppIncludedFile)
128 return;
129
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000130 StrAdapter SA(*this);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000131 CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
132 SA.toCStr(filename),
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000133 (CXFile)File,
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000134 isImport, isAngled };
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000135 CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info);
136 FileMap[File] = idxFile;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000137}
138
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000139void IndexingContext::startedTranslationUnit() {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000140 CXIdxClientContainer idxCont = 0;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000141 if (CB.startedTranslationUnit)
142 idxCont = CB.startedTranslationUnit(ClientData, 0);
143 addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
144}
145
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000146void IndexingContext::handleDiagnosticSet(CXDiagnostic CXDiagSet) {
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000147 if (!CB.diagnostic)
148 return;
149
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000150 CB.diagnostic(ClientData, CXDiagSet, 0);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000151}
152
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000153bool IndexingContext::handleDecl(const NamedDecl *D,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000154 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000155 DeclInfo &DInfo) {
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000156 if (!CB.indexDeclaration || !D)
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000157 return false;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000158
159 StrAdapter SA(*this);
160 getEntityInfo(D, DInfo.CXEntInfo, SA);
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000161 if (!DInfo.CXEntInfo.USR || Loc.isInvalid())
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000162 return false;
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000163
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000164 markEntityOccurrenceInFile(D, Loc);
165
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000166 DInfo.entityInfo = &DInfo.CXEntInfo;
167 DInfo.cursor = Cursor;
168 DInfo.loc = getIndexLoc(Loc);
169 DInfo.container = getIndexContainer(D);
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000170 DInfo.isImplicit = D->isImplicit();
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000171
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000172 AttrListInfo AttrList(D, *this, SA);
173 DInfo.attributes = AttrList.getAttrs();
174 DInfo.numAttributes = AttrList.getNumAttrs();
175
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000176 CXIdxClientContainer clientCont = 0;
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000177 CXIdxDeclOut DeclOut = { DInfo.isContainer ? &clientCont : 0 };
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000178 CB.indexDeclaration(ClientData, &DInfo, &DeclOut);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000179
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000180 if (DInfo.isContainer)
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000181 addContainerInMap(cast<DeclContext>(D), clientCont);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000182
183 return true;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000184}
185
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000186bool IndexingContext::handleObjCContainer(const ObjCContainerDecl *D,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000187 SourceLocation Loc, CXCursor Cursor,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000188 ObjCContainerDeclInfo &ContDInfo) {
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000189 ContDInfo.ObjCContDeclInfo.declInfo = &ContDInfo;
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000190 return handleDecl(D, Loc, Cursor, ContDInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000191}
192
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000193bool IndexingContext::handleFunction(const FunctionDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000194 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
195 D->isThisDeclarationADefinition());
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000196 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000197}
198
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000199bool IndexingContext::handleVar(const VarDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000200 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
201 /*isContainer=*/false);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000202 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000203}
204
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000205bool IndexingContext::handleField(const FieldDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000206 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
207 /*isContainer=*/false);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000208 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000209}
210
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000211bool IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000212 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
213 /*isContainer=*/false);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000214 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000215}
216
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000217bool IndexingContext::handleTagDecl(const TagDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000218 DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
219 D->isThisDeclarationADefinition());
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000220 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000221}
222
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000223bool IndexingContext::handleTypedef(const TypedefDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000224 DeclInfo DInfo(!D->isFirstDeclaration(), /*isDefinition=*/true,
225 /*isContainer=*/false);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000226 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000227}
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000228
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000229bool IndexingContext::handleObjCClass(const ObjCClassDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000230 const ObjCClassDecl::ObjCClassRef *Ref = D->getForwardDecl();
231 ObjCInterfaceDecl *IFaceD = Ref->getInterface();
232 SourceLocation Loc = Ref->getLocation();
233 bool isRedeclaration = IFaceD->getLocation() != Loc;
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000234
235 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true, isRedeclaration,
236 /*isImplementation=*/false);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000237 return handleObjCContainer(IFaceD, Loc,
238 MakeCursorObjCClassRef(IFaceD, Loc, CXTU), ContDInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000239}
240
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000241bool IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000242 StrAdapter SA(*this);
243
244 CXIdxBaseClassInfo BaseClass;
245 CXIdxEntityInfo BaseEntity;
246 BaseClass.cursor = clang_getNullCursor();
247 if (ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
248 getEntityInfo(SuperD, BaseEntity, SA);
249 SourceLocation SuperLoc = D->getSuperClassLoc();
250 BaseClass.base = &BaseEntity;
251 BaseClass.cursor = MakeCursorObjCSuperClassRef(SuperD, SuperLoc, CXTU);
252 BaseClass.loc = getIndexLoc(SuperLoc);
253 }
254
255 ObjCProtocolListInfo ProtInfo(D->getReferencedProtocols(), *this, SA);
256
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000257 ObjCInterfaceDeclInfo InterInfo(D);
258 InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();
259 InterInfo.ObjCInterDeclInfo.containerInfo = &InterInfo.ObjCContDeclInfo;
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000260 InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass : 0;
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000261 InterInfo.ObjCInterDeclInfo.protocols = &InterInfo.ObjCProtoListInfo;
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000262
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000263 return handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000264}
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000265
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000266bool IndexingContext::handleObjCImplementation(
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000267 const ObjCImplementationDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000268 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/false,
Argyrios Kyrtzidise7bbab92011-11-15 06:20:24 +0000269 /*isRedeclaration=*/true,
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000270 /*isImplementation=*/true);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000271 return handleObjCContainer(D, D->getLocation(), getCursor(D), ContDInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000272}
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000273
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000274bool IndexingContext::handleObjCForwardProtocol(const ObjCProtocolDecl *D,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000275 SourceLocation Loc,
276 bool isRedeclaration) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000277 ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true,
278 isRedeclaration,
279 /*isImplementation=*/false);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000280 return handleObjCContainer(D, Loc, MakeCursorObjCProtocolRef(D, Loc, CXTU),
281 ContDInfo);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000282}
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000283
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000284bool IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000285 StrAdapter SA(*this);
286 ObjCProtocolListInfo ProtListInfo(D->getReferencedProtocols(), *this, SA);
287
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000288 ObjCProtocolDeclInfo ProtInfo(D);
289 ProtInfo.ObjCProtoRefListInfo = ProtListInfo.getListInfo();
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000290
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000291 return handleObjCContainer(D, D->getLocation(), getCursor(D), ProtInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000292}
293
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000294bool IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000295 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000296 CXIdxEntityInfo ClassEntity;
297 StrAdapter SA(*this);
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000298 const ObjCInterfaceDecl *IFaceD = D->getClassInterface();
299 SourceLocation ClassLoc = D->getLocation();
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000300 SourceLocation CategoryLoc = D->IsClassExtension() ? ClassLoc
301 : D->getCategoryNameLoc();
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000302 getEntityInfo(IFaceD, ClassEntity, SA);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000303
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000304 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000305 if (IFaceD) {
306 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
307 CatDInfo.ObjCCatDeclInfo.classCursor =
308 MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
309 } else {
310 CatDInfo.ObjCCatDeclInfo.objcClass = 0;
311 CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
312 }
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000313 CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000314 return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000315}
316
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000317bool IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000318 const ObjCCategoryDecl *CatD = D->getCategoryDecl();
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000319 ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000320 CXIdxEntityInfo ClassEntity;
321 StrAdapter SA(*this);
Argyrios Kyrtzidis3e340a62011-11-16 02:35:05 +0000322 const ObjCInterfaceDecl *IFaceD = CatD->getClassInterface();
323 SourceLocation ClassLoc = D->getLocation();
324 SourceLocation CategoryLoc = ClassLoc; //FIXME: D->getCategoryNameLoc();
325 getEntityInfo(IFaceD, ClassEntity, SA);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000326
Argyrios Kyrtzidis6ec43ad2011-11-12 02:16:30 +0000327 CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
Argyrios Kyrtzidis3e340a62011-11-16 02:35:05 +0000328 if (IFaceD) {
329 CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
330 CatDInfo.ObjCCatDeclInfo.classCursor =
331 MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
332 } else {
333 CatDInfo.ObjCCatDeclInfo.objcClass = 0;
334 CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
335 }
336 CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000337 return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000338}
339
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000340bool IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000341 DeclInfo DInfo(!D->isCanonicalDecl(), D->isThisDeclarationADefinition(),
342 D->isThisDeclarationADefinition());
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000343 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000344}
345
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000346bool IndexingContext::handleSynthesizedObjCProperty(
347 const ObjCPropertyImplDecl *D) {
348 ObjCPropertyDecl *PD = D->getPropertyDecl();
349 return handleReference(PD, D->getLocation(), getCursor(D), 0, D->getDeclContext());
350}
351
352bool IndexingContext::handleSynthesizedObjCMethod(const ObjCMethodDecl *D,
353 SourceLocation Loc) {
354 DeclInfo DInfo(/*isRedeclaration=*/true, /*isDefinition=*/true,
355 /*isContainer=*/false);
356 return handleDecl(D, Loc, getCursor(D), DInfo);
357}
358
359bool IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000360 DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/false,
361 /*isContainer=*/false);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000362 return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000363}
364
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000365bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000366 const NamedDecl *Parent,
367 const DeclContext *DC,
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +0000368 const Expr *E,
369 CXIdxEntityRefKind Kind) {
Argyrios Kyrtzidisd6c82092011-11-16 02:35:01 +0000370 if (!D)
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000371 return false;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000372
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000373 CXCursor Cursor = E ? MakeCXCursor(const_cast<Expr*>(E),
374 const_cast<Decl*>(cast<Decl>(DC)), CXTU)
375 : getRefCursor(D, Loc);
376 return handleReference(D, Loc, Cursor, Parent, DC, E, Kind);
377}
378
379bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
380 CXCursor Cursor,
381 const NamedDecl *Parent,
382 const DeclContext *DC,
383 const Expr *E,
384 CXIdxEntityRefKind Kind) {
385 if (!D)
386 return false;
387 if (D->getParentFunctionOrMethod())
388 return false;
389 if (Loc.isInvalid())
390 return false;
391 if (!CB.indexEntityReference)
392 return false;
393 if (isNotFromSourceFile(D->getLocation()))
394 return false;
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000395
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000396 StrAdapter SA(*this);
397 CXIdxEntityInfo RefEntity, ParentEntity;
398 getEntityInfo(D, RefEntity, SA);
399 if (!RefEntity.USR)
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000400 return false;
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000401
402 getEntityInfo(Parent, ParentEntity, SA);
403
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000404 if (suppressRefs()) {
405 if (markEntityOccurrenceInFile(D, Loc))
406 return false; // already occurred.
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000407 }
408
Benjamin Kramer854625f2011-10-28 13:37:11 +0000409 CXIdxEntityRefInfo Info = { Cursor,
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000410 getIndexLoc(Loc),
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000411 &RefEntity,
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000412 Parent ? &ParentEntity : 0,
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +0000413 getIndexContainerForDC(DC),
414 Kind };
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000415 CB.indexEntityReference(ClientData, &Info);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000416 return true;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000417}
418
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000419bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
420 if (Loc.isInvalid())
421 return true;
422 SourceManager &SM = Ctx->getSourceManager();
423 SourceLocation FileLoc = SM.getFileLoc(Loc);
424 FileID FID = SM.getFileID(FileLoc);
425 return SM.getFileEntryForID(FID) == 0;
426}
427
428void IndexingContext::addContainerInMap(const DeclContext *DC,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000429 CXIdxClientContainer container) {
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000430 assert(getScopedContext(DC) == DC);
431 ContainerMapTy::iterator I = ContainerMap.find(DC);
432 if (I == ContainerMap.end()) {
433 if (container)
434 ContainerMap[DC] = container;
435 return;
436 }
437 // Allow changing the container of a previously seen DeclContext so we
438 // can handle invalid user code, like a function re-definition.
439 if (container)
440 I->second = container;
441 else
442 ContainerMap.erase(I);
443}
444
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000445bool IndexingContext::markEntityOccurrenceInFile(const NamedDecl *D,
446 SourceLocation Loc) {
447 SourceManager &SM = Ctx->getSourceManager();
448 SourceLocation FileLoc = SM.getFileLoc(Loc);
449 D = getEntityDecl(D);
450
451 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
452 FileID FID = LocInfo.first;
453 if (FID.isInvalid())
454 return true;
455
456 const FileEntry *FE = SM.getFileEntryForID(FID);
457 if (!FE)
458 return true;
459 RefFileOccurence RefOccur(FE, D);
460 std::pair<llvm::DenseSet<RefFileOccurence>::iterator, bool>
461 res = RefFileOccurences.insert(RefOccur);
462 if (!res.second)
463 return true; // already in map.
464
465 return false;
466}
467
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000468const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
469 assert(D);
470 D = cast<NamedDecl>(D->getCanonicalDecl());
471
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000472 if (const ObjCImplementationDecl *
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000473 ImplD = dyn_cast<ObjCImplementationDecl>(D)) {
474 return getEntityDecl(ImplD->getClassInterface());
475
476 } else if (const ObjCCategoryImplDecl *
477 CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {
478 return getEntityDecl(CatImplD->getCategoryDecl());
479 }
480
481 return D;
482}
483
484const DeclContext *
485IndexingContext::getScopedContext(const DeclContext *DC) const {
486 // Local contexts are ignored for indexing.
487 const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod();
488 if (FuncCtx)
489 return FuncCtx;
490
491 // We consider enums always scoped for indexing.
492 if (isa<TagDecl>(DC))
493 return DC;
494
495 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
496 if (NS->isAnonymousNamespace())
497 return getScopedContext(NS->getParent());
498 return NS;
499 }
500
501 return DC->getRedeclContext();
502}
503
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000504CXIdxClientContainer
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000505IndexingContext::getIndexContainerForDC(const DeclContext *DC) const {
506 DC = getScopedContext(DC);
507 ContainerMapTy::const_iterator I = ContainerMap.find(DC);
Argyrios Kyrtzidis3e340a62011-11-16 02:35:05 +0000508 if (I == ContainerMap.end())
509 return 0;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000510// assert(I != ContainerMap.end() &&
511// "Failed to include a scoped context in the container map");
512 return I->second;
513}
514
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000515CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) {
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000516 if (!File)
517 return 0;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000518
519 FileMapTy::iterator FI = FileMap.find(File);
520 if (FI != FileMap.end())
521 return FI->second;
522
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000523 return 0;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000524}
525
526CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
527 CXIdxLoc idxLoc = { {0, 0}, 0 };
528 if (Loc.isInvalid())
529 return idxLoc;
530
531 idxLoc.ptr_data[0] = (void*)this;
532 idxLoc.int_data = Loc.getRawEncoding();
533 return idxLoc;
534}
535
536void IndexingContext::translateLoc(SourceLocation Loc,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000537 CXIdxClientFile *indexFile, CXFile *file,
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000538 unsigned *line, unsigned *column,
539 unsigned *offset) {
540 if (Loc.isInvalid())
541 return;
542
543 SourceManager &SM = Ctx->getSourceManager();
544 Loc = SM.getFileLoc(Loc);
545
546 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
547 FileID FID = LocInfo.first;
548 unsigned FileOffset = LocInfo.second;
549
550 if (FID.isInvalid())
551 return;
552
553 const FileEntry *FE = SM.getFileEntryForID(FID);
554 if (indexFile)
555 *indexFile = getIndexFile(FE);
556 if (file)
557 *file = (void *)FE;
558 if (line)
559 *line = SM.getLineNumber(FID, FileOffset);
560 if (column)
561 *column = SM.getColumnNumber(FID, FileOffset);
562 if (offset)
563 *offset = FileOffset;
564}
565
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000566void IndexingContext::getEntityInfo(const NamedDecl *D,
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000567 CXIdxEntityInfo &EntityInfo,
568 StrAdapter &SA) {
Argyrios Kyrtzidisc6b4a502011-11-16 02:34:59 +0000569 if (!D)
570 return;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000571 D = getEntityDecl(D);
572 EntityInfo.kind = CXIdxEntity_Unexposed;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000573
574 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
575 switch (TD->getTagKind()) {
576 case TTK_Struct:
577 EntityInfo.kind = CXIdxEntity_Struct; break;
578 case TTK_Union:
579 EntityInfo.kind = CXIdxEntity_Union; break;
580 case TTK_Class:
581 EntityInfo.kind = CXIdxEntity_CXXClass; break;
582 case TTK_Enum:
583 EntityInfo.kind = CXIdxEntity_Enum; break;
584 }
585
586 } else {
587 switch (D->getKind()) {
588 case Decl::Typedef:
589 EntityInfo.kind = CXIdxEntity_Typedef; break;
590 case Decl::Function:
591 EntityInfo.kind = CXIdxEntity_Function; break;
592 case Decl::Var:
593 EntityInfo.kind = CXIdxEntity_Variable; break;
594 case Decl::Field:
595 EntityInfo.kind = CXIdxEntity_Field; break;
596 case Decl::EnumConstant:
597 EntityInfo.kind = CXIdxEntity_EnumConstant; break;
598 case Decl::ObjCInterface:
599 EntityInfo.kind = CXIdxEntity_ObjCClass; break;
600 case Decl::ObjCProtocol:
601 EntityInfo.kind = CXIdxEntity_ObjCProtocol; break;
602 case Decl::ObjCCategory:
603 EntityInfo.kind = CXIdxEntity_ObjCCategory; break;
604 case Decl::ObjCMethod:
Argyrios Kyrtzidisc71d5542011-11-14 22:39:19 +0000605 if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
606 EntityInfo.kind = CXIdxEntity_ObjCInstanceMethod;
607 else
608 EntityInfo.kind = CXIdxEntity_ObjCClassMethod;
609 break;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000610 case Decl::ObjCProperty:
611 EntityInfo.kind = CXIdxEntity_ObjCProperty; break;
612 case Decl::ObjCIvar:
613 EntityInfo.kind = CXIdxEntity_ObjCIvar; break;
614 default:
615 break;
616 }
617 }
618
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000619 if (IdentifierInfo *II = D->getIdentifier()) {
620 EntityInfo.name = SA.toCStr(II->getName());
621
622 } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000623 EntityInfo.name = 0; // anonymous record/namespace.
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000624
625 } else {
626 unsigned Begin = SA.getCurSize();
627 {
628 llvm::raw_svector_ostream OS(SA.getBuffer());
629 D->printName(OS);
630 }
631 EntityInfo.name = SA.getCStr(Begin);
632 }
633
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000634 {
635 unsigned Begin = SA.getCurSize();
636 bool Ignore = getDeclCursorUSR(D, SA.getBuffer());
637 if (Ignore) {
Argyrios Kyrtzidis144b6c02011-11-18 00:26:46 +0000638 EntityInfo.USR = 0;
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000639 } else {
640 EntityInfo.USR = SA.getCStr(Begin);
641 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000642 }
643}
644
645CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
646 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
647 return MakeCursorTypeRef(TD, Loc, CXTU);
648 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
649 return MakeCursorObjCClassRef(ID, Loc, CXTU);
650 if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
651 return MakeCursorObjCProtocolRef(PD, Loc, CXTU);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000652 if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
653 return MakeCursorTemplateRef(Template, Loc, CXTU);
654 if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(D))
655 return MakeCursorNamespaceRef(Namespace, Loc, CXTU);
656 if (const NamespaceAliasDecl *Namespace = dyn_cast<NamespaceAliasDecl>(D))
657 return MakeCursorNamespaceRef(Namespace, Loc, CXTU);
658 if (const FieldDecl *Field = dyn_cast<FieldDecl>(D))
659 return MakeCursorMemberRef(Field, Loc, CXTU);
660
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000661 return clang_getNullCursor();
662}