blob: bd8b874735fc2cafdb231077ef9e6f515984e704 [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"
Daniel Dunbarde300732008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Chris Lattner10318b82008-03-16 00:19:01 +000017using namespace clang;
18
Chris Lattner114add62008-03-16 00:49:28 +000019//===----------------------------------------------------------------------===//
20// ObjC Decl Allocation/Deallocation Method Implementations
21//===----------------------------------------------------------------------===//
22
Chris Lattnereee57c02008-04-04 06:12:32 +000023ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
24 SourceLocation beginLoc,
Chris Lattner114add62008-03-16 00:49:28 +000025 SourceLocation endLoc,
26 Selector SelInfo, QualType T,
27 Decl *contextDecl,
Chris Lattner114add62008-03-16 00:49:28 +000028 AttributeList *M, bool isInstance,
29 bool isVariadic,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000030 bool isSynthesized,
Chris Lattnerf7355832008-03-16 00:58:16 +000031 ImplementationControl impControl) {
Chris Lattner114add62008-03-16 00:49:28 +000032 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000033 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
34 SelInfo, T, contextDecl,
Chris Lattnerf7355832008-03-16 00:58:16 +000035 M, isInstance,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000036 isVariadic, isSynthesized, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000037}
Chris Lattner114add62008-03-16 00:49:28 +000038
Ted Kremenek8c945b12008-06-06 16:45:15 +000039ObjCMethodDecl::~ObjCMethodDecl() {
40 delete [] ParamInfo;
41 //delete [] MethodAttrs; // FIXME: Also destroy the stored Expr*.
42}
43
44void ObjCMethodDecl::Destroy(ASTContext& C) {
45 if (Body) Body->Destroy(C);
46 if (SelfDecl) SelfDecl->Destroy(C);
47
48 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
49 if (*I) (*I)->Destroy(C);
50
51 Decl::Destroy(C);
52}
53
Chris Lattnereee57c02008-04-04 06:12:32 +000054ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
55 SourceLocation atLoc,
Steve Naroff7c371742008-04-11 19:35:35 +000056 IdentifierInfo *Id,
57 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000058 bool ForwardDecl, bool isInternal){
59 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattner5cece462008-07-21 07:06:49 +000060 return new (Mem) ObjCInterfaceDecl(atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000061 isInternal);
62}
63
Ted Kremenek8c945b12008-06-06 16:45:15 +000064ObjCInterfaceDecl::~ObjCInterfaceDecl() {
65 delete [] Ivars;
66 delete [] InstanceMethods;
67 delete [] ClassMethods;
68 delete [] PropertyDecl;
69 // FIXME: CategoryList?
70}
71
72void ObjCInterfaceDecl::Destroy(ASTContext& C) {
73 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
74 if (*I) (*I)->Destroy(C);
75
76 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
77 if (*I) (*I)->Destroy(C);
78
79 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
80 if (*I) (*I)->Destroy(C);
Ted Kremenek22db1602008-06-06 17:21:42 +000081
82 // FIXME: Because there is no clear ownership
83 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
84 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
85
Ted Kremenek8c945b12008-06-06 16:45:15 +000086 Decl::Destroy(C);
87}
88
89
Chris Lattnerf3874bc2008-04-06 04:47:34 +000090ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenek173dd312008-07-23 18:04:17 +000091 IdentifierInfo *Id, QualType T,
92 AccessControl ac, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000093 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenek173dd312008-07-23 18:04:17 +000094 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000095}
96
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000097
98ObjCAtDefsFieldDecl
99*ObjCAtDefsFieldDecl::Create(ASTContext &C, SourceLocation L,
100 IdentifierInfo *Id, QualType T, Expr *BW) {
101 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
102 return new (Mem) ObjCAtDefsFieldDecl(L, Id, T, BW);
103}
104
105void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
106 this->~ObjCAtDefsFieldDecl();
107 C.getAllocator().Deallocate((void *)this);
108}
109
Chris Lattnereee57c02008-04-04 06:12:32 +0000110ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
111 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000112 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +0000113 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner0be08822008-07-21 21:32:27 +0000114 return new (Mem) ObjCProtocolDecl(L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000115}
116
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000117ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000118 delete [] InstanceMethods;
119 delete [] ClassMethods;
120 delete [] PropertyDecl;
121}
122
123void ObjCProtocolDecl::Destroy(ASTContext& C) {
124
125 // Referenced Protocols are not owned, so don't Destroy them.
126
127 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
128 if (*I) (*I)->Destroy(C);
129
130 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
131 if (*I) (*I)->Destroy(C);
132
133 // FIXME: Because there is no clear ownership
134 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
135 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
136
137 Decl::Destroy(C);
138}
139
140
Chris Lattnereee57c02008-04-04 06:12:32 +0000141ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
142 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000143 ObjCInterfaceDecl **Elts, unsigned nElts) {
144 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
145 return new (Mem) ObjCClassDecl(L, Elts, nElts);
146}
147
Ted Kremenekff291622008-06-06 20:11:53 +0000148ObjCClassDecl::~ObjCClassDecl() {
149 delete [] ForwardDecls;
150}
151
152void ObjCClassDecl::Destroy(ASTContext& C) {
153
154 // FIXME: There is no clear ownership policy now for referenced
155 // ObjCInterfaceDecls. Some of them can be forward declarations that
156 // are never later defined (in which case the ObjCClassDecl owns them)
157 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
158 // we should have separate objects for forward declarations and definitions,
159 // obviating this problem. Because of this situation, referenced
160 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
161
162 Decl::Destroy(C);
163}
164
Chris Lattnere29dc832008-03-16 20:34:23 +0000165ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000166ObjCForwardProtocolDecl::Create(ASTContext &C,
167 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000168 ObjCProtocolDecl **Elts, unsigned NumElts) {
169 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
170 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
171}
172
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000173ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
174 delete [] ReferencedProtocols;
175}
176
Chris Lattnereee57c02008-04-04 06:12:32 +0000177ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
178 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000179 IdentifierInfo *Id) {
180 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +0000181 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000182}
183
Chris Lattner1b6de332008-03-16 20:53:07 +0000184ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000185ObjCCategoryImplDecl::Create(ASTContext &C,
186 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000187 ObjCInterfaceDecl *ClassInterface) {
188 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
189 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
190}
191
192ObjCImplementationDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000193ObjCImplementationDecl::Create(ASTContext &C,
194 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000195 IdentifierInfo *Id,
196 ObjCInterfaceDecl *ClassInterface,
197 ObjCInterfaceDecl *SuperDecl) {
198 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
199 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
200}
Chris Lattner10318b82008-03-16 00:19:01 +0000201
Chris Lattner2d1c4312008-03-16 21:17:37 +0000202ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000203ObjCCompatibleAliasDecl::Create(ASTContext &C,
204 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000205 IdentifierInfo *Id,
206 ObjCInterfaceDecl* AliasedClass) {
207 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
208 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
209}
210
Chris Lattnereee57c02008-04-04 06:12:32 +0000211ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000212 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000213 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000214 QualType T,
215 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000216 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000217 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000218}
219
Chris Lattner10318b82008-03-16 00:19:01 +0000220//===----------------------------------------------------------------------===//
221// Objective-C Decl Implementation
222//===----------------------------------------------------------------------===//
223
224void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
225 unsigned NumParams) {
226 assert(ParamInfo == 0 && "Already has param info!");
227
228 // Zero params -> null pointer.
229 if (NumParams) {
230 ParamInfo = new ParmVarDecl*[NumParams];
231 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
232 NumMethodParams = NumParams;
233 }
234}
235
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000236/// FindPropertyDeclaration - Finds declaration of the property given its name
237/// in 'PropertyId' and returns it. It returns 0, if not found.
238///
239ObjCPropertyDecl *
240 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
241 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
242 E = classprop_end(); I != E; ++I) {
243 ObjCPropertyDecl *property = *I;
244 if (property->getIdentifier() == PropertyId)
245 return property;
246 }
Steve Naroff30faf472008-06-04 04:46:04 +0000247 // Look through categories.
248 for (ObjCCategoryDecl *Category = getCategoryList();
249 Category; Category = Category->getNextClassCategory()) {
250 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
251 if (property)
252 return property;
253 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000254 // Look through protocols.
255 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
256 E = protocol_end(); I != E; ++I) {
257 ObjCProtocolDecl *Protocol = *I;
258 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
259 if (property)
260 return property;
261 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000262 if (getSuperClass())
263 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000264 return 0;
265}
266
267/// FindCategoryDeclaration - Finds category declaration in the list of
268/// categories for this class and returns it. Name of the category is passed
269/// in 'CategoryId'. If category not found, return 0;
270///
271ObjCCategoryDecl *
272 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
273 for (ObjCCategoryDecl *Category = getCategoryList();
274 Category; Category = Category->getNextClassCategory())
275 if (Category->getIdentifier() == CategoryId)
276 return Category;
277 return 0;
278}
279
280/// FindIvarDeclaration - Find an Ivar declaration in this class given its
281/// name in 'IvarId'. On failure to find, return 0;
282///
283ObjCIvarDecl *
284 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
285 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
286 IVE = ivar_end(); IVI != IVE; ++IVI) {
287 ObjCIvarDecl* Ivar = (*IVI);
288 if (Ivar->getIdentifier() == IvarId)
289 return Ivar;
290 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000291 if (getSuperClass())
292 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000293 return 0;
294}
295
Chris Lattner10318b82008-03-16 00:19:01 +0000296/// ObjCAddInstanceVariablesToClass - Inserts instance variables
297/// into ObjCInterfaceDecl's fields.
298///
299void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
300 unsigned numIvars,
301 SourceLocation RBrac) {
302 NumIvars = numIvars;
303 if (numIvars) {
304 Ivars = new ObjCIvarDecl*[numIvars];
305 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
306 }
307 setLocEnd(RBrac);
308}
309
310/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
311/// Variables (Ivars) relative to what declared in @implementation;s class.
312/// Ivars into ObjCImplementationDecl's fields.
313///
314void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
315 ObjCIvarDecl **ivars, unsigned numIvars) {
316 NumIvars = numIvars;
317 if (numIvars) {
318 Ivars = new ObjCIvarDecl*[numIvars];
319 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
320 }
321}
322
323/// addMethods - Insert instance and methods declarations into
324/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
325///
326void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
327 unsigned numInsMembers,
328 ObjCMethodDecl **clsMethods,
329 unsigned numClsMembers,
330 SourceLocation endLoc) {
331 NumInstanceMethods = numInsMembers;
332 if (numInsMembers) {
333 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
334 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
335 }
336 NumClassMethods = numClsMembers;
337 if (numClsMembers) {
338 ClassMethods = new ObjCMethodDecl*[numClsMembers];
339 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
340 }
341 AtEndLoc = endLoc;
342}
343
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000344/// addProperties - Insert property declaration AST nodes into
345/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000346///
347void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
348 unsigned NumProperties) {
349 if (NumProperties == 0) return;
350
351 NumPropertyDecl = NumProperties;
352 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
353 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
354}
355
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000356/// mergeProperties - Adds properties to the end of list of current properties
357/// for this class.
358
359void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
360 unsigned NumNewProperties) {
361 if (NumNewProperties == 0) return;
362
363 if (PropertyDecl) {
364 ObjCPropertyDecl **newPropertyDecl =
365 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
366 ObjCPropertyDecl **buf = newPropertyDecl;
367 // put back original properties in buffer.
368 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
369 // Add new properties to this buffer.
370 memcpy(buf+NumPropertyDecl, Properties,
371 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes1ee78042008-05-10 10:31:54 +0000372 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000373 PropertyDecl = newPropertyDecl;
374 NumPropertyDecl += NumNewProperties;
375 }
376 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000377 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000378 }
379}
380
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000381/// addPropertyMethods - Goes through list of properties declared in this class
382/// and builds setter/getter method declartions depending on the setter/getter
383/// attributes of the property.
384///
385void ObjCInterfaceDecl::addPropertyMethods(
386 ASTContext &Context,
387 ObjCPropertyDecl *property,
388 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
389 // Find the default getter and if one not found, add one.
390 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
391 if (GetterDecl) {
392 // An instance method with same name as property getter name found.
393 property->setGetterMethodDecl(GetterDecl);
394 }
395 else {
396 // No instance method of same name as property getter name was found.
397 // Declare a getter method and add it to the list of methods
398 // for this class.
399 QualType resultDeclType = property->getType();
400 ObjCMethodDecl* ObjCMethod =
401 ObjCMethodDecl::Create(Context, property->getLocation(),
402 property->getLocation(),
403 property->getGetterName(), resultDeclType,
404 this, 0,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +0000405 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000406 property->setGetterMethodDecl(ObjCMethod);
407 insMethods.push_back(ObjCMethod);
408 }
409}
410
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000411/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000412/// ObjCProtocolDecl's PropertyDecl field.
413///
414void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
415 unsigned NumProperties) {
416 if (NumProperties == 0) return;
417
418 NumPropertyDecl = NumProperties;
419 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
420 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
421}
422
423/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000424/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000425///
426void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
427 unsigned NumProperties) {
428 if (NumProperties == 0) return;
429
430 NumPropertyDecl = NumProperties;
431 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
432 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
433}
434
Chris Lattnercffe3662008-03-16 21:23:50 +0000435/// addMethods - Insert instance and methods declarations into
Chris Lattner10318b82008-03-16 00:19:01 +0000436/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
437///
438void ObjCProtocolDecl::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
Chris Lattner321b5d12008-03-16 20:47:45 +0000456
457
Chris Lattner10318b82008-03-16 00:19:01 +0000458/// addMethods - Insert instance and methods declarations into
459/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
460///
461void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
462 unsigned numInsMembers,
463 ObjCMethodDecl **clsMethods,
464 unsigned numClsMembers,
465 SourceLocation endLoc) {
466 NumInstanceMethods = numInsMembers;
467 if (numInsMembers) {
468 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
469 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
470 }
471 NumClassMethods = numClsMembers;
472 if (numClsMembers) {
473 ClassMethods = new ObjCMethodDecl*[numClsMembers];
474 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
475 }
476 AtEndLoc = endLoc;
477}
478
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000479/// FindPropertyDeclaration - Finds declaration of the property given its name
480/// in 'PropertyId' and returns it. It returns 0, if not found.
481///
482ObjCPropertyDecl *
483ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
484 for (ObjCCategoryDecl::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
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000493/// FindPropertyDeclaration - Finds declaration of the property given its name
494/// in 'PropertyId' and returns it. It returns 0, if not found.
495///
496ObjCPropertyDecl *
497ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
498 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
499 E = classprop_end(); I != E; ++I) {
500 ObjCPropertyDecl *property = *I;
501 if (property->getIdentifier() == PropertyId)
502 return property;
503 }
504 return 0;
505}
506
Chris Lattner10318b82008-03-16 00:19:01 +0000507ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
508 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
509 ObjCInterfaceDecl* ClassDecl = this;
510 while (ClassDecl != NULL) {
511 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
512 I != E; ++I) {
513 if ((*I)->getIdentifier() == ID) {
514 clsDeclared = ClassDecl;
515 return *I;
516 }
517 }
518 ClassDecl = ClassDecl->getSuperClass();
519 }
520 return NULL;
521}
522
523/// lookupInstanceMethod - This method returns an instance method by looking in
524/// the class, its categories, and its super classes (using a linear search).
525ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
526 ObjCInterfaceDecl* ClassDecl = this;
527 ObjCMethodDecl *MethodDecl = 0;
528
529 while (ClassDecl != NULL) {
530 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
531 return MethodDecl;
532
533 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000534 const ObjCList<ObjCProtocolDecl> &Protocols =
535 ClassDecl->getReferencedProtocols();
536 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
537 E = Protocols.end(); I != E; ++I)
538 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000539 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000540
Chris Lattner10318b82008-03-16 00:19:01 +0000541 // Didn't find one yet - now look through categories.
542 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
543 while (CatDecl) {
544 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
545 return MethodDecl;
546 CatDecl = CatDecl->getNextClassCategory();
547 }
548 ClassDecl = ClassDecl->getSuperClass();
549 }
550 return NULL;
551}
552
553// lookupClassMethod - This method returns a class method by looking in the
554// class, its categories, and its super classes (using a linear search).
555ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
556 ObjCInterfaceDecl* ClassDecl = this;
557 ObjCMethodDecl *MethodDecl = 0;
558
559 while (ClassDecl != NULL) {
560 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
561 return MethodDecl;
562
563 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000564 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
565 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000566 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000567 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000568
Chris Lattner10318b82008-03-16 00:19:01 +0000569 // Didn't find one yet - now look through categories.
570 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
571 while (CatDecl) {
572 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
573 return MethodDecl;
574 CatDecl = CatDecl->getNextClassCategory();
575 }
576 ClassDecl = ClassDecl->getSuperClass();
577 }
578 return NULL;
579}
580
581/// lookupInstanceMethod - This method returns an instance method by looking in
582/// the class implementation. Unlike interfaces, we don't look outside the
583/// implementation.
584ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
585 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
586 if ((*I)->getSelector() == Sel)
587 return *I;
588 return NULL;
589}
590
591/// lookupClassMethod - This method returns a class method by looking in
592/// the class implementation. Unlike interfaces, we don't look outside the
593/// implementation.
594ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
595 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
596 I != E; ++I)
597 if ((*I)->getSelector() == Sel)
598 return *I;
599 return NULL;
600}
601
602// lookupInstanceMethod - This method returns an instance method by looking in
603// the class implementation. Unlike interfaces, we don't look outside the
604// implementation.
605ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
606 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
607 if ((*I)->getSelector() == Sel)
608 return *I;
609 return NULL;
610}
611
612// lookupClassMethod - This method returns an instance method by looking in
613// the class implementation. Unlike interfaces, we don't look outside the
614// implementation.
615ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
616 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
617 I != E; ++I)
618 if ((*I)->getSelector() == Sel)
619 return *I;
620 return NULL;
621}
622
623// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
624// it inherited.
625ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
626 ObjCMethodDecl *MethodDecl = NULL;
627
628 if ((MethodDecl = getInstanceMethod(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)->getInstanceMethod(Sel)))
633 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000634 return NULL;
635}
636
637// lookupInstanceMethod - Lookup a class method in the protocol and protocols
638// it inherited.
639ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
640 ObjCMethodDecl *MethodDecl = NULL;
641
642 if ((MethodDecl = getClassMethod(Sel)))
643 return MethodDecl;
644
Chris Lattner0be08822008-07-21 21:32:27 +0000645 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
646 if ((MethodDecl = (*I)->getClassMethod(Sel)))
647 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000648 return NULL;
649}
650
651/// getSynthesizedMethodSize - Compute size of synthesized method name
652/// as done be the rewrite.
653///
654unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
655 // syntesized method name is a concatenation of -/+[class-name selector]
656 // Get length of this name.
657 unsigned length = 3; // _I_ or _C_
658 length += strlen(getClassInterface()->getName()) +1; // extra for _
659 NamedDecl *MethodContext = getMethodContext();
660 if (ObjCCategoryImplDecl *CID =
661 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
662 length += strlen(CID->getName()) +1;
663 length += getSelector().getName().size(); // selector name
664 return length;
665}
666
Chris Lattner052fbcd2008-04-06 05:25:03 +0000667ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000668 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
669 return ID;
670 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
671 return CD->getClassInterface();
672 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000673 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000674 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000675 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000676 return CID->getClassInterface();
677 assert(false && "unknown method context");
678 return 0;
679}
Chris Lattner44859612008-03-17 01:19:02 +0000680
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000681ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
682 SourceLocation atLoc,
683 SourceLocation L,
684 ObjCPropertyDecl *property,
685 PropertyImplKind kind,
686 ObjCIvarDecl *ivar) {
687 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
688 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
689}
Chris Lattner44859612008-03-17 01:19:02 +0000690
Chris Lattnereee57c02008-04-04 06:12:32 +0000691