blob: 9ff65b30f489d4c57535bc834544263f1a413047 [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 VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000081 IndexCtx.handleObjCInterface(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000082
Douglas Gregor375bb142011-12-27 22:43:10 +000083 if (D->isThisDeclarationADefinition()) {
84 IndexCtx.indexTUDeclsInObjCContainer();
85 IndexCtx.indexDeclContext(D);
86 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000087 return true;
88 }
89
90 bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +000091 IndexCtx.handleObjCProtocol(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000092
Douglas Gregorbd9482d2012-01-01 21:23:57 +000093 if (D->isThisDeclarationADefinition()) {
94 IndexCtx.indexTUDeclsInObjCContainer();
95 IndexCtx.indexDeclContext(D);
96 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000097 return true;
98 }
99
100 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
Argyrios Kyrtzidise7bbab92011-11-15 06:20:24 +0000101 const ObjCInterfaceDecl *Class = D->getClassInterface();
Argyrios Kyrtzidis37f40572011-11-23 20:27:26 +0000102 if (!Class)
103 return true;
104
Argyrios Kyrtzidise7bbab92011-11-15 06:20:24 +0000105 if (Class->isImplicitInterfaceDecl())
106 IndexCtx.handleObjCInterface(Class);
107
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000108 IndexCtx.handleObjCImplementation(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 VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000116 IndexCtx.handleObjCCategory(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000117
118 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000119 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000120 return true;
121 }
122
123 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Argyrios Kyrtzidis37f40572011-11-23 20:27:26 +0000124 const ObjCCategoryDecl *Cat = D->getCategoryDecl();
125 if (!Cat)
Argyrios Kyrtzidisdd93c592011-11-11 00:23:36 +0000126 return true;
127
128 IndexCtx.handleObjCCategoryImpl(D);
129
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000130 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000131 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000132 return true;
133 }
134
135 bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
136 IndexCtx.handleObjCMethod(D);
137 IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
138 for (ObjCMethodDecl::param_iterator
139 I = D->param_begin(), E = D->param_end(); I != E; ++I)
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000140 handleDeclarator(*I, D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000141
142 if (D->isThisDeclarationADefinition()) {
143 const Stmt *Body = D->getBody();
144 if (Body) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000145 IndexCtx.indexBody(Body, D, D);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000146 }
147 }
148 return true;
149 }
150
151 bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
152 IndexCtx.handleObjCProperty(D);
153 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
154 return true;
155 }
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000156
157 bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
158 ObjCPropertyDecl *PD = D->getPropertyDecl();
159 IndexCtx.handleSynthesizedObjCProperty(D);
160
161 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
162 return true;
163 assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
164
165 if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
166 if (!IvarD->getSynthesize())
167 IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), 0,
168 D->getDeclContext());
169 }
170
171 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
172 if (MD->isSynthesized())
173 IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation());
174 }
175 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
176 if (MD->isSynthesized())
177 IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation());
178 }
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000179 return true;
180 }
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000181
Argyrios Kyrtzidis68478b02011-12-07 05:52:06 +0000182 bool VisitNamespaceDecl(NamespaceDecl *D) {
183 IndexCtx.handleNamespace(D);
184 IndexCtx.indexDeclContext(D);
185 return true;
186 }
187
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000188 bool VisitClassTemplateDecl(ClassTemplateDecl *D) {
189 IndexCtx.handleClassTemplate(D);
190 if (D->isThisDeclarationADefinition())
191 IndexCtx.indexDeclContext(D->getTemplatedDecl());
192 return true;
193 }
194
195 bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
196 IndexCtx.handleFunctionTemplate(D);
197 FunctionDecl *FD = D->getTemplatedDecl();
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000198 handleDeclarator(FD, D);
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000199 if (FD->isThisDeclarationADefinition()) {
200 const Stmt *Body = FD->getBody();
201 if (Body) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000202 IndexCtx.indexBody(Body, D, FD);
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000203 }
204 }
205 return true;
206 }
207
208 bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
209 IndexCtx.handleTypeAliasTemplate(D);
210 IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000211 return true;
212 }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000213};
214
215} // anonymous namespace
216
217void IndexingContext::indexDecl(const Decl *D) {
218 bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
219 if (!Handled && isa<DeclContext>(D))
220 indexDeclContext(cast<DeclContext>(D));
221}
222
223void IndexingContext::indexDeclContext(const DeclContext *DC) {
224 for (DeclContext::decl_iterator
225 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
226 indexDecl(*I);
227 }
228}
229
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000230void IndexingContext::indexTopLevelDecl(Decl *D) {
231 if (isNotFromSourceFile(D->getLocation()))
232 return;
233
234 if (isa<ObjCMethodDecl>(D))
235 return; // Wait for the objc container.
236
237 indexDecl(D);
238}
239
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000240void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
Argyrios Kyrtzidis21ee5702011-11-15 06:20:16 +0000241 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
242 indexTopLevelDecl(*I);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000243}
244
245void IndexingContext::indexTUDeclsInObjCContainer() {
246 for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i)
247 indexDeclGroupRef(TUDeclsInObjCContainer[i]);
248 TUDeclsInObjCContainer.clear();
249}