blob: 792834998313481eb0cd4aa6f006f07fca0794e8 [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"
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000011#include "clang/AST/DeclVisitor.h"
12
13using namespace clang;
14using namespace cxindex;
15
16namespace {
17
18class IndexingDeclVisitor : public DeclVisitor<IndexingDeclVisitor, bool> {
19 IndexingContext &IndexCtx;
20
21public:
22 explicit IndexingDeclVisitor(IndexingContext &indexCtx)
23 : IndexCtx(indexCtx) { }
24
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000025 void handleDeclarator(DeclaratorDecl *D, const NamedDecl *Parent = 0) {
26 if (!Parent) Parent = D;
Argyrios Kyrtzidisdb4d7a52012-01-14 02:05:51 +000027
Argyrios Kyrtzidis58d2dbe2012-02-14 22:23:11 +000028 if (!IndexCtx.shouldIndexFunctionLocalSymbols()) {
Argyrios Kyrtzidisdb4d7a52012-01-14 02:05:51 +000029 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent);
30 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
31 } else {
32 if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
33 IndexCtx.handleVar(Parm);
34 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
35 for (FunctionDecl::param_iterator
36 PI = FD->param_begin(), PE = FD->param_end(); PI != PE; ++PI) {
37 IndexCtx.handleVar(*PI);
38 }
39 }
40 }
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000041 }
42
Argyrios Kyrtzidisd7c15a62012-02-28 17:50:28 +000043 void handleObjCMethod(ObjCMethodDecl *D) {
44 IndexCtx.handleObjCMethod(D);
45 if (D->isImplicit())
46 return;
47
48 IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
49 for (ObjCMethodDecl::param_iterator
50 I = D->param_begin(), E = D->param_end(); I != E; ++I)
51 handleDeclarator(*I, D);
52
53 if (D->isThisDeclarationADefinition()) {
54 const Stmt *Body = D->getBody();
55 if (Body) {
56 IndexCtx.indexBody(Body, D, D);
57 }
58 }
59 }
60
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000061 bool VisitFunctionDecl(FunctionDecl *D) {
62 IndexCtx.handleFunction(D);
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000063 handleDeclarator(D);
Argyrios Kyrtzidis8818d452012-01-23 16:58:36 +000064
65 if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
66 // Constructor initializers.
67 for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
68 E = Ctor->init_end();
69 I != E; ++I) {
70 CXXCtorInitializer *Init = *I;
71 if (Init->isWritten()) {
72 IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
73 if (const FieldDecl *Member = Init->getAnyMember())
74 IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D);
75 IndexCtx.indexBody(Init->getInit(), D, D);
76 }
77 }
78 }
79
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000080 if (D->isThisDeclarationADefinition()) {
81 const Stmt *Body = D->getBody();
82 if (Body) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000083 IndexCtx.indexBody(Body, D, D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000084 }
85 }
86 return true;
87 }
88
89 bool VisitVarDecl(VarDecl *D) {
90 IndexCtx.handleVar(D);
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000091 handleDeclarator(D);
92 IndexCtx.indexBody(D->getInit(), D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000093 return true;
94 }
95
96 bool VisitFieldDecl(FieldDecl *D) {
97 IndexCtx.handleField(D);
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000098 handleDeclarator(D);
99 if (D->isBitField())
100 IndexCtx.indexBody(D->getBitWidth(), D);
101 else if (D->hasInClassInitializer())
102 IndexCtx.indexBody(D->getInClassInitializer(), D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000103 return true;
104 }
105
106 bool VisitEnumConstantDecl(EnumConstantDecl *D) {
107 IndexCtx.handleEnumerator(D);
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000108 IndexCtx.indexBody(D->getInitExpr(), D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000109 return true;
110 }
111
Argyrios Kyrtzidis754a5d12012-09-01 19:08:08 +0000112 bool VisitTypedefNameDecl(TypedefNameDecl *D) {
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000113 IndexCtx.handleTypedefName(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000114 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
115 return true;
116 }
117
118 bool VisitTagDecl(TagDecl *D) {
119 // Non-free standing tags are handled in indexTypeSourceInfo.
120 if (D->isFreeStanding())
121 IndexCtx.indexTagDecl(D);
122 return true;
123 }
124
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000125 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000126 IndexCtx.handleObjCInterface(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000127
Douglas Gregor375bb142011-12-27 22:43:10 +0000128 if (D->isThisDeclarationADefinition()) {
129 IndexCtx.indexTUDeclsInObjCContainer();
130 IndexCtx.indexDeclContext(D);
131 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000132 return true;
133 }
134
135 bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000136 IndexCtx.handleObjCProtocol(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000137
Douglas Gregorbd9482d2012-01-01 21:23:57 +0000138 if (D->isThisDeclarationADefinition()) {
139 IndexCtx.indexTUDeclsInObjCContainer();
140 IndexCtx.indexDeclContext(D);
141 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000142 return true;
143 }
144
145 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
Argyrios Kyrtzidise7bbab92011-11-15 06:20:24 +0000146 const ObjCInterfaceDecl *Class = D->getClassInterface();
Argyrios Kyrtzidis37f40572011-11-23 20:27:26 +0000147 if (!Class)
148 return true;
149
Argyrios Kyrtzidise7bbab92011-11-15 06:20:24 +0000150 if (Class->isImplicitInterfaceDecl())
151 IndexCtx.handleObjCInterface(Class);
152
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000153 IndexCtx.handleObjCImplementation(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000154
155 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis390fff82012-06-08 02:16:11 +0000156
157 // Index the ivars first to make sure the synthesized ivars are indexed
158 // before indexing the methods that can reference them.
159 for (ObjCImplementationDecl::ivar_iterator
160 IvarI = D->ivar_begin(),
161 IvarE = D->ivar_end(); IvarI != IvarE; ++IvarI) {
162 IndexCtx.indexDecl(*IvarI);
163 }
164 for (DeclContext::decl_iterator
165 I = D->decls_begin(), E = D->decls_end(); I != E; ++I) {
166 if (!isa<ObjCIvarDecl>(*I))
167 IndexCtx.indexDecl(*I);
168 }
169
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000170 return true;
171 }
172
173 bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000174 IndexCtx.handleObjCCategory(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000175
176 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000177 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000178 return true;
179 }
180
181 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Argyrios Kyrtzidis37f40572011-11-23 20:27:26 +0000182 const ObjCCategoryDecl *Cat = D->getCategoryDecl();
183 if (!Cat)
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000184 return true;
185
186 IndexCtx.handleObjCCategoryImpl(D);
187
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000188 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000189 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000190 return true;
191 }
192
193 bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
Argyrios Kyrtzidisd7c15a62012-02-28 17:50:28 +0000194 // Methods associated with a property, even user-declared ones, are
195 // handled when we handle the property.
Jordan Rose1e4691b2012-10-10 16:42:25 +0000196 if (D->isPropertyAccessor())
Argyrios Kyrtzidisd7c15a62012-02-28 17:50:28 +0000197 return true;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000198
Argyrios Kyrtzidisd7c15a62012-02-28 17:50:28 +0000199 handleObjCMethod(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000200 return true;
201 }
202
203 bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
Argyrios Kyrtzidisd7c15a62012-02-28 17:50:28 +0000204 if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
205 if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
206 handleObjCMethod(MD);
207 if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
208 if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
209 handleObjCMethod(MD);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000210 IndexCtx.handleObjCProperty(D);
211 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
212 return true;
213 }
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000214
215 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
216 ObjCPropertyDecl *PD = D->getPropertyDecl();
217 IndexCtx.handleSynthesizedObjCProperty(D);
218
219 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
220 return true;
221 assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
222
223 if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
224 if (!IvarD->getSynthesize())
225 IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), 0,
226 D->getDeclContext());
227 }
228
229 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
Jordan Rose1e4691b2012-10-10 16:42:25 +0000230 if (MD->isPropertyAccessor())
Argyrios Kyrtzidisf9112422012-02-28 17:50:39 +0000231 IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(),
232 D->getLexicalDeclContext());
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000233 }
234 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
Jordan Rose1e4691b2012-10-10 16:42:25 +0000235 if (MD->isPropertyAccessor())
Argyrios Kyrtzidisf9112422012-02-28 17:50:39 +0000236 IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(),
237 D->getLexicalDeclContext());
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000238 }
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000239 return true;
240 }
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000241
Argyrios Kyrtzidis68478b02011-12-07 05:52:06 +0000242 bool VisitNamespaceDecl(NamespaceDecl *D) {
243 IndexCtx.handleNamespace(D);
244 IndexCtx.indexDeclContext(D);
245 return true;
246 }
247
Argyrios Kyrtzidis911d7172012-02-10 20:10:48 +0000248 bool VisitUsingDecl(UsingDecl *D) {
249 // FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
250 // we should do better.
251
252 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
253 for (UsingDecl::shadow_iterator
254 I = D->shadow_begin(), E = D->shadow_end(); I != E; ++I) {
255 IndexCtx.handleReference((*I)->getUnderlyingDecl(), D->getLocation(),
256 D, D->getLexicalDeclContext());
257 }
258 return true;
259 }
260
261 bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
262 // FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
263 // we should do better.
264
265 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
266 IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
267 D->getLocation(), D, D->getLexicalDeclContext());
268 return true;
269 }
270
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000271 bool VisitClassTemplateDecl(ClassTemplateDecl *D) {
272 IndexCtx.handleClassTemplate(D);
273 if (D->isThisDeclarationADefinition())
274 IndexCtx.indexDeclContext(D->getTemplatedDecl());
275 return true;
276 }
277
Argyrios Kyrtzidis6d968362012-02-10 20:10:44 +0000278 bool VisitClassTemplateSpecializationDecl(
279 ClassTemplateSpecializationDecl *D) {
Argyrios Kyrtzidis58d2dbe2012-02-14 22:23:11 +0000280 // FIXME: Notify subsequent callbacks if info comes from implicit
Argyrios Kyrtzidis6d968362012-02-10 20:10:44 +0000281 // instantiation.
Argyrios Kyrtzidis58d2dbe2012-02-14 22:23:11 +0000282 if (D->isThisDeclarationADefinition() &&
283 (IndexCtx.shouldIndexImplicitTemplateInsts() ||
284 !IndexCtx.isTemplateImplicitInstantiation(D)))
Argyrios Kyrtzidis6d968362012-02-10 20:10:44 +0000285 IndexCtx.indexTagDecl(D);
286 return true;
287 }
288
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000289 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
290 IndexCtx.handleFunctionTemplate(D);
291 FunctionDecl *FD = D->getTemplatedDecl();
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000292 handleDeclarator(FD, D);
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000293 if (FD->isThisDeclarationADefinition()) {
294 const Stmt *Body = FD->getBody();
295 if (Body) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000296 IndexCtx.indexBody(Body, D, FD);
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000297 }
298 }
299 return true;
300 }
301
302 bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
303 IndexCtx.handleTypeAliasTemplate(D);
304 IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000305 return true;
306 }
Argyrios Kyrtzidis2c3e05c2012-10-02 16:10:38 +0000307
308 bool VisitImportDecl(ImportDecl *D) {
Argyrios Kyrtzidis37f2f522012-10-03 21:05:44 +0000309 IndexCtx.importedModule(D);
Argyrios Kyrtzidis2c3e05c2012-10-02 16:10:38 +0000310 return true;
311 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000312};
313
314} // anonymous namespace
315
316void IndexingContext::indexDecl(const Decl *D) {
Argyrios Kyrtzidisd0890082012-02-07 22:46:16 +0000317 if (D->isImplicit() && shouldIgnoreIfImplicit(D))
318 return;
319
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000320 bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
321 if (!Handled && isa<DeclContext>(D))
322 indexDeclContext(cast<DeclContext>(D));
323}
324
325void IndexingContext::indexDeclContext(const DeclContext *DC) {
326 for (DeclContext::decl_iterator
327 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
328 indexDecl(*I);
329 }
330}
331
Argyrios Kyrtzidis3bed3d12012-09-10 22:58:04 +0000332void IndexingContext::indexTopLevelDecl(const Decl *D) {
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000333 if (isNotFromSourceFile(D->getLocation()))
334 return;
335
336 if (isa<ObjCMethodDecl>(D))
337 return; // Wait for the objc container.
338
339 indexDecl(D);
340}
341
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000342void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000343 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
344 indexTopLevelDecl(*I);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000345}
346
347void IndexingContext::indexTUDeclsInObjCContainer() {
Argyrios Kyrtzidis30a28052012-03-23 23:24:18 +0000348 while (!TUDeclsInObjCContainer.empty()) {
349 DeclGroupRef DG = TUDeclsInObjCContainer.front();
350 TUDeclsInObjCContainer.pop_front();
351 indexDeclGroupRef(DG);
352 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000353}