blob: 4f1671ef0738fdb08ac89bec146deeefc1e8d729 [file] [log] [blame]
Chris Lattner10318b82008-03-16 00:19:01 +00001//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
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// This file implements the Objective-C related Decl classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclObjC.h"
15#include "clang/AST/ASTContext.h"
16using namespace clang;
17
Chris Lattner114add62008-03-16 00:49:28 +000018//===----------------------------------------------------------------------===//
19// ObjC Decl Allocation/Deallocation Method Implementations
20//===----------------------------------------------------------------------===//
21
22ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc,
23 SourceLocation endLoc,
24 Selector SelInfo, QualType T,
25 Decl *contextDecl,
Chris Lattner114add62008-03-16 00:49:28 +000026 AttributeList *M, bool isInstance,
27 bool isVariadic,
Chris Lattnerf7355832008-03-16 00:58:16 +000028 ImplementationControl impControl) {
Chris Lattner114add62008-03-16 00:49:28 +000029 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
30 return new (Mem) ObjCMethodDecl(beginLoc, endLoc, SelInfo, T, contextDecl,
Chris Lattnerf7355832008-03-16 00:58:16 +000031 M, isInstance,
32 isVariadic, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000033}
Chris Lattner114add62008-03-16 00:49:28 +000034
Chris Lattner0db541b2008-03-16 01:15:50 +000035ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,SourceLocation atLoc,
36 unsigned numRefProtos,
37 IdentifierInfo *Id,
38 bool ForwardDecl, bool isInternal){
39 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
40 return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos, Id, ForwardDecl,
41 isInternal);
42}
43
44ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
45 IdentifierInfo *Id, QualType T) {
46 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
47 return new (Mem) ObjCIvarDecl(L, Id, T);
Chris Lattner114add62008-03-16 00:49:28 +000048}
49
Chris Lattner180f7e22008-03-16 01:23:04 +000050ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, SourceLocation L,
51 unsigned numRefProtos,
Chris Lattner7afba9c2008-03-16 20:19:15 +000052 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +000053 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner7afba9c2008-03-16 20:19:15 +000054 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +000055}
56
Chris Lattnere29dc832008-03-16 20:34:23 +000057ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, SourceLocation L,
58 ObjCInterfaceDecl **Elts, unsigned nElts) {
59 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
60 return new (Mem) ObjCClassDecl(L, Elts, nElts);
61}
62
63ObjCForwardProtocolDecl *
64ObjCForwardProtocolDecl::Create(ASTContext &C, SourceLocation L,
65 ObjCProtocolDecl **Elts, unsigned NumElts) {
66 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
67 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
68}
69
70ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +000071 IdentifierInfo *Id) {
72 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +000073 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +000074}
75
Chris Lattner1b6de332008-03-16 20:53:07 +000076ObjCCategoryImplDecl *
77ObjCCategoryImplDecl::Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id,
78 ObjCInterfaceDecl *ClassInterface) {
79 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
80 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
81}
82
83ObjCImplementationDecl *
84ObjCImplementationDecl::Create(ASTContext &C, SourceLocation L,
85 IdentifierInfo *Id,
86 ObjCInterfaceDecl *ClassInterface,
87 ObjCInterfaceDecl *SuperDecl) {
88 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
89 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
90}
Chris Lattner10318b82008-03-16 00:19:01 +000091
92//===----------------------------------------------------------------------===//
93// Objective-C Decl Implementation
94//===----------------------------------------------------------------------===//
95
96void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
97 unsigned NumParams) {
98 assert(ParamInfo == 0 && "Already has param info!");
99
100 // Zero params -> null pointer.
101 if (NumParams) {
102 ParamInfo = new ParmVarDecl*[NumParams];
103 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
104 NumMethodParams = NumParams;
105 }
106}
107
108ObjCMethodDecl::~ObjCMethodDecl() {
109 delete[] ParamInfo;
110}
111
112/// ObjCAddInstanceVariablesToClass - Inserts instance variables
113/// into ObjCInterfaceDecl's fields.
114///
115void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
116 unsigned numIvars,
117 SourceLocation RBrac) {
118 NumIvars = numIvars;
119 if (numIvars) {
120 Ivars = new ObjCIvarDecl*[numIvars];
121 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
122 }
123 setLocEnd(RBrac);
124}
125
126/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
127/// Variables (Ivars) relative to what declared in @implementation;s class.
128/// Ivars into ObjCImplementationDecl's fields.
129///
130void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
131 ObjCIvarDecl **ivars, unsigned numIvars) {
132 NumIvars = numIvars;
133 if (numIvars) {
134 Ivars = new ObjCIvarDecl*[numIvars];
135 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
136 }
137}
138
139/// addMethods - Insert instance and methods declarations into
140/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
141///
142void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
143 unsigned numInsMembers,
144 ObjCMethodDecl **clsMethods,
145 unsigned numClsMembers,
146 SourceLocation endLoc) {
147 NumInstanceMethods = numInsMembers;
148 if (numInsMembers) {
149 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
150 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
151 }
152 NumClassMethods = numClsMembers;
153 if (numClsMembers) {
154 ClassMethods = new ObjCMethodDecl*[numClsMembers];
155 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
156 }
157 AtEndLoc = endLoc;
158}
159
160/// addMethods - Insert instance and methods declarations into
161/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
162///
163void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
164 unsigned numInsMembers,
165 ObjCMethodDecl **clsMethods,
166 unsigned numClsMembers,
167 SourceLocation endLoc) {
168 NumInstanceMethods = numInsMembers;
169 if (numInsMembers) {
170 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
171 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
172 }
173 NumClassMethods = numClsMembers;
174 if (numClsMembers) {
175 ClassMethods = new ObjCMethodDecl*[numClsMembers];
176 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
177 }
178 AtEndLoc = endLoc;
179}
180
Chris Lattner321b5d12008-03-16 20:47:45 +0000181void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
182 unsigned NumRPs) {
183 assert(NumReferencedProtocols == 0 && "Protocol list already set");
184 if (NumRPs == 0) return;
185
186 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
187 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
188 NumReferencedProtocols = NumRPs;
189}
190
191
Chris Lattner10318b82008-03-16 00:19:01 +0000192/// addMethods - Insert instance and methods declarations into
193/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
194///
195void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
196 unsigned numInsMembers,
197 ObjCMethodDecl **clsMethods,
198 unsigned numClsMembers,
199 SourceLocation endLoc) {
200 NumInstanceMethods = numInsMembers;
201 if (numInsMembers) {
202 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
203 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
204 }
205 NumClassMethods = numClsMembers;
206 if (numClsMembers) {
207 ClassMethods = new ObjCMethodDecl*[numClsMembers];
208 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
209 }
210 AtEndLoc = endLoc;
211}
212
213ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
214 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
215 ObjCInterfaceDecl* ClassDecl = this;
216 while (ClassDecl != NULL) {
217 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
218 I != E; ++I) {
219 if ((*I)->getIdentifier() == ID) {
220 clsDeclared = ClassDecl;
221 return *I;
222 }
223 }
224 ClassDecl = ClassDecl->getSuperClass();
225 }
226 return NULL;
227}
228
229/// lookupInstanceMethod - This method returns an instance method by looking in
230/// the class, its categories, and its super classes (using a linear search).
231ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
232 ObjCInterfaceDecl* ClassDecl = this;
233 ObjCMethodDecl *MethodDecl = 0;
234
235 while (ClassDecl != NULL) {
236 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
237 return MethodDecl;
238
239 // Didn't find one yet - look through protocols.
240 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
241 int numProtocols = ClassDecl->getNumIntfRefProtocols();
242 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
243 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
244 return MethodDecl;
245 }
246 // Didn't find one yet - now look through categories.
247 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
248 while (CatDecl) {
249 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
250 return MethodDecl;
251 CatDecl = CatDecl->getNextClassCategory();
252 }
253 ClassDecl = ClassDecl->getSuperClass();
254 }
255 return NULL;
256}
257
258// lookupClassMethod - This method returns a class method by looking in the
259// class, its categories, and its super classes (using a linear search).
260ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
261 ObjCInterfaceDecl* ClassDecl = this;
262 ObjCMethodDecl *MethodDecl = 0;
263
264 while (ClassDecl != NULL) {
265 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
266 return MethodDecl;
267
268 // Didn't find one yet - look through protocols.
269 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
270 int numProtocols = ClassDecl->getNumIntfRefProtocols();
271 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
272 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
273 return MethodDecl;
274 }
275 // Didn't find one yet - now look through categories.
276 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
277 while (CatDecl) {
278 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
279 return MethodDecl;
280 CatDecl = CatDecl->getNextClassCategory();
281 }
282 ClassDecl = ClassDecl->getSuperClass();
283 }
284 return NULL;
285}
286
287/// lookupInstanceMethod - This method returns an instance method by looking in
288/// the class implementation. Unlike interfaces, we don't look outside the
289/// implementation.
290ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
291 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
292 if ((*I)->getSelector() == Sel)
293 return *I;
294 return NULL;
295}
296
297/// lookupClassMethod - This method returns a class method by looking in
298/// the class implementation. Unlike interfaces, we don't look outside the
299/// implementation.
300ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
301 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
302 I != E; ++I)
303 if ((*I)->getSelector() == Sel)
304 return *I;
305 return NULL;
306}
307
308// lookupInstanceMethod - This method returns an instance method by looking in
309// the class implementation. Unlike interfaces, we don't look outside the
310// implementation.
311ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
312 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
313 if ((*I)->getSelector() == Sel)
314 return *I;
315 return NULL;
316}
317
318// lookupClassMethod - This method returns an instance method by looking in
319// the class implementation. Unlike interfaces, we don't look outside the
320// implementation.
321ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
322 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
323 I != E; ++I)
324 if ((*I)->getSelector() == Sel)
325 return *I;
326 return NULL;
327}
328
329// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
330// it inherited.
331ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
332 ObjCMethodDecl *MethodDecl = NULL;
333
334 if ((MethodDecl = getInstanceMethod(Sel)))
335 return MethodDecl;
336
337 if (getNumReferencedProtocols() > 0) {
338 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
339
340 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
341 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
342 return MethodDecl;
343 }
344 }
345 return NULL;
346}
347
348// lookupInstanceMethod - Lookup a class method in the protocol and protocols
349// it inherited.
350ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
351 ObjCMethodDecl *MethodDecl = NULL;
352
353 if ((MethodDecl = getClassMethod(Sel)))
354 return MethodDecl;
355
356 if (getNumReferencedProtocols() > 0) {
357 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
358
359 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
360 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
361 return MethodDecl;
362 }
363 }
364 return NULL;
365}
366
367/// getSynthesizedMethodSize - Compute size of synthesized method name
368/// as done be the rewrite.
369///
370unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
371 // syntesized method name is a concatenation of -/+[class-name selector]
372 // Get length of this name.
373 unsigned length = 3; // _I_ or _C_
374 length += strlen(getClassInterface()->getName()) +1; // extra for _
375 NamedDecl *MethodContext = getMethodContext();
376 if (ObjCCategoryImplDecl *CID =
377 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
378 length += strlen(CID->getName()) +1;
379 length += getSelector().getName().size(); // selector name
380 return length;
381}
382
383ObjCInterfaceDecl *const ObjCMethodDecl::getClassInterface() const {
384 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
385 return ID;
386 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
387 return CD->getClassInterface();
388 if (ObjCImplementationDecl *IMD =
389 dyn_cast<ObjCImplementationDecl>(MethodContext))
390 return IMD->getClassInterface();
391 if (ObjCCategoryImplDecl *CID =
392 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
393 return CID->getClassInterface();
394 assert(false && "unknown method context");
395 return 0;
396}