blob: 5cf9f802634b20e57353e7f42da4c94b140bbd46 [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
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) {
32 IndexCtx.invokeStartedStatementBody(D, D);
33 IndexCtx.indexBody(Body, D);
34 IndexCtx.invokeEndedContainer(D);
35 }
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) {
71 ObjCClassDecl::ObjCClassRef *Ref = D->getForwardDecl();
72 if (Ref->getInterface()->getLocation() == Ref->getLocation()) {
73 IndexCtx.handleObjCInterface(Ref->getInterface());
74 } else {
75 IndexCtx.handleReference(Ref->getInterface(),
76 Ref->getLocation(),
77 0,
78 Ref->getInterface()->getDeclContext());
79 }
80 return true;
81 }
82
83 bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
84 ObjCForwardProtocolDecl::protocol_loc_iterator LI = D->protocol_loc_begin();
85 for (ObjCForwardProtocolDecl::protocol_iterator
86 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) {
87 SourceLocation Loc = *LI;
88 ObjCProtocolDecl *PD = *I;
89
90 if (PD->getLocation() == Loc) {
91 IndexCtx.handleObjCProtocol(PD);
92 } else {
93 IndexCtx.handleReference(PD, Loc, 0, PD->getDeclContext());
94 }
95 }
96 return true;
97 }
98
99 bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
100 // Only definitions are handled here.
101 if (D->isForwardDecl())
102 return true;
103
104 if (!D->isInitiallyForwardDecl())
105 IndexCtx.handleObjCInterface(D);
106
107 IndexCtx.indexTUDeclsInObjCContainer();
108 IndexCtx.invokeStartedObjCContainer(D);
109 IndexCtx.defineObjCInterface(D);
110 IndexCtx.indexDeclContext(D);
111 IndexCtx.invokeEndedContainer(D);
112 return true;
113 }
114
115 bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
116 // Only definitions are handled here.
117 if (D->isForwardDecl())
118 return true;
119
120 if (!D->isInitiallyForwardDecl())
121 IndexCtx.handleObjCProtocol(D);
122
123 IndexCtx.indexTUDeclsInObjCContainer();
124 IndexCtx.invokeStartedObjCContainer(D);
125 IndexCtx.indexDeclContext(D);
126 IndexCtx.invokeEndedContainer(D);
127 return true;
128 }
129
130 bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
131 ObjCInterfaceDecl *Class = D->getClassInterface();
132 if (Class->isImplicitInterfaceDecl())
133 IndexCtx.handleObjCInterface(Class);
134
135 IndexCtx.indexTUDeclsInObjCContainer();
136 IndexCtx.invokeStartedObjCContainer(D);
137 IndexCtx.indexDeclContext(D);
138 IndexCtx.invokeEndedContainer(D);
139 return true;
140 }
141
142 bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
143 if (!D->IsClassExtension())
144 IndexCtx.handleObjCCategory(D);
145
146 IndexCtx.indexTUDeclsInObjCContainer();
147 IndexCtx.invokeStartedObjCContainer(D);
148 IndexCtx.indexDeclContext(D);
149 IndexCtx.invokeEndedContainer(D);
150 return true;
151 }
152
153 bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
154 IndexCtx.indexTUDeclsInObjCContainer();
155 IndexCtx.invokeStartedObjCContainer(D);
156 IndexCtx.indexDeclContext(D);
157 IndexCtx.invokeEndedContainer(D);
158 return true;
159 }
160
161 bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
162 IndexCtx.handleObjCMethod(D);
163 IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
164 for (ObjCMethodDecl::param_iterator
165 I = D->param_begin(), E = D->param_end(); I != E; ++I)
166 IndexCtx.indexTypeSourceInfo((*I)->getTypeSourceInfo(), D);
167
168 if (D->isThisDeclarationADefinition()) {
169 const Stmt *Body = D->getBody();
170 if (Body) {
171 IndexCtx.invokeStartedStatementBody(D, D);
172 IndexCtx.indexBody(Body, D);
173 IndexCtx.invokeEndedContainer(D);
174 }
175 }
176 return true;
177 }
178
179 bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
180 IndexCtx.handleObjCProperty(D);
181 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
182 return true;
183 }
184};
185
186} // anonymous namespace
187
188void IndexingContext::indexDecl(const Decl *D) {
189 bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
190 if (!Handled && isa<DeclContext>(D))
191 indexDeclContext(cast<DeclContext>(D));
192}
193
194void IndexingContext::indexDeclContext(const DeclContext *DC) {
195 for (DeclContext::decl_iterator
196 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
197 indexDecl(*I);
198 }
199}
200
201void IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
202 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
203 Decl *D = *I;
204 if (isNotFromSourceFile(D->getLocation()))
205 return;
206
207 if (isa<ObjCMethodDecl>(D))
208 continue; // Wait for the objc container.
209
210 indexDecl(D);
211 }
212}
213
214void IndexingContext::indexTUDeclsInObjCContainer() {
215 for (unsigned i = 0, e = TUDeclsInObjCContainer.size(); i != e; ++i)
216 indexDeclGroupRef(TUDeclsInObjCContainer[i]);
217 TUDeclsInObjCContainer.clear();
218}