blob: 38868138cf2302a9484bf4cc4e052e328c6ccc4f [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
12#include "clang/AST/DeclVisitor.h"
13
14using namespace clang;
15using namespace cxindex;
16
17namespace {
18
19class IndexingDeclVisitor : public DeclVisitor<IndexingDeclVisitor, bool> {
20 IndexingContext &IndexCtx;
21
22public:
23 explicit IndexingDeclVisitor(IndexingContext &indexCtx)
24 : IndexCtx(indexCtx) { }
25
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000026 void handleDeclarator(DeclaratorDecl *D, const NamedDecl *Parent = 0) {
27 if (!Parent) Parent = D;
28 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent);
29 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
30 }
31
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000032 bool VisitFunctionDecl(FunctionDecl *D) {
33 IndexCtx.handleFunction(D);
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000034 handleDeclarator(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000035 if (D->isThisDeclarationADefinition()) {
36 const Stmt *Body = D->getBody();
37 if (Body) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000038 IndexCtx.indexBody(Body, D, D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000039 }
40 }
41 return true;
42 }
43
44 bool VisitVarDecl(VarDecl *D) {
45 IndexCtx.handleVar(D);
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000046 handleDeclarator(D);
47 IndexCtx.indexBody(D->getInit(), D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000048 return true;
49 }
50
51 bool VisitFieldDecl(FieldDecl *D) {
52 IndexCtx.handleField(D);
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000053 handleDeclarator(D);
54 if (D->isBitField())
55 IndexCtx.indexBody(D->getBitWidth(), D);
56 else if (D->hasInClassInitializer())
57 IndexCtx.indexBody(D->getInClassInitializer(), D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000058 return true;
59 }
60
61 bool VisitEnumConstantDecl(EnumConstantDecl *D) {
62 IndexCtx.handleEnumerator(D);
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000063 IndexCtx.indexBody(D->getInitExpr(), D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000064 return true;
65 }
66
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +000067 bool VisitTypedefDecl(TypedefNameDecl *D) {
68 IndexCtx.handleTypedefName(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000069 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
70 return true;
71 }
72
73 bool VisitTagDecl(TagDecl *D) {
74 // Non-free standing tags are handled in indexTypeSourceInfo.
75 if (D->isFreeStanding())
76 IndexCtx.indexTagDecl(D);
77 return true;
78 }
79
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000080 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
81 ObjCForwardProtocolDecl::protocol_loc_iterator LI = D->protocol_loc_begin();
82 for (ObjCForwardProtocolDecl::protocol_iterator
83 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) {
84 SourceLocation Loc = *LI;
85 ObjCProtocolDecl *PD = *I;
86
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000087 bool isRedeclaration = PD->getLocation() != Loc;
88 IndexCtx.handleObjCForwardProtocol(PD, Loc, isRedeclaration);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000089 }
90 return true;
91 }
92
93 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000094 IndexCtx.handleObjCInterface(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000095
Douglas Gregor375bb142011-12-27 22:43:10 +000096 if (D->isThisDeclarationADefinition()) {
97 IndexCtx.indexTUDeclsInObjCContainer();
98 IndexCtx.indexDeclContext(D);
99 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000100 return true;
101 }
102
103 bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000104 // Forward decls are handled at VisitObjCForwardProtocolDecl.
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000105 if (D->isForwardDecl())
106 return true;
107
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000108 IndexCtx.handleObjCProtocol(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000109
110 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000111 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000112 return true;
113 }
114
115 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
Argyrios Kyrtzidise7bbab92011-11-15 06:20:24 +0000116 const ObjCInterfaceDecl *Class = D->getClassInterface();
Argyrios Kyrtzidis37f40572011-11-23 20:27:26 +0000117 if (!Class)
118 return true;
119
Argyrios Kyrtzidise7bbab92011-11-15 06:20:24 +0000120 if (Class->isImplicitInterfaceDecl())
121 IndexCtx.handleObjCInterface(Class);
122
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000123 IndexCtx.handleObjCImplementation(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000124
125 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000126 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000127 return true;
128 }
129
130 bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000131 IndexCtx.handleObjCCategory(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000132
133 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000134 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000135 return true;
136 }
137
138 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Argyrios Kyrtzidis37f40572011-11-23 20:27:26 +0000139 const ObjCCategoryDecl *Cat = D->getCategoryDecl();
140 if (!Cat)
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000141 return true;
142
143 IndexCtx.handleObjCCategoryImpl(D);
144
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000145 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000146 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000147 return true;
148 }
149
150 bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
151 IndexCtx.handleObjCMethod(D);
152 IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
153 for (ObjCMethodDecl::param_iterator
154 I = D->param_begin(), E = D->param_end(); I != E; ++I)
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000155 handleDeclarator(*I, D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000156
157 if (D->isThisDeclarationADefinition()) {
158 const Stmt *Body = D->getBody();
159 if (Body) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000160 IndexCtx.indexBody(Body, D, D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000161 }
162 }
163 return true;
164 }
165
166 bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
167 IndexCtx.handleObjCProperty(D);
168 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
169 return true;
170 }
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000171
172 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
173 ObjCPropertyDecl *PD = D->getPropertyDecl();
174 IndexCtx.handleSynthesizedObjCProperty(D);
175
176 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
177 return true;
178 assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
179
180 if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
181 if (!IvarD->getSynthesize())
182 IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), 0,
183 D->getDeclContext());
184 }
185
186 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
187 if (MD->isSynthesized())
188 IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation());
189 }
190 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
191 if (MD->isSynthesized())
192 IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation());
193 }
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000194 return true;
195 }
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000196
Argyrios Kyrtzidis68478b02011-12-07 05:52:06 +0000197 bool VisitNamespaceDecl(NamespaceDecl *D) {
198 IndexCtx.handleNamespace(D);
199 IndexCtx.indexDeclContext(D);
200 return true;
201 }
202
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000203 bool VisitClassTemplateDecl(ClassTemplateDecl *D) {
204 IndexCtx.handleClassTemplate(D);
205 if (D->isThisDeclarationADefinition())
206 IndexCtx.indexDeclContext(D->getTemplatedDecl());
207 return true;
208 }
209
210 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
211 IndexCtx.handleFunctionTemplate(D);
212 FunctionDecl *FD = D->getTemplatedDecl();
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000213 handleDeclarator(FD, D);
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000214 if (FD->isThisDeclarationADefinition()) {
215 const Stmt *Body = FD->getBody();
216 if (Body) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000217 IndexCtx.indexBody(Body, D, FD);
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000218 }
219 }
220 return true;
221 }
222
223 bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
224 IndexCtx.handleTypeAliasTemplate(D);
225 IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000226 return true;
227 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000228};
229
230} // anonymous namespace
231
232void IndexingContext::indexDecl(const Decl *D) {
233 bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
234 if (!Handled && isa<DeclContext>(D))
235 indexDeclContext(cast<DeclContext>(D));
236}
237
238void IndexingContext::indexDeclContext(const DeclContext *DC) {
239 for (DeclContext::decl_iterator
240 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
241 indexDecl(*I);
242 }
243}
244
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000245void IndexingContext::indexTopLevelDecl(Decl *D) {
246 if (isNotFromSourceFile(D->getLocation()))
247 return;
248
249 if (isa<ObjCMethodDecl>(D))
250 return; // Wait for the objc container.
251
252 indexDecl(D);
253}
254
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000255void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000256 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
257 indexTopLevelDecl(*I);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000258}
259
260void IndexingContext::indexTUDeclsInObjCContainer() {
261 for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i)
262 indexDeclGroupRef(TUDeclsInObjCContainer[i]);
263 TUDeclsInObjCContainer.clear();
264}