blob: a0d281808e69152afebc3c7a9cc47e31ceda3fde [file] [log] [blame]
Chris Lattner1e03a562008-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 Lattner6c4ae5d2008-03-16 00:49:28 +000018//===----------------------------------------------------------------------===//
19// ObjC Decl Allocation/Deallocation Method Implementations
20//===----------------------------------------------------------------------===//
21
Chris Lattner0ed844b2008-04-04 06:12:32 +000022ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
23 SourceLocation beginLoc,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000024 SourceLocation endLoc,
25 Selector SelInfo, QualType T,
26 Decl *contextDecl,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000027 AttributeList *M, bool isInstance,
28 bool isVariadic,
Fariborz Jahanian46070342008-05-07 20:53:44 +000029 bool isSynthesized,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000030 ImplementationControl impControl) {
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000031 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000032 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
33 SelInfo, T, contextDecl,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000034 M, isInstance,
Fariborz Jahanian46070342008-05-07 20:53:44 +000035 isVariadic, isSynthesized, impControl);
Chris Lattner0e77ba02008-03-16 01:15:50 +000036}
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000037
Ted Kremenek8a779312008-06-06 16:45:15 +000038ObjCMethodDecl::~ObjCMethodDecl() {
39 delete [] ParamInfo;
40 //delete [] MethodAttrs; // FIXME: Also destroy the stored Expr*.
41}
42
43void ObjCMethodDecl::Destroy(ASTContext& C) {
44 if (Body) Body->Destroy(C);
45 if (SelfDecl) SelfDecl->Destroy(C);
46
47 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
48 if (*I) (*I)->Destroy(C);
49
50 Decl::Destroy(C);
51}
52
Chris Lattner0ed844b2008-04-04 06:12:32 +000053ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
54 SourceLocation atLoc,
Chris Lattner0e77ba02008-03-16 01:15:50 +000055 unsigned numRefProtos,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000056 IdentifierInfo *Id,
57 SourceLocation ClassLoc,
Chris Lattner0e77ba02008-03-16 01:15:50 +000058 bool ForwardDecl, bool isInternal){
59 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000060 return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000061 Id, ClassLoc, ForwardDecl,
Chris Lattner0e77ba02008-03-16 01:15:50 +000062 isInternal);
63}
64
Ted Kremenek8a779312008-06-06 16:45:15 +000065ObjCInterfaceDecl::~ObjCInterfaceDecl() {
66 delete [] Ivars;
67 delete [] InstanceMethods;
68 delete [] ClassMethods;
69 delete [] PropertyDecl;
70 // FIXME: CategoryList?
71}
72
73void ObjCInterfaceDecl::Destroy(ASTContext& C) {
74 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
75 if (*I) (*I)->Destroy(C);
76
77 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
78 if (*I) (*I)->Destroy(C);
79
80 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
81 if (*I) (*I)->Destroy(C);
Ted Kremenek1a726d72008-06-06 17:21:42 +000082
83 // FIXME: Because there is no clear ownership
84 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
85 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
86
Ted Kremenek8a779312008-06-06 16:45:15 +000087 Decl::Destroy(C);
88}
89
90
Chris Lattnerb048c982008-04-06 04:47:34 +000091ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Chris Lattner0e77ba02008-03-16 01:15:50 +000092 IdentifierInfo *Id, QualType T) {
93 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Chris Lattnerb048c982008-04-06 04:47:34 +000094 return new (Mem) ObjCIvarDecl(L, Id, T);
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000095}
96
Chris Lattner0ed844b2008-04-04 06:12:32 +000097ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
98 SourceLocation L,
Chris Lattnercca59d72008-03-16 01:23:04 +000099 unsigned numRefProtos,
Chris Lattnerc8581052008-03-16 20:19:15 +0000100 IdentifierInfo *Id) {
Chris Lattnercca59d72008-03-16 01:23:04 +0000101 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattnerc8581052008-03-16 20:19:15 +0000102 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattnercca59d72008-03-16 01:23:04 +0000103}
104
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000105ObjCProtocolDecl::~ObjCProtocolDecl() {
106 delete [] ReferencedProtocols;
107 delete [] InstanceMethods;
108 delete [] ClassMethods;
109 delete [] PropertyDecl;
110}
111
112void ObjCProtocolDecl::Destroy(ASTContext& C) {
113
114 // Referenced Protocols are not owned, so don't Destroy them.
115
116 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
117 if (*I) (*I)->Destroy(C);
118
119 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
120 if (*I) (*I)->Destroy(C);
121
122 // FIXME: Because there is no clear ownership
123 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
124 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
125
126 Decl::Destroy(C);
127}
128
129
Chris Lattner0ed844b2008-04-04 06:12:32 +0000130ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
131 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000132 ObjCInterfaceDecl **Elts, unsigned nElts) {
133 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
134 return new (Mem) ObjCClassDecl(L, Elts, nElts);
135}
136
137ObjCForwardProtocolDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000138ObjCForwardProtocolDecl::Create(ASTContext &C,
139 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000140 ObjCProtocolDecl **Elts, unsigned NumElts) {
141 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
142 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
143}
144
Chris Lattner0ed844b2008-04-04 06:12:32 +0000145ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
146 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000147 IdentifierInfo *Id) {
148 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner68c82cf2008-03-16 20:47:45 +0000149 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattner61f9d412008-03-16 20:34:23 +0000150}
151
Chris Lattner75c9cae2008-03-16 20:53:07 +0000152ObjCCategoryImplDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000153ObjCCategoryImplDecl::Create(ASTContext &C,
154 SourceLocation L,IdentifierInfo *Id,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000155 ObjCInterfaceDecl *ClassInterface) {
156 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
157 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
158}
159
160ObjCImplementationDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000161ObjCImplementationDecl::Create(ASTContext &C,
162 SourceLocation L,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000163 IdentifierInfo *Id,
164 ObjCInterfaceDecl *ClassInterface,
165 ObjCInterfaceDecl *SuperDecl) {
166 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
167 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
168}
Chris Lattner1e03a562008-03-16 00:19:01 +0000169
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000170ObjCCompatibleAliasDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000171ObjCCompatibleAliasDecl::Create(ASTContext &C,
172 SourceLocation L,
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000173 IdentifierInfo *Id,
174 ObjCInterfaceDecl* AliasedClass) {
175 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
176 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
177}
178
Chris Lattner0ed844b2008-04-04 06:12:32 +0000179ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniandae1a1a2008-04-11 23:40:25 +0000180 SourceLocation L,
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000181 IdentifierInfo *Id,
Fariborz Jahanian46b55e52008-05-05 18:51:55 +0000182 QualType T,
183 PropertyControl propControl) {
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000184 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000185 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000186}
187
Chris Lattner1e03a562008-03-16 00:19:01 +0000188//===----------------------------------------------------------------------===//
189// Objective-C Decl Implementation
190//===----------------------------------------------------------------------===//
191
192void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
193 unsigned NumParams) {
194 assert(ParamInfo == 0 && "Already has param info!");
195
196 // Zero params -> null pointer.
197 if (NumParams) {
198 ParamInfo = new ParmVarDecl*[NumParams];
199 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
200 NumMethodParams = NumParams;
201 }
202}
203
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000204/// FindPropertyDeclaration - Finds declaration of the property given its name
205/// in 'PropertyId' and returns it. It returns 0, if not found.
206///
207ObjCPropertyDecl *
208 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
209 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
210 E = classprop_end(); I != E; ++I) {
211 ObjCPropertyDecl *property = *I;
212 if (property->getIdentifier() == PropertyId)
213 return property;
214 }
Steve Naroff6c930f22008-06-04 04:46:04 +0000215 // Look through categories.
216 for (ObjCCategoryDecl *Category = getCategoryList();
217 Category; Category = Category->getNextClassCategory()) {
218 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
219 if (property)
220 return property;
221 }
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000222 // Look through protocols.
223 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
224 E = protocol_end(); I != E; ++I) {
225 ObjCProtocolDecl *Protocol = *I;
226 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
227 if (property)
228 return property;
229 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000230 if (getSuperClass())
231 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000232 return 0;
233}
234
235/// FindCategoryDeclaration - Finds category declaration in the list of
236/// categories for this class and returns it. Name of the category is passed
237/// in 'CategoryId'. If category not found, return 0;
238///
239ObjCCategoryDecl *
240 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
241 for (ObjCCategoryDecl *Category = getCategoryList();
242 Category; Category = Category->getNextClassCategory())
243 if (Category->getIdentifier() == CategoryId)
244 return Category;
245 return 0;
246}
247
248/// FindIvarDeclaration - Find an Ivar declaration in this class given its
249/// name in 'IvarId'. On failure to find, return 0;
250///
251ObjCIvarDecl *
252 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
253 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
254 IVE = ivar_end(); IVI != IVE; ++IVI) {
255 ObjCIvarDecl* Ivar = (*IVI);
256 if (Ivar->getIdentifier() == IvarId)
257 return Ivar;
258 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000259 if (getSuperClass())
260 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000261 return 0;
262}
263
Chris Lattner1e03a562008-03-16 00:19:01 +0000264/// ObjCAddInstanceVariablesToClass - Inserts instance variables
265/// into ObjCInterfaceDecl's fields.
266///
267void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
268 unsigned numIvars,
269 SourceLocation RBrac) {
270 NumIvars = numIvars;
271 if (numIvars) {
272 Ivars = new ObjCIvarDecl*[numIvars];
273 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
274 }
275 setLocEnd(RBrac);
276}
277
278/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
279/// Variables (Ivars) relative to what declared in @implementation;s class.
280/// Ivars into ObjCImplementationDecl's fields.
281///
282void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
283 ObjCIvarDecl **ivars, unsigned numIvars) {
284 NumIvars = numIvars;
285 if (numIvars) {
286 Ivars = new ObjCIvarDecl*[numIvars];
287 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
288 }
289}
290
291/// addMethods - Insert instance and methods declarations into
292/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
293///
294void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
295 unsigned numInsMembers,
296 ObjCMethodDecl **clsMethods,
297 unsigned numClsMembers,
298 SourceLocation endLoc) {
299 NumInstanceMethods = numInsMembers;
300 if (numInsMembers) {
301 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
302 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
303 }
304 NumClassMethods = numClsMembers;
305 if (numClsMembers) {
306 ClassMethods = new ObjCMethodDecl*[numClsMembers];
307 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
308 }
309 AtEndLoc = endLoc;
310}
311
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000312/// addProperties - Insert property declaration AST nodes into
313/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattner55d13b42008-03-16 21:23:50 +0000314///
315void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
316 unsigned NumProperties) {
317 if (NumProperties == 0) return;
318
319 NumPropertyDecl = NumProperties;
320 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
321 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
322}
323
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000324/// mergeProperties - Adds properties to the end of list of current properties
325/// for this class.
326
327void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
328 unsigned NumNewProperties) {
329 if (NumNewProperties == 0) return;
330
331 if (PropertyDecl) {
332 ObjCPropertyDecl **newPropertyDecl =
333 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
334 ObjCPropertyDecl **buf = newPropertyDecl;
335 // put back original properties in buffer.
336 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
337 // Add new properties to this buffer.
338 memcpy(buf+NumPropertyDecl, Properties,
339 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000340 delete[] PropertyDecl;
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000341 PropertyDecl = newPropertyDecl;
342 NumPropertyDecl += NumNewProperties;
343 }
344 else {
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000345 addProperties(Properties, NumNewProperties);
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000346 }
347}
348
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000349/// addPropertyMethods - Goes through list of properties declared in this class
350/// and builds setter/getter method declartions depending on the setter/getter
351/// attributes of the property.
352///
353void ObjCInterfaceDecl::addPropertyMethods(
354 ASTContext &Context,
355 ObjCPropertyDecl *property,
356 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
357 // Find the default getter and if one not found, add one.
358 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
359 if (GetterDecl) {
360 // An instance method with same name as property getter name found.
361 property->setGetterMethodDecl(GetterDecl);
362 }
363 else {
364 // No instance method of same name as property getter name was found.
365 // Declare a getter method and add it to the list of methods
366 // for this class.
367 QualType resultDeclType = property->getType();
368 ObjCMethodDecl* ObjCMethod =
369 ObjCMethodDecl::Create(Context, property->getLocation(),
370 property->getLocation(),
371 property->getGetterName(), resultDeclType,
372 this, 0,
Fariborz Jahanian46070342008-05-07 20:53:44 +0000373 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000374 property->setGetterMethodDecl(ObjCMethod);
375 insMethods.push_back(ObjCMethod);
376 }
377}
378
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000379/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian3dd4ba42008-04-17 18:25:18 +0000380/// ObjCProtocolDecl's PropertyDecl field.
381///
382void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
383 unsigned NumProperties) {
384 if (NumProperties == 0) return;
385
386 NumPropertyDecl = NumProperties;
387 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
388 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
389}
390
391/// addProperties - Insert property declaration AST nodes into
Fariborz Jahaniand9a3c332008-04-16 21:11:25 +0000392/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000393///
394void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
395 unsigned NumProperties) {
396 if (NumProperties == 0) return;
397
398 NumPropertyDecl = NumProperties;
399 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
400 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
401}
402
Chris Lattner55d13b42008-03-16 21:23:50 +0000403/// addMethods - Insert instance and methods declarations into
Chris Lattner1e03a562008-03-16 00:19:01 +0000404/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
405///
406void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
407 unsigned numInsMembers,
408 ObjCMethodDecl **clsMethods,
409 unsigned numClsMembers,
410 SourceLocation endLoc) {
411 NumInstanceMethods = numInsMembers;
412 if (numInsMembers) {
413 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
414 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
415 }
416 NumClassMethods = numClsMembers;
417 if (numClsMembers) {
418 ClassMethods = new ObjCMethodDecl*[numClsMembers];
419 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
420 }
421 AtEndLoc = endLoc;
422}
423
Chris Lattner68c82cf2008-03-16 20:47:45 +0000424void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
425 unsigned NumRPs) {
426 assert(NumReferencedProtocols == 0 && "Protocol list already set");
427 if (NumRPs == 0) return;
428
429 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
430 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
431 NumReferencedProtocols = NumRPs;
432}
433
434
Chris Lattner1e03a562008-03-16 00:19:01 +0000435/// addMethods - Insert instance and methods declarations into
436/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
437///
438void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
439 unsigned numInsMembers,
440 ObjCMethodDecl **clsMethods,
441 unsigned numClsMembers,
442 SourceLocation endLoc) {
443 NumInstanceMethods = numInsMembers;
444 if (numInsMembers) {
445 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
446 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
447 }
448 NumClassMethods = numClsMembers;
449 if (numClsMembers) {
450 ClassMethods = new ObjCMethodDecl*[numClsMembers];
451 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
452 }
453 AtEndLoc = endLoc;
454}
455
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000456/// FindPropertyDeclaration - Finds declaration of the property given its name
457/// in 'PropertyId' and returns it. It returns 0, if not found.
458///
459ObjCPropertyDecl *
460ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
461 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
462 E = classprop_end(); I != E; ++I) {
463 ObjCPropertyDecl *property = *I;
464 if (property->getIdentifier() == PropertyId)
465 return property;
466 }
467 return 0;
468}
469
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000470/// FindPropertyDeclaration - Finds declaration of the property given its name
471/// in 'PropertyId' and returns it. It returns 0, if not found.
472///
473ObjCPropertyDecl *
474ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
475 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
476 E = classprop_end(); I != E; ++I) {
477 ObjCPropertyDecl *property = *I;
478 if (property->getIdentifier() == PropertyId)
479 return property;
480 }
481 return 0;
482}
483
Chris Lattner1e03a562008-03-16 00:19:01 +0000484ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
485 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
486 ObjCInterfaceDecl* ClassDecl = this;
487 while (ClassDecl != NULL) {
488 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
489 I != E; ++I) {
490 if ((*I)->getIdentifier() == ID) {
491 clsDeclared = ClassDecl;
492 return *I;
493 }
494 }
495 ClassDecl = ClassDecl->getSuperClass();
496 }
497 return NULL;
498}
499
500/// lookupInstanceMethod - This method returns an instance method by looking in
501/// the class, its categories, and its super classes (using a linear search).
502ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
503 ObjCInterfaceDecl* ClassDecl = this;
504 ObjCMethodDecl *MethodDecl = 0;
505
506 while (ClassDecl != NULL) {
507 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
508 return MethodDecl;
509
510 // Didn't find one yet - look through protocols.
511 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
512 int numProtocols = ClassDecl->getNumIntfRefProtocols();
513 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
514 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
515 return MethodDecl;
516 }
517 // Didn't find one yet - now look through categories.
518 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
519 while (CatDecl) {
520 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
521 return MethodDecl;
522 CatDecl = CatDecl->getNextClassCategory();
523 }
524 ClassDecl = ClassDecl->getSuperClass();
525 }
526 return NULL;
527}
528
529// lookupClassMethod - This method returns a class method by looking in the
530// class, its categories, and its super classes (using a linear search).
531ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
532 ObjCInterfaceDecl* ClassDecl = this;
533 ObjCMethodDecl *MethodDecl = 0;
534
535 while (ClassDecl != NULL) {
536 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
537 return MethodDecl;
538
539 // Didn't find one yet - look through protocols.
540 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
541 int numProtocols = ClassDecl->getNumIntfRefProtocols();
542 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
543 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
544 return MethodDecl;
545 }
546 // Didn't find one yet - now look through categories.
547 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
548 while (CatDecl) {
549 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
550 return MethodDecl;
551 CatDecl = CatDecl->getNextClassCategory();
552 }
553 ClassDecl = ClassDecl->getSuperClass();
554 }
555 return NULL;
556}
557
558/// lookupInstanceMethod - This method returns an instance method by looking in
559/// the class implementation. Unlike interfaces, we don't look outside the
560/// implementation.
561ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
562 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
563 if ((*I)->getSelector() == Sel)
564 return *I;
565 return NULL;
566}
567
568/// lookupClassMethod - This method returns a class method by looking in
569/// the class implementation. Unlike interfaces, we don't look outside the
570/// implementation.
571ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
572 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
573 I != E; ++I)
574 if ((*I)->getSelector() == Sel)
575 return *I;
576 return NULL;
577}
578
579// lookupInstanceMethod - This method returns an instance method by looking in
580// the class implementation. Unlike interfaces, we don't look outside the
581// implementation.
582ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
583 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
584 if ((*I)->getSelector() == Sel)
585 return *I;
586 return NULL;
587}
588
589// lookupClassMethod - This method returns an instance method by looking in
590// the class implementation. Unlike interfaces, we don't look outside the
591// implementation.
592ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
593 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
594 I != E; ++I)
595 if ((*I)->getSelector() == Sel)
596 return *I;
597 return NULL;
598}
599
600// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
601// it inherited.
602ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
603 ObjCMethodDecl *MethodDecl = NULL;
604
605 if ((MethodDecl = getInstanceMethod(Sel)))
606 return MethodDecl;
607
608 if (getNumReferencedProtocols() > 0) {
609 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
610
611 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
612 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
613 return MethodDecl;
614 }
615 }
616 return NULL;
617}
618
619// lookupInstanceMethod - Lookup a class method in the protocol and protocols
620// it inherited.
621ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
622 ObjCMethodDecl *MethodDecl = NULL;
623
624 if ((MethodDecl = getClassMethod(Sel)))
625 return MethodDecl;
626
627 if (getNumReferencedProtocols() > 0) {
628 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
629
630 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
631 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
632 return MethodDecl;
633 }
634 }
635 return NULL;
636}
637
638/// getSynthesizedMethodSize - Compute size of synthesized method name
639/// as done be the rewrite.
640///
641unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
642 // syntesized method name is a concatenation of -/+[class-name selector]
643 // Get length of this name.
644 unsigned length = 3; // _I_ or _C_
645 length += strlen(getClassInterface()->getName()) +1; // extra for _
646 NamedDecl *MethodContext = getMethodContext();
647 if (ObjCCategoryImplDecl *CID =
648 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
649 length += strlen(CID->getName()) +1;
650 length += getSelector().getName().size(); // selector name
651 return length;
652}
653
Chris Lattner56196882008-04-06 05:25:03 +0000654ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner1e03a562008-03-16 00:19:01 +0000655 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
656 return ID;
657 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
658 return CD->getClassInterface();
659 if (ObjCImplementationDecl *IMD =
Chris Lattner56196882008-04-06 05:25:03 +0000660 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000661 return IMD->getClassInterface();
Chris Lattner56196882008-04-06 05:25:03 +0000662 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000663 return CID->getClassInterface();
664 assert(false && "unknown method context");
665 return 0;
666}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000667
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000668ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
669 SourceLocation atLoc,
670 SourceLocation L,
671 ObjCPropertyDecl *property,
672 PropertyImplKind kind,
673 ObjCIvarDecl *ivar) {
674 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
675 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
676}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000677
Chris Lattner0ed844b2008-04-04 06:12:32 +0000678