blob: 9ba6e86cf097705d761415309873a45fad6b6211 [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
Chris Lattnereee57c02008-04-04 06:12:32 +000022ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
23 SourceLocation beginLoc,
Chris Lattner114add62008-03-16 00:49:28 +000024 SourceLocation endLoc,
25 Selector SelInfo, QualType T,
26 Decl *contextDecl,
Chris Lattner114add62008-03-16 00:49:28 +000027 AttributeList *M, bool isInstance,
28 bool isVariadic,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000029 bool isSynthesized,
Chris Lattnerf7355832008-03-16 00:58:16 +000030 ImplementationControl impControl) {
Chris Lattner114add62008-03-16 00:49:28 +000031 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000032 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
33 SelInfo, T, contextDecl,
Chris Lattnerf7355832008-03-16 00:58:16 +000034 M, isInstance,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000035 isVariadic, isSynthesized, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000036}
Chris Lattner114add62008-03-16 00:49:28 +000037
Ted Kremenek8c945b12008-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 Lattnereee57c02008-04-04 06:12:32 +000053ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
54 SourceLocation atLoc,
Steve Naroff7c371742008-04-11 19:35:35 +000055 IdentifierInfo *Id,
56 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000057 bool ForwardDecl, bool isInternal){
58 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattner5cece462008-07-21 07:06:49 +000059 return new (Mem) ObjCInterfaceDecl(atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000060 isInternal);
61}
62
Ted Kremenek8c945b12008-06-06 16:45:15 +000063ObjCInterfaceDecl::~ObjCInterfaceDecl() {
64 delete [] Ivars;
65 delete [] InstanceMethods;
66 delete [] ClassMethods;
67 delete [] PropertyDecl;
68 // FIXME: CategoryList?
69}
70
71void ObjCInterfaceDecl::Destroy(ASTContext& C) {
72 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
73 if (*I) (*I)->Destroy(C);
74
75 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
76 if (*I) (*I)->Destroy(C);
77
78 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
79 if (*I) (*I)->Destroy(C);
Ted Kremenek22db1602008-06-06 17:21:42 +000080
81 // FIXME: Because there is no clear ownership
82 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
83 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
84
Ted Kremenek8c945b12008-06-06 16:45:15 +000085 Decl::Destroy(C);
86}
87
88
Chris Lattnerf3874bc2008-04-06 04:47:34 +000089ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenek173dd312008-07-23 18:04:17 +000090 IdentifierInfo *Id, QualType T,
91 AccessControl ac, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000092 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenek173dd312008-07-23 18:04:17 +000093 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000094}
95
Chris Lattnereee57c02008-04-04 06:12:32 +000096ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
97 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +000098 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +000099 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner0be08822008-07-21 21:32:27 +0000100 return new (Mem) ObjCProtocolDecl(L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000101}
102
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000103ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000104 delete [] InstanceMethods;
105 delete [] ClassMethods;
106 delete [] PropertyDecl;
107}
108
109void ObjCProtocolDecl::Destroy(ASTContext& C) {
110
111 // Referenced Protocols are not owned, so don't Destroy them.
112
113 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
114 if (*I) (*I)->Destroy(C);
115
116 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
117 if (*I) (*I)->Destroy(C);
118
119 // FIXME: Because there is no clear ownership
120 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
121 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
122
123 Decl::Destroy(C);
124}
125
126
Chris Lattnereee57c02008-04-04 06:12:32 +0000127ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
128 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000129 ObjCInterfaceDecl **Elts, unsigned nElts) {
130 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
131 return new (Mem) ObjCClassDecl(L, Elts, nElts);
132}
133
Ted Kremenekff291622008-06-06 20:11:53 +0000134ObjCClassDecl::~ObjCClassDecl() {
135 delete [] ForwardDecls;
136}
137
138void ObjCClassDecl::Destroy(ASTContext& C) {
139
140 // FIXME: There is no clear ownership policy now for referenced
141 // ObjCInterfaceDecls. Some of them can be forward declarations that
142 // are never later defined (in which case the ObjCClassDecl owns them)
143 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
144 // we should have separate objects for forward declarations and definitions,
145 // obviating this problem. Because of this situation, referenced
146 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
147
148 Decl::Destroy(C);
149}
150
Chris Lattnere29dc832008-03-16 20:34:23 +0000151ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000152ObjCForwardProtocolDecl::Create(ASTContext &C,
153 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000154 ObjCProtocolDecl **Elts, unsigned NumElts) {
155 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
156 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
157}
158
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000159ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
160 delete [] ReferencedProtocols;
161}
162
Chris Lattnereee57c02008-04-04 06:12:32 +0000163ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
164 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000165 IdentifierInfo *Id) {
166 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +0000167 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000168}
169
Chris Lattner1b6de332008-03-16 20:53:07 +0000170ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000171ObjCCategoryImplDecl::Create(ASTContext &C,
172 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000173 ObjCInterfaceDecl *ClassInterface) {
174 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
175 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
176}
177
178ObjCImplementationDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000179ObjCImplementationDecl::Create(ASTContext &C,
180 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000181 IdentifierInfo *Id,
182 ObjCInterfaceDecl *ClassInterface,
183 ObjCInterfaceDecl *SuperDecl) {
184 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
185 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
186}
Chris Lattner10318b82008-03-16 00:19:01 +0000187
Chris Lattner2d1c4312008-03-16 21:17:37 +0000188ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000189ObjCCompatibleAliasDecl::Create(ASTContext &C,
190 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000191 IdentifierInfo *Id,
192 ObjCInterfaceDecl* AliasedClass) {
193 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
194 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
195}
196
Chris Lattnereee57c02008-04-04 06:12:32 +0000197ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000198 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000199 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000200 QualType T,
201 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000202 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000203 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000204}
205
Chris Lattner10318b82008-03-16 00:19:01 +0000206//===----------------------------------------------------------------------===//
207// Objective-C Decl Implementation
208//===----------------------------------------------------------------------===//
209
210void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
211 unsigned NumParams) {
212 assert(ParamInfo == 0 && "Already has param info!");
213
214 // Zero params -> null pointer.
215 if (NumParams) {
216 ParamInfo = new ParmVarDecl*[NumParams];
217 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
218 NumMethodParams = NumParams;
219 }
220}
221
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000222/// FindPropertyDeclaration - Finds declaration of the property given its name
223/// in 'PropertyId' and returns it. It returns 0, if not found.
224///
225ObjCPropertyDecl *
226 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
227 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
228 E = classprop_end(); I != E; ++I) {
229 ObjCPropertyDecl *property = *I;
230 if (property->getIdentifier() == PropertyId)
231 return property;
232 }
Steve Naroff30faf472008-06-04 04:46:04 +0000233 // Look through categories.
234 for (ObjCCategoryDecl *Category = getCategoryList();
235 Category; Category = Category->getNextClassCategory()) {
236 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
237 if (property)
238 return property;
239 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000240 // Look through protocols.
241 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
242 E = protocol_end(); I != E; ++I) {
243 ObjCProtocolDecl *Protocol = *I;
244 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
245 if (property)
246 return property;
247 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000248 if (getSuperClass())
249 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000250 return 0;
251}
252
253/// FindCategoryDeclaration - Finds category declaration in the list of
254/// categories for this class and returns it. Name of the category is passed
255/// in 'CategoryId'. If category not found, return 0;
256///
257ObjCCategoryDecl *
258 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
259 for (ObjCCategoryDecl *Category = getCategoryList();
260 Category; Category = Category->getNextClassCategory())
261 if (Category->getIdentifier() == CategoryId)
262 return Category;
263 return 0;
264}
265
266/// FindIvarDeclaration - Find an Ivar declaration in this class given its
267/// name in 'IvarId'. On failure to find, return 0;
268///
269ObjCIvarDecl *
270 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
271 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
272 IVE = ivar_end(); IVI != IVE; ++IVI) {
273 ObjCIvarDecl* Ivar = (*IVI);
274 if (Ivar->getIdentifier() == IvarId)
275 return Ivar;
276 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000277 if (getSuperClass())
278 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000279 return 0;
280}
281
Chris Lattner10318b82008-03-16 00:19:01 +0000282/// ObjCAddInstanceVariablesToClass - Inserts instance variables
283/// into ObjCInterfaceDecl's fields.
284///
285void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
286 unsigned numIvars,
287 SourceLocation RBrac) {
288 NumIvars = numIvars;
289 if (numIvars) {
290 Ivars = new ObjCIvarDecl*[numIvars];
291 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
292 }
293 setLocEnd(RBrac);
294}
295
296/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
297/// Variables (Ivars) relative to what declared in @implementation;s class.
298/// Ivars into ObjCImplementationDecl's fields.
299///
300void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
301 ObjCIvarDecl **ivars, unsigned numIvars) {
302 NumIvars = numIvars;
303 if (numIvars) {
304 Ivars = new ObjCIvarDecl*[numIvars];
305 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
306 }
307}
308
309/// addMethods - Insert instance and methods declarations into
310/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
311///
312void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
313 unsigned numInsMembers,
314 ObjCMethodDecl **clsMethods,
315 unsigned numClsMembers,
316 SourceLocation endLoc) {
317 NumInstanceMethods = numInsMembers;
318 if (numInsMembers) {
319 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
320 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
321 }
322 NumClassMethods = numClsMembers;
323 if (numClsMembers) {
324 ClassMethods = new ObjCMethodDecl*[numClsMembers];
325 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
326 }
327 AtEndLoc = endLoc;
328}
329
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000330/// addProperties - Insert property declaration AST nodes into
331/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000332///
333void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
334 unsigned NumProperties) {
335 if (NumProperties == 0) return;
336
337 NumPropertyDecl = NumProperties;
338 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
339 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
340}
341
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000342/// mergeProperties - Adds properties to the end of list of current properties
343/// for this class.
344
345void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
346 unsigned NumNewProperties) {
347 if (NumNewProperties == 0) return;
348
349 if (PropertyDecl) {
350 ObjCPropertyDecl **newPropertyDecl =
351 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
352 ObjCPropertyDecl **buf = newPropertyDecl;
353 // put back original properties in buffer.
354 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
355 // Add new properties to this buffer.
356 memcpy(buf+NumPropertyDecl, Properties,
357 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes1ee78042008-05-10 10:31:54 +0000358 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000359 PropertyDecl = newPropertyDecl;
360 NumPropertyDecl += NumNewProperties;
361 }
362 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000363 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000364 }
365}
366
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000367/// addPropertyMethods - Goes through list of properties declared in this class
368/// and builds setter/getter method declartions depending on the setter/getter
369/// attributes of the property.
370///
371void ObjCInterfaceDecl::addPropertyMethods(
372 ASTContext &Context,
373 ObjCPropertyDecl *property,
374 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
375 // Find the default getter and if one not found, add one.
376 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
377 if (GetterDecl) {
378 // An instance method with same name as property getter name found.
379 property->setGetterMethodDecl(GetterDecl);
380 }
381 else {
382 // No instance method of same name as property getter name was found.
383 // Declare a getter method and add it to the list of methods
384 // for this class.
385 QualType resultDeclType = property->getType();
386 ObjCMethodDecl* ObjCMethod =
387 ObjCMethodDecl::Create(Context, property->getLocation(),
388 property->getLocation(),
389 property->getGetterName(), resultDeclType,
390 this, 0,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +0000391 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000392 property->setGetterMethodDecl(ObjCMethod);
393 insMethods.push_back(ObjCMethod);
394 }
395}
396
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000397/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000398/// ObjCProtocolDecl's PropertyDecl field.
399///
400void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
401 unsigned NumProperties) {
402 if (NumProperties == 0) return;
403
404 NumPropertyDecl = NumProperties;
405 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
406 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
407}
408
409/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000410/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000411///
412void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
413 unsigned NumProperties) {
414 if (NumProperties == 0) return;
415
416 NumPropertyDecl = NumProperties;
417 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
418 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
419}
420
Chris Lattnercffe3662008-03-16 21:23:50 +0000421/// addMethods - Insert instance and methods declarations into
Chris Lattner10318b82008-03-16 00:19:01 +0000422/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
423///
424void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
425 unsigned numInsMembers,
426 ObjCMethodDecl **clsMethods,
427 unsigned numClsMembers,
428 SourceLocation endLoc) {
429 NumInstanceMethods = numInsMembers;
430 if (numInsMembers) {
431 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
432 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
433 }
434 NumClassMethods = numClsMembers;
435 if (numClsMembers) {
436 ClassMethods = new ObjCMethodDecl*[numClsMembers];
437 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
438 }
439 AtEndLoc = endLoc;
440}
441
Chris Lattner321b5d12008-03-16 20:47:45 +0000442
443
Chris Lattner10318b82008-03-16 00:19:01 +0000444/// addMethods - Insert instance and methods declarations into
445/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
446///
447void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
448 unsigned numInsMembers,
449 ObjCMethodDecl **clsMethods,
450 unsigned numClsMembers,
451 SourceLocation endLoc) {
452 NumInstanceMethods = numInsMembers;
453 if (numInsMembers) {
454 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
455 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
456 }
457 NumClassMethods = numClsMembers;
458 if (numClsMembers) {
459 ClassMethods = new ObjCMethodDecl*[numClsMembers];
460 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
461 }
462 AtEndLoc = endLoc;
463}
464
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000465/// FindPropertyDeclaration - Finds declaration of the property given its name
466/// in 'PropertyId' and returns it. It returns 0, if not found.
467///
468ObjCPropertyDecl *
469ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
470 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
471 E = classprop_end(); I != E; ++I) {
472 ObjCPropertyDecl *property = *I;
473 if (property->getIdentifier() == PropertyId)
474 return property;
475 }
476 return 0;
477}
478
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000479/// FindPropertyDeclaration - Finds declaration of the property given its name
480/// in 'PropertyId' and returns it. It returns 0, if not found.
481///
482ObjCPropertyDecl *
483ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
484 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
485 E = classprop_end(); I != E; ++I) {
486 ObjCPropertyDecl *property = *I;
487 if (property->getIdentifier() == PropertyId)
488 return property;
489 }
490 return 0;
491}
492
Chris Lattner10318b82008-03-16 00:19:01 +0000493ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
494 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
495 ObjCInterfaceDecl* ClassDecl = this;
496 while (ClassDecl != NULL) {
497 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
498 I != E; ++I) {
499 if ((*I)->getIdentifier() == ID) {
500 clsDeclared = ClassDecl;
501 return *I;
502 }
503 }
504 ClassDecl = ClassDecl->getSuperClass();
505 }
506 return NULL;
507}
508
509/// lookupInstanceMethod - This method returns an instance method by looking in
510/// the class, its categories, and its super classes (using a linear search).
511ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
512 ObjCInterfaceDecl* ClassDecl = this;
513 ObjCMethodDecl *MethodDecl = 0;
514
515 while (ClassDecl != NULL) {
516 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
517 return MethodDecl;
518
519 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000520 const ObjCList<ObjCProtocolDecl> &Protocols =
521 ClassDecl->getReferencedProtocols();
522 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
523 E = Protocols.end(); I != E; ++I)
524 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000525 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000526
Chris Lattner10318b82008-03-16 00:19:01 +0000527 // Didn't find one yet - now look through categories.
528 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
529 while (CatDecl) {
530 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
531 return MethodDecl;
532 CatDecl = CatDecl->getNextClassCategory();
533 }
534 ClassDecl = ClassDecl->getSuperClass();
535 }
536 return NULL;
537}
538
539// lookupClassMethod - This method returns a class method by looking in the
540// class, its categories, and its super classes (using a linear search).
541ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
542 ObjCInterfaceDecl* ClassDecl = this;
543 ObjCMethodDecl *MethodDecl = 0;
544
545 while (ClassDecl != NULL) {
546 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
547 return MethodDecl;
548
549 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000550 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
551 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000552 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000553 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000554
Chris Lattner10318b82008-03-16 00:19:01 +0000555 // Didn't find one yet - now look through categories.
556 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
557 while (CatDecl) {
558 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
559 return MethodDecl;
560 CatDecl = CatDecl->getNextClassCategory();
561 }
562 ClassDecl = ClassDecl->getSuperClass();
563 }
564 return NULL;
565}
566
567/// lookupInstanceMethod - This method returns an instance method by looking in
568/// the class implementation. Unlike interfaces, we don't look outside the
569/// implementation.
570ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
571 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
572 if ((*I)->getSelector() == Sel)
573 return *I;
574 return NULL;
575}
576
577/// lookupClassMethod - This method returns a class method by looking in
578/// the class implementation. Unlike interfaces, we don't look outside the
579/// implementation.
580ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
581 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
582 I != E; ++I)
583 if ((*I)->getSelector() == Sel)
584 return *I;
585 return NULL;
586}
587
588// lookupInstanceMethod - This method returns an instance method by looking in
589// the class implementation. Unlike interfaces, we don't look outside the
590// implementation.
591ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
592 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
593 if ((*I)->getSelector() == Sel)
594 return *I;
595 return NULL;
596}
597
598// lookupClassMethod - This method returns an instance method by looking in
599// the class implementation. Unlike interfaces, we don't look outside the
600// implementation.
601ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
602 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
603 I != E; ++I)
604 if ((*I)->getSelector() == Sel)
605 return *I;
606 return NULL;
607}
608
609// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
610// it inherited.
611ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
612 ObjCMethodDecl *MethodDecl = NULL;
613
614 if ((MethodDecl = getInstanceMethod(Sel)))
615 return MethodDecl;
616
Chris Lattner0be08822008-07-21 21:32:27 +0000617 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
618 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
619 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000620 return NULL;
621}
622
623// lookupInstanceMethod - Lookup a class method in the protocol and protocols
624// it inherited.
625ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
626 ObjCMethodDecl *MethodDecl = NULL;
627
628 if ((MethodDecl = getClassMethod(Sel)))
629 return MethodDecl;
630
Chris Lattner0be08822008-07-21 21:32:27 +0000631 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
632 if ((MethodDecl = (*I)->getClassMethod(Sel)))
633 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000634 return NULL;
635}
636
637/// getSynthesizedMethodSize - Compute size of synthesized method name
638/// as done be the rewrite.
639///
640unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
641 // syntesized method name is a concatenation of -/+[class-name selector]
642 // Get length of this name.
643 unsigned length = 3; // _I_ or _C_
644 length += strlen(getClassInterface()->getName()) +1; // extra for _
645 NamedDecl *MethodContext = getMethodContext();
646 if (ObjCCategoryImplDecl *CID =
647 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
648 length += strlen(CID->getName()) +1;
649 length += getSelector().getName().size(); // selector name
650 return length;
651}
652
Chris Lattner052fbcd2008-04-06 05:25:03 +0000653ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000654 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
655 return ID;
656 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
657 return CD->getClassInterface();
658 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000659 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000660 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000661 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000662 return CID->getClassInterface();
663 assert(false && "unknown method context");
664 return 0;
665}
Chris Lattner44859612008-03-17 01:19:02 +0000666
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000667ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
668 SourceLocation atLoc,
669 SourceLocation L,
670 ObjCPropertyDecl *property,
671 PropertyImplKind kind,
672 ObjCIvarDecl *ivar) {
673 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
674 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
675}
Chris Lattner44859612008-03-17 01:19:02 +0000676
Chris Lattnereee57c02008-04-04 06:12:32 +0000677