blob: 5087355a8ddb508febefe9e09477e1985648bf08 [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
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
26 bool VisitFunctionDecl(FunctionDecl *D) {
27 IndexCtx.handleFunction(D);
28 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
29 if (D->isThisDeclarationADefinition()) {
30 const Stmt *Body = D->getBody();
31 if (Body) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000032 IndexCtx.startContainer(D, /*isBody=*/true);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000033 IndexCtx.indexBody(Body, D);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000034 IndexCtx.endContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000035 }
36 }
37 return true;
38 }
39
40 bool VisitVarDecl(VarDecl *D) {
41 IndexCtx.handleVar(D);
42 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
43 return true;
44 }
45
46 bool VisitFieldDecl(FieldDecl *D) {
47 IndexCtx.handleField(D);
48 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
49 return true;
50 }
51
52 bool VisitEnumConstantDecl(EnumConstantDecl *D) {
53 IndexCtx.handleEnumerator(D);
54 return true;
55 }
56
57 bool VisitTypedefDecl(TypedefDecl *D) {
58 IndexCtx.handleTypedef(D);
59 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
60 return true;
61 }
62
63 bool VisitTagDecl(TagDecl *D) {
64 // Non-free standing tags are handled in indexTypeSourceInfo.
65 if (D->isFreeStanding())
66 IndexCtx.indexTagDecl(D);
67 return true;
68 }
69
70 bool VisitObjCClassDecl(ObjCClassDecl *D) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000071 IndexCtx.handleObjCClass(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000072 return true;
73 }
74
75 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
76 ObjCForwardProtocolDecl::protocol_loc_iterator LI = D->protocol_loc_begin();
77 for (ObjCForwardProtocolDecl::protocol_iterator
78 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) {
79 SourceLocation Loc = *LI;
80 ObjCProtocolDecl *PD = *I;
81
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000082 bool isRedeclaration = PD->getLocation() != Loc;
83 IndexCtx.handleObjCForwardProtocol(PD, Loc, isRedeclaration);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000084 }
85 return true;
86 }
87
88 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000089 // Forward decls are handled at VisitObjCClassDecl.
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000090 if (D->isForwardDecl())
91 return true;
92
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000093 IndexCtx.handleObjCInterface(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000094
95 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000096 IndexCtx.startContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000097 IndexCtx.defineObjCInterface(D);
98 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +000099 IndexCtx.endContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000100 return true;
101 }
102
103 bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000104 // Forward decls are handled at VisitObjCForwardProtocolDecl.
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000105 if (D->isForwardDecl())
106 return true;
107
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000108 IndexCtx.handleObjCProtocol(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000109
110 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000111 IndexCtx.startContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000112 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000113 IndexCtx.endContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000114 return true;
115 }
116
117 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000118 IndexCtx.handleObjCImplementation(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000119
120 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000121 IndexCtx.startContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000122 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000123 IndexCtx.endContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000124 return true;
125 }
126
127 bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000128 IndexCtx.handleObjCCategory(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000129
130 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000131 IndexCtx.startContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000132 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000133 IndexCtx.endContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000134 return true;
135 }
136
137 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000138 if (D->getCategoryDecl()->getLocation().isInvalid())
139 return true;
140
141 IndexCtx.handleObjCCategoryImpl(D);
142
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000143 IndexCtx.indexTUDeclsInObjCContainer();
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000144 IndexCtx.startContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000145 IndexCtx.indexDeclContext(D);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000146 IndexCtx.endContainer(D);
Argyrios Kyrtzidisdc199a32011-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)
155 IndexCtx.indexTypeSourceInfo((*I)->getTypeSourceInfo(), D);
156
157 if (D->isThisDeclarationADefinition()) {
158 const Stmt *Body = D->getBody();
159 if (Body) {
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000160 IndexCtx.startContainer(D, /*isBody=*/true);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000161 IndexCtx.indexBody(Body, D);
Argyrios Kyrtzidis7519c5e2011-11-11 00:23:36 +0000162 IndexCtx.endContainer(D);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000163 }
164 }
165 return true;
166 }
167
168 bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
169 IndexCtx.handleObjCProperty(D);
170 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
171 return true;
172 }
173};
174
175} // anonymous namespace
176
177void IndexingContext::indexDecl(const Decl *D) {
178 bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
179 if (!Handled && isa<DeclContext>(D))
180 indexDeclContext(cast<DeclContext>(D));
181}
182
183void IndexingContext::indexDeclContext(const DeclContext *DC) {
184 for (DeclContext::decl_iterator
185 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
186 indexDecl(*I);
187 }
188}
189
190void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
191 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
192 Decl *D = *I;
193 if (isNotFromSourceFile(D->getLocation()))
194 return;
195
196 if (isa<ObjCMethodDecl>(D))
197 continue; // Wait for the objc container.
198
199 indexDecl(D);
200 }
201}
202
203void IndexingContext::indexTUDeclsInObjCContainer() {
204 for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i)
205 indexDeclGroupRef(TUDeclsInObjCContainer[i]);
206 TUDeclsInObjCContainer.clear();
207}