blob: 4b798474f626df2bca434222a5f380b96311b27d [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,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000055 IdentifierInfo *Id,
56 SourceLocation ClassLoc,
Chris Lattner0e77ba02008-03-16 01:15:50 +000057 bool ForwardDecl, bool isInternal){
58 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattnerb752f282008-07-21 07:06:49 +000059 return new (Mem) ObjCInterfaceDecl(atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0e77ba02008-03-16 01:15:50 +000060 isInternal);
61}
62
Ted Kremenek8a779312008-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 Kremenek1a726d72008-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 Kremenek8a779312008-06-06 16:45:15 +000085 Decl::Destroy(C);
86}
87
88
Chris Lattnerb048c982008-04-06 04:47:34 +000089ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Steve Naroff8f3b2652008-07-16 18:22:22 +000090 IdentifierInfo *Id, QualType T, Expr *BW) {
Chris Lattner0e77ba02008-03-16 01:15:50 +000091 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Steve Naroff8f3b2652008-07-16 18:22:22 +000092 return new (Mem) ObjCIvarDecl(L, Id, T, BW);
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000093}
94
Chris Lattner0ed844b2008-04-04 06:12:32 +000095ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
96 SourceLocation L,
Chris Lattnerc8581052008-03-16 20:19:15 +000097 IdentifierInfo *Id) {
Chris Lattnercca59d72008-03-16 01:23:04 +000098 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner780f3292008-07-21 21:32:27 +000099 return new (Mem) ObjCProtocolDecl(L, Id);
Chris Lattnercca59d72008-03-16 01:23:04 +0000100}
101
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000102ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000103 delete [] InstanceMethods;
104 delete [] ClassMethods;
105 delete [] PropertyDecl;
106}
107
108void ObjCProtocolDecl::Destroy(ASTContext& C) {
109
110 // Referenced Protocols are not owned, so don't Destroy them.
111
112 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
113 if (*I) (*I)->Destroy(C);
114
115 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
116 if (*I) (*I)->Destroy(C);
117
118 // FIXME: Because there is no clear ownership
119 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
120 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
121
122 Decl::Destroy(C);
123}
124
125
Chris Lattner0ed844b2008-04-04 06:12:32 +0000126ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
127 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000128 ObjCInterfaceDecl **Elts, unsigned nElts) {
129 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
130 return new (Mem) ObjCClassDecl(L, Elts, nElts);
131}
132
Ted Kremenek400d95f2008-06-06 20:11:53 +0000133ObjCClassDecl::~ObjCClassDecl() {
134 delete [] ForwardDecls;
135}
136
137void ObjCClassDecl::Destroy(ASTContext& C) {
138
139 // FIXME: There is no clear ownership policy now for referenced
140 // ObjCInterfaceDecls. Some of them can be forward declarations that
141 // are never later defined (in which case the ObjCClassDecl owns them)
142 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
143 // we should have separate objects for forward declarations and definitions,
144 // obviating this problem. Because of this situation, referenced
145 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
146
147 Decl::Destroy(C);
148}
149
Chris Lattner61f9d412008-03-16 20:34:23 +0000150ObjCForwardProtocolDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000151ObjCForwardProtocolDecl::Create(ASTContext &C,
152 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000153 ObjCProtocolDecl **Elts, unsigned NumElts) {
154 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
155 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
156}
157
Ted Kremenek05ac3ef2008-06-06 21:05:33 +0000158ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
159 delete [] ReferencedProtocols;
160}
161
Chris Lattner0ed844b2008-04-04 06:12:32 +0000162ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
163 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000164 IdentifierInfo *Id) {
165 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner68c82cf2008-03-16 20:47:45 +0000166 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattner61f9d412008-03-16 20:34:23 +0000167}
168
Chris Lattner75c9cae2008-03-16 20:53:07 +0000169ObjCCategoryImplDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000170ObjCCategoryImplDecl::Create(ASTContext &C,
171 SourceLocation L,IdentifierInfo *Id,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000172 ObjCInterfaceDecl *ClassInterface) {
173 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
174 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
175}
176
177ObjCImplementationDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000178ObjCImplementationDecl::Create(ASTContext &C,
179 SourceLocation L,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000180 IdentifierInfo *Id,
181 ObjCInterfaceDecl *ClassInterface,
182 ObjCInterfaceDecl *SuperDecl) {
183 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
184 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
185}
Chris Lattner1e03a562008-03-16 00:19:01 +0000186
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000187ObjCCompatibleAliasDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000188ObjCCompatibleAliasDecl::Create(ASTContext &C,
189 SourceLocation L,
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000190 IdentifierInfo *Id,
191 ObjCInterfaceDecl* AliasedClass) {
192 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
193 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
194}
195
Chris Lattner0ed844b2008-04-04 06:12:32 +0000196ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniandae1a1a2008-04-11 23:40:25 +0000197 SourceLocation L,
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000198 IdentifierInfo *Id,
Fariborz Jahanian46b55e52008-05-05 18:51:55 +0000199 QualType T,
200 PropertyControl propControl) {
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000201 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000202 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000203}
204
Chris Lattner1e03a562008-03-16 00:19:01 +0000205//===----------------------------------------------------------------------===//
206// Objective-C Decl Implementation
207//===----------------------------------------------------------------------===//
208
209void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
210 unsigned NumParams) {
211 assert(ParamInfo == 0 && "Already has param info!");
212
213 // Zero params -> null pointer.
214 if (NumParams) {
215 ParamInfo = new ParmVarDecl*[NumParams];
216 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
217 NumMethodParams = NumParams;
218 }
219}
220
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000221/// FindPropertyDeclaration - Finds declaration of the property given its name
222/// in 'PropertyId' and returns it. It returns 0, if not found.
223///
224ObjCPropertyDecl *
225 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
226 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
227 E = classprop_end(); I != E; ++I) {
228 ObjCPropertyDecl *property = *I;
229 if (property->getIdentifier() == PropertyId)
230 return property;
231 }
Steve Naroff6c930f22008-06-04 04:46:04 +0000232 // Look through categories.
233 for (ObjCCategoryDecl *Category = getCategoryList();
234 Category; Category = Category->getNextClassCategory()) {
235 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
236 if (property)
237 return property;
238 }
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000239 // Look through protocols.
240 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
241 E = protocol_end(); I != E; ++I) {
242 ObjCProtocolDecl *Protocol = *I;
243 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
244 if (property)
245 return property;
246 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000247 if (getSuperClass())
248 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000249 return 0;
250}
251
252/// FindCategoryDeclaration - Finds category declaration in the list of
253/// categories for this class and returns it. Name of the category is passed
254/// in 'CategoryId'. If category not found, return 0;
255///
256ObjCCategoryDecl *
257 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
258 for (ObjCCategoryDecl *Category = getCategoryList();
259 Category; Category = Category->getNextClassCategory())
260 if (Category->getIdentifier() == CategoryId)
261 return Category;
262 return 0;
263}
264
265/// FindIvarDeclaration - Find an Ivar declaration in this class given its
266/// name in 'IvarId'. On failure to find, return 0;
267///
268ObjCIvarDecl *
269 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
270 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
271 IVE = ivar_end(); IVI != IVE; ++IVI) {
272 ObjCIvarDecl* Ivar = (*IVI);
273 if (Ivar->getIdentifier() == IvarId)
274 return Ivar;
275 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000276 if (getSuperClass())
277 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000278 return 0;
279}
280
Chris Lattner1e03a562008-03-16 00:19:01 +0000281/// ObjCAddInstanceVariablesToClass - Inserts instance variables
282/// into ObjCInterfaceDecl's fields.
283///
284void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
285 unsigned numIvars,
286 SourceLocation RBrac) {
287 NumIvars = numIvars;
288 if (numIvars) {
289 Ivars = new ObjCIvarDecl*[numIvars];
290 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
291 }
292 setLocEnd(RBrac);
293}
294
295/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
296/// Variables (Ivars) relative to what declared in @implementation;s class.
297/// Ivars into ObjCImplementationDecl's fields.
298///
299void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
300 ObjCIvarDecl **ivars, unsigned numIvars) {
301 NumIvars = numIvars;
302 if (numIvars) {
303 Ivars = new ObjCIvarDecl*[numIvars];
304 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
305 }
306}
307
308/// addMethods - Insert instance and methods declarations into
309/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
310///
311void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
312 unsigned numInsMembers,
313 ObjCMethodDecl **clsMethods,
314 unsigned numClsMembers,
315 SourceLocation endLoc) {
316 NumInstanceMethods = numInsMembers;
317 if (numInsMembers) {
318 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
319 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
320 }
321 NumClassMethods = numClsMembers;
322 if (numClsMembers) {
323 ClassMethods = new ObjCMethodDecl*[numClsMembers];
324 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
325 }
326 AtEndLoc = endLoc;
327}
328
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000329/// addProperties - Insert property declaration AST nodes into
330/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattner55d13b42008-03-16 21:23:50 +0000331///
332void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
333 unsigned NumProperties) {
334 if (NumProperties == 0) return;
335
336 NumPropertyDecl = NumProperties;
337 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
338 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
339}
340
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000341/// mergeProperties - Adds properties to the end of list of current properties
342/// for this class.
343
344void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
345 unsigned NumNewProperties) {
346 if (NumNewProperties == 0) return;
347
348 if (PropertyDecl) {
349 ObjCPropertyDecl **newPropertyDecl =
350 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
351 ObjCPropertyDecl **buf = newPropertyDecl;
352 // put back original properties in buffer.
353 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
354 // Add new properties to this buffer.
355 memcpy(buf+NumPropertyDecl, Properties,
356 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000357 delete[] PropertyDecl;
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000358 PropertyDecl = newPropertyDecl;
359 NumPropertyDecl += NumNewProperties;
360 }
361 else {
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000362 addProperties(Properties, NumNewProperties);
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000363 }
364}
365
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000366/// addPropertyMethods - Goes through list of properties declared in this class
367/// and builds setter/getter method declartions depending on the setter/getter
368/// attributes of the property.
369///
370void ObjCInterfaceDecl::addPropertyMethods(
371 ASTContext &Context,
372 ObjCPropertyDecl *property,
373 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
374 // Find the default getter and if one not found, add one.
375 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
376 if (GetterDecl) {
377 // An instance method with same name as property getter name found.
378 property->setGetterMethodDecl(GetterDecl);
379 }
380 else {
381 // No instance method of same name as property getter name was found.
382 // Declare a getter method and add it to the list of methods
383 // for this class.
384 QualType resultDeclType = property->getType();
385 ObjCMethodDecl* ObjCMethod =
386 ObjCMethodDecl::Create(Context, property->getLocation(),
387 property->getLocation(),
388 property->getGetterName(), resultDeclType,
389 this, 0,
Fariborz Jahanian46070342008-05-07 20:53:44 +0000390 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000391 property->setGetterMethodDecl(ObjCMethod);
392 insMethods.push_back(ObjCMethod);
393 }
394}
395
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000396/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian3dd4ba42008-04-17 18:25:18 +0000397/// ObjCProtocolDecl's PropertyDecl field.
398///
399void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
400 unsigned NumProperties) {
401 if (NumProperties == 0) return;
402
403 NumPropertyDecl = NumProperties;
404 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
405 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
406}
407
408/// addProperties - Insert property declaration AST nodes into
Fariborz Jahaniand9a3c332008-04-16 21:11:25 +0000409/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000410///
411void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
412 unsigned NumProperties) {
413 if (NumProperties == 0) return;
414
415 NumPropertyDecl = NumProperties;
416 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
417 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
418}
419
Chris Lattner55d13b42008-03-16 21:23:50 +0000420/// addMethods - Insert instance and methods declarations into
Chris Lattner1e03a562008-03-16 00:19:01 +0000421/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
422///
423void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
424 unsigned numInsMembers,
425 ObjCMethodDecl **clsMethods,
426 unsigned numClsMembers,
427 SourceLocation endLoc) {
428 NumInstanceMethods = numInsMembers;
429 if (numInsMembers) {
430 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
431 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
432 }
433 NumClassMethods = numClsMembers;
434 if (numClsMembers) {
435 ClassMethods = new ObjCMethodDecl*[numClsMembers];
436 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
437 }
438 AtEndLoc = endLoc;
439}
440
Chris Lattner68c82cf2008-03-16 20:47:45 +0000441
442
Chris Lattner1e03a562008-03-16 00:19:01 +0000443/// addMethods - Insert instance and methods declarations into
444/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
445///
446void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
447 unsigned numInsMembers,
448 ObjCMethodDecl **clsMethods,
449 unsigned numClsMembers,
450 SourceLocation endLoc) {
451 NumInstanceMethods = numInsMembers;
452 if (numInsMembers) {
453 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
454 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
455 }
456 NumClassMethods = numClsMembers;
457 if (numClsMembers) {
458 ClassMethods = new ObjCMethodDecl*[numClsMembers];
459 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
460 }
461 AtEndLoc = endLoc;
462}
463
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000464/// FindPropertyDeclaration - Finds declaration of the property given its name
465/// in 'PropertyId' and returns it. It returns 0, if not found.
466///
467ObjCPropertyDecl *
468ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
469 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
470 E = classprop_end(); I != E; ++I) {
471 ObjCPropertyDecl *property = *I;
472 if (property->getIdentifier() == PropertyId)
473 return property;
474 }
475 return 0;
476}
477
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000478/// FindPropertyDeclaration - Finds declaration of the property given its name
479/// in 'PropertyId' and returns it. It returns 0, if not found.
480///
481ObjCPropertyDecl *
482ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
483 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
484 E = classprop_end(); I != E; ++I) {
485 ObjCPropertyDecl *property = *I;
486 if (property->getIdentifier() == PropertyId)
487 return property;
488 }
489 return 0;
490}
491
Chris Lattner1e03a562008-03-16 00:19:01 +0000492ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
493 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
494 ObjCInterfaceDecl* ClassDecl = this;
495 while (ClassDecl != NULL) {
496 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
497 I != E; ++I) {
498 if ((*I)->getIdentifier() == ID) {
499 clsDeclared = ClassDecl;
500 return *I;
501 }
502 }
503 ClassDecl = ClassDecl->getSuperClass();
504 }
505 return NULL;
506}
507
508/// lookupInstanceMethod - This method returns an instance method by looking in
509/// the class, its categories, and its super classes (using a linear search).
510ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
511 ObjCInterfaceDecl* ClassDecl = this;
512 ObjCMethodDecl *MethodDecl = 0;
513
514 while (ClassDecl != NULL) {
515 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
516 return MethodDecl;
517
518 // Didn't find one yet - look through protocols.
Chris Lattner3db6cae2008-07-21 18:19:38 +0000519 const ObjCList<ObjCProtocolDecl> &Protocols =
520 ClassDecl->getReferencedProtocols();
521 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
522 E = Protocols.end(); I != E; ++I)
523 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000524 return MethodDecl;
Chris Lattner3db6cae2008-07-21 18:19:38 +0000525
Chris Lattner1e03a562008-03-16 00:19:01 +0000526 // Didn't find one yet - now look through categories.
527 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
528 while (CatDecl) {
529 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
530 return MethodDecl;
531 CatDecl = CatDecl->getNextClassCategory();
532 }
533 ClassDecl = ClassDecl->getSuperClass();
534 }
535 return NULL;
536}
537
538// lookupClassMethod - This method returns a class method by looking in the
539// class, its categories, and its super classes (using a linear search).
540ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
541 ObjCInterfaceDecl* ClassDecl = this;
542 ObjCMethodDecl *MethodDecl = 0;
543
544 while (ClassDecl != NULL) {
545 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
546 return MethodDecl;
547
548 // Didn't find one yet - look through protocols.
Chris Lattner780f3292008-07-21 21:32:27 +0000549 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
550 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner3db6cae2008-07-21 18:19:38 +0000551 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000552 return MethodDecl;
Chris Lattner780f3292008-07-21 21:32:27 +0000553
Chris Lattner1e03a562008-03-16 00:19:01 +0000554 // Didn't find one yet - now look through categories.
555 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
556 while (CatDecl) {
557 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
558 return MethodDecl;
559 CatDecl = CatDecl->getNextClassCategory();
560 }
561 ClassDecl = ClassDecl->getSuperClass();
562 }
563 return NULL;
564}
565
566/// lookupInstanceMethod - This method returns an instance method by looking in
567/// the class implementation. Unlike interfaces, we don't look outside the
568/// implementation.
569ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
570 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
571 if ((*I)->getSelector() == Sel)
572 return *I;
573 return NULL;
574}
575
576/// lookupClassMethod - This method returns a class method by looking in
577/// the class implementation. Unlike interfaces, we don't look outside the
578/// implementation.
579ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
580 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
581 I != E; ++I)
582 if ((*I)->getSelector() == Sel)
583 return *I;
584 return NULL;
585}
586
587// lookupInstanceMethod - This method returns an instance method by looking in
588// the class implementation. Unlike interfaces, we don't look outside the
589// implementation.
590ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
591 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
592 if ((*I)->getSelector() == Sel)
593 return *I;
594 return NULL;
595}
596
597// lookupClassMethod - This method returns an instance method by looking in
598// the class implementation. Unlike interfaces, we don't look outside the
599// implementation.
600ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
601 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
602 I != E; ++I)
603 if ((*I)->getSelector() == Sel)
604 return *I;
605 return NULL;
606}
607
608// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
609// it inherited.
610ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
611 ObjCMethodDecl *MethodDecl = NULL;
612
613 if ((MethodDecl = getInstanceMethod(Sel)))
614 return MethodDecl;
615
Chris Lattner780f3292008-07-21 21:32:27 +0000616 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
617 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
618 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000619 return NULL;
620}
621
622// lookupInstanceMethod - Lookup a class method in the protocol and protocols
623// it inherited.
624ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
625 ObjCMethodDecl *MethodDecl = NULL;
626
627 if ((MethodDecl = getClassMethod(Sel)))
628 return MethodDecl;
629
Chris Lattner780f3292008-07-21 21:32:27 +0000630 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
631 if ((MethodDecl = (*I)->getClassMethod(Sel)))
632 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000633 return NULL;
634}
635
636/// getSynthesizedMethodSize - Compute size of synthesized method name
637/// as done be the rewrite.
638///
639unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
640 // syntesized method name is a concatenation of -/+[class-name selector]
641 // Get length of this name.
642 unsigned length = 3; // _I_ or _C_
643 length += strlen(getClassInterface()->getName()) +1; // extra for _
644 NamedDecl *MethodContext = getMethodContext();
645 if (ObjCCategoryImplDecl *CID =
646 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
647 length += strlen(CID->getName()) +1;
648 length += getSelector().getName().size(); // selector name
649 return length;
650}
651
Chris Lattner56196882008-04-06 05:25:03 +0000652ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner1e03a562008-03-16 00:19:01 +0000653 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
654 return ID;
655 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
656 return CD->getClassInterface();
657 if (ObjCImplementationDecl *IMD =
Chris Lattner56196882008-04-06 05:25:03 +0000658 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000659 return IMD->getClassInterface();
Chris Lattner56196882008-04-06 05:25:03 +0000660 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000661 return CID->getClassInterface();
662 assert(false && "unknown method context");
663 return 0;
664}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000665
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000666ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
667 SourceLocation atLoc,
668 SourceLocation L,
669 ObjCPropertyDecl *property,
670 PropertyImplKind kind,
671 ObjCIvarDecl *ivar) {
672 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
673 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
674}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000675
Chris Lattner0ed844b2008-04-04 06:12:32 +0000676