blob: 7b28b10f9198f6acb79cf7a6a5d0f3ec625180ab [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 Lattnercca59d72008-03-16 01:23:04 +000097 unsigned numRefProtos,
Chris Lattnerc8581052008-03-16 20:19:15 +000098 IdentifierInfo *Id) {
Chris Lattnercca59d72008-03-16 01:23:04 +000099 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattnerc8581052008-03-16 20:19:15 +0000100 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattnercca59d72008-03-16 01:23:04 +0000101}
102
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000103ObjCProtocolDecl::~ObjCProtocolDecl() {
104 delete [] ReferencedProtocols;
105 delete [] InstanceMethods;
106 delete [] ClassMethods;
107 delete [] PropertyDecl;
108}
109
110void ObjCProtocolDecl::Destroy(ASTContext& C) {
111
112 // Referenced Protocols are not owned, so don't Destroy them.
113
114 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
115 if (*I) (*I)->Destroy(C);
116
117 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
118 if (*I) (*I)->Destroy(C);
119
120 // FIXME: Because there is no clear ownership
121 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
122 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
123
124 Decl::Destroy(C);
125}
126
127
Chris Lattner0ed844b2008-04-04 06:12:32 +0000128ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
129 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000130 ObjCInterfaceDecl **Elts, unsigned nElts) {
131 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
132 return new (Mem) ObjCClassDecl(L, Elts, nElts);
133}
134
Ted Kremenek400d95f2008-06-06 20:11:53 +0000135ObjCClassDecl::~ObjCClassDecl() {
136 delete [] ForwardDecls;
137}
138
139void ObjCClassDecl::Destroy(ASTContext& C) {
140
141 // FIXME: There is no clear ownership policy now for referenced
142 // ObjCInterfaceDecls. Some of them can be forward declarations that
143 // are never later defined (in which case the ObjCClassDecl owns them)
144 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
145 // we should have separate objects for forward declarations and definitions,
146 // obviating this problem. Because of this situation, referenced
147 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
148
149 Decl::Destroy(C);
150}
151
Chris Lattner61f9d412008-03-16 20:34:23 +0000152ObjCForwardProtocolDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000153ObjCForwardProtocolDecl::Create(ASTContext &C,
154 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000155 ObjCProtocolDecl **Elts, unsigned NumElts) {
156 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
157 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
158}
159
Ted Kremenek05ac3ef2008-06-06 21:05:33 +0000160ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
161 delete [] ReferencedProtocols;
162}
163
Chris Lattner0ed844b2008-04-04 06:12:32 +0000164ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
165 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000166 IdentifierInfo *Id) {
167 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner68c82cf2008-03-16 20:47:45 +0000168 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattner61f9d412008-03-16 20:34:23 +0000169}
170
Chris Lattner75c9cae2008-03-16 20:53:07 +0000171ObjCCategoryImplDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000172ObjCCategoryImplDecl::Create(ASTContext &C,
173 SourceLocation L,IdentifierInfo *Id,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000174 ObjCInterfaceDecl *ClassInterface) {
175 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
176 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
177}
178
179ObjCImplementationDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000180ObjCImplementationDecl::Create(ASTContext &C,
181 SourceLocation L,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000182 IdentifierInfo *Id,
183 ObjCInterfaceDecl *ClassInterface,
184 ObjCInterfaceDecl *SuperDecl) {
185 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
186 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
187}
Chris Lattner1e03a562008-03-16 00:19:01 +0000188
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000189ObjCCompatibleAliasDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000190ObjCCompatibleAliasDecl::Create(ASTContext &C,
191 SourceLocation L,
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000192 IdentifierInfo *Id,
193 ObjCInterfaceDecl* AliasedClass) {
194 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
195 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
196}
197
Chris Lattner0ed844b2008-04-04 06:12:32 +0000198ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniandae1a1a2008-04-11 23:40:25 +0000199 SourceLocation L,
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000200 IdentifierInfo *Id,
Fariborz Jahanian46b55e52008-05-05 18:51:55 +0000201 QualType T,
202 PropertyControl propControl) {
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000203 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000204 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000205}
206
Chris Lattner1e03a562008-03-16 00:19:01 +0000207//===----------------------------------------------------------------------===//
208// Objective-C Decl Implementation
209//===----------------------------------------------------------------------===//
210
211void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
212 unsigned NumParams) {
213 assert(ParamInfo == 0 && "Already has param info!");
214
215 // Zero params -> null pointer.
216 if (NumParams) {
217 ParamInfo = new ParmVarDecl*[NumParams];
218 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
219 NumMethodParams = NumParams;
220 }
221}
222
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000223/// FindPropertyDeclaration - Finds declaration of the property given its name
224/// in 'PropertyId' and returns it. It returns 0, if not found.
225///
226ObjCPropertyDecl *
227 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
228 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
229 E = classprop_end(); I != E; ++I) {
230 ObjCPropertyDecl *property = *I;
231 if (property->getIdentifier() == PropertyId)
232 return property;
233 }
Steve Naroff6c930f22008-06-04 04:46:04 +0000234 // Look through categories.
235 for (ObjCCategoryDecl *Category = getCategoryList();
236 Category; Category = Category->getNextClassCategory()) {
237 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
238 if (property)
239 return property;
240 }
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000241 // Look through protocols.
242 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
243 E = protocol_end(); I != E; ++I) {
244 ObjCProtocolDecl *Protocol = *I;
245 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
246 if (property)
247 return property;
248 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000249 if (getSuperClass())
250 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000251 return 0;
252}
253
254/// FindCategoryDeclaration - Finds category declaration in the list of
255/// categories for this class and returns it. Name of the category is passed
256/// in 'CategoryId'. If category not found, return 0;
257///
258ObjCCategoryDecl *
259 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
260 for (ObjCCategoryDecl *Category = getCategoryList();
261 Category; Category = Category->getNextClassCategory())
262 if (Category->getIdentifier() == CategoryId)
263 return Category;
264 return 0;
265}
266
267/// FindIvarDeclaration - Find an Ivar declaration in this class given its
268/// name in 'IvarId'. On failure to find, return 0;
269///
270ObjCIvarDecl *
271 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
272 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
273 IVE = ivar_end(); IVI != IVE; ++IVI) {
274 ObjCIvarDecl* Ivar = (*IVI);
275 if (Ivar->getIdentifier() == IvarId)
276 return Ivar;
277 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000278 if (getSuperClass())
279 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000280 return 0;
281}
282
Chris Lattner1e03a562008-03-16 00:19:01 +0000283/// ObjCAddInstanceVariablesToClass - Inserts instance variables
284/// into ObjCInterfaceDecl's fields.
285///
286void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
287 unsigned numIvars,
288 SourceLocation RBrac) {
289 NumIvars = numIvars;
290 if (numIvars) {
291 Ivars = new ObjCIvarDecl*[numIvars];
292 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
293 }
294 setLocEnd(RBrac);
295}
296
297/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
298/// Variables (Ivars) relative to what declared in @implementation;s class.
299/// Ivars into ObjCImplementationDecl's fields.
300///
301void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
302 ObjCIvarDecl **ivars, unsigned numIvars) {
303 NumIvars = numIvars;
304 if (numIvars) {
305 Ivars = new ObjCIvarDecl*[numIvars];
306 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
307 }
308}
309
310/// addMethods - Insert instance and methods declarations into
311/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
312///
313void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
314 unsigned numInsMembers,
315 ObjCMethodDecl **clsMethods,
316 unsigned numClsMembers,
317 SourceLocation endLoc) {
318 NumInstanceMethods = numInsMembers;
319 if (numInsMembers) {
320 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
321 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
322 }
323 NumClassMethods = numClsMembers;
324 if (numClsMembers) {
325 ClassMethods = new ObjCMethodDecl*[numClsMembers];
326 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
327 }
328 AtEndLoc = endLoc;
329}
330
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000331/// addProperties - Insert property declaration AST nodes into
332/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattner55d13b42008-03-16 21:23:50 +0000333///
334void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
335 unsigned NumProperties) {
336 if (NumProperties == 0) return;
337
338 NumPropertyDecl = NumProperties;
339 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
340 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
341}
342
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000343/// mergeProperties - Adds properties to the end of list of current properties
344/// for this class.
345
346void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
347 unsigned NumNewProperties) {
348 if (NumNewProperties == 0) return;
349
350 if (PropertyDecl) {
351 ObjCPropertyDecl **newPropertyDecl =
352 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
353 ObjCPropertyDecl **buf = newPropertyDecl;
354 // put back original properties in buffer.
355 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
356 // Add new properties to this buffer.
357 memcpy(buf+NumPropertyDecl, Properties,
358 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000359 delete[] PropertyDecl;
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000360 PropertyDecl = newPropertyDecl;
361 NumPropertyDecl += NumNewProperties;
362 }
363 else {
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000364 addProperties(Properties, NumNewProperties);
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000365 }
366}
367
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000368/// addPropertyMethods - Goes through list of properties declared in this class
369/// and builds setter/getter method declartions depending on the setter/getter
370/// attributes of the property.
371///
372void ObjCInterfaceDecl::addPropertyMethods(
373 ASTContext &Context,
374 ObjCPropertyDecl *property,
375 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
376 // Find the default getter and if one not found, add one.
377 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
378 if (GetterDecl) {
379 // An instance method with same name as property getter name found.
380 property->setGetterMethodDecl(GetterDecl);
381 }
382 else {
383 // No instance method of same name as property getter name was found.
384 // Declare a getter method and add it to the list of methods
385 // for this class.
386 QualType resultDeclType = property->getType();
387 ObjCMethodDecl* ObjCMethod =
388 ObjCMethodDecl::Create(Context, property->getLocation(),
389 property->getLocation(),
390 property->getGetterName(), resultDeclType,
391 this, 0,
Fariborz Jahanian46070342008-05-07 20:53:44 +0000392 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000393 property->setGetterMethodDecl(ObjCMethod);
394 insMethods.push_back(ObjCMethod);
395 }
396}
397
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000398/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian3dd4ba42008-04-17 18:25:18 +0000399/// ObjCProtocolDecl's PropertyDecl field.
400///
401void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
402 unsigned NumProperties) {
403 if (NumProperties == 0) return;
404
405 NumPropertyDecl = NumProperties;
406 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
407 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
408}
409
410/// addProperties - Insert property declaration AST nodes into
Fariborz Jahaniand9a3c332008-04-16 21:11:25 +0000411/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000412///
413void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
414 unsigned NumProperties) {
415 if (NumProperties == 0) return;
416
417 NumPropertyDecl = NumProperties;
418 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
419 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
420}
421
Chris Lattner55d13b42008-03-16 21:23:50 +0000422/// addMethods - Insert instance and methods declarations into
Chris Lattner1e03a562008-03-16 00:19:01 +0000423/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
424///
425void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
426 unsigned numInsMembers,
427 ObjCMethodDecl **clsMethods,
428 unsigned numClsMembers,
429 SourceLocation endLoc) {
430 NumInstanceMethods = numInsMembers;
431 if (numInsMembers) {
432 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
433 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
434 }
435 NumClassMethods = numClsMembers;
436 if (numClsMembers) {
437 ClassMethods = new ObjCMethodDecl*[numClsMembers];
438 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
439 }
440 AtEndLoc = endLoc;
441}
442
Chris Lattnerf7b2c982008-07-21 17:23:15 +0000443void ObjCCategoryDecl::addReferencedProtocols(ObjCProtocolDecl **List,
444 unsigned NumRPs) {
Chris Lattner68c82cf2008-03-16 20:47:45 +0000445 assert(NumReferencedProtocols == 0 && "Protocol list already set");
446 if (NumRPs == 0) return;
447
448 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
449 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
450 NumReferencedProtocols = NumRPs;
451}
452
453
Chris Lattner1e03a562008-03-16 00:19:01 +0000454/// addMethods - Insert instance and methods declarations into
455/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
456///
457void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
458 unsigned numInsMembers,
459 ObjCMethodDecl **clsMethods,
460 unsigned numClsMembers,
461 SourceLocation endLoc) {
462 NumInstanceMethods = numInsMembers;
463 if (numInsMembers) {
464 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
465 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
466 }
467 NumClassMethods = numClsMembers;
468 if (numClsMembers) {
469 ClassMethods = new ObjCMethodDecl*[numClsMembers];
470 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
471 }
472 AtEndLoc = endLoc;
473}
474
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000475/// FindPropertyDeclaration - Finds declaration of the property given its name
476/// in 'PropertyId' and returns it. It returns 0, if not found.
477///
478ObjCPropertyDecl *
479ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
480 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
481 E = classprop_end(); I != E; ++I) {
482 ObjCPropertyDecl *property = *I;
483 if (property->getIdentifier() == PropertyId)
484 return property;
485 }
486 return 0;
487}
488
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000489/// FindPropertyDeclaration - Finds declaration of the property given its name
490/// in 'PropertyId' and returns it. It returns 0, if not found.
491///
492ObjCPropertyDecl *
493ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
494 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
495 E = classprop_end(); I != E; ++I) {
496 ObjCPropertyDecl *property = *I;
497 if (property->getIdentifier() == PropertyId)
498 return property;
499 }
500 return 0;
501}
502
Chris Lattner1e03a562008-03-16 00:19:01 +0000503ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
504 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
505 ObjCInterfaceDecl* ClassDecl = this;
506 while (ClassDecl != NULL) {
507 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
508 I != E; ++I) {
509 if ((*I)->getIdentifier() == ID) {
510 clsDeclared = ClassDecl;
511 return *I;
512 }
513 }
514 ClassDecl = ClassDecl->getSuperClass();
515 }
516 return NULL;
517}
518
519/// lookupInstanceMethod - This method returns an instance method by looking in
520/// the class, its categories, and its super classes (using a linear search).
521ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
522 ObjCInterfaceDecl* ClassDecl = this;
523 ObjCMethodDecl *MethodDecl = 0;
524
525 while (ClassDecl != NULL) {
526 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
527 return MethodDecl;
528
529 // Didn't find one yet - look through protocols.
Chris Lattner3db6cae2008-07-21 18:19:38 +0000530 const ObjCList<ObjCProtocolDecl> &Protocols =
531 ClassDecl->getReferencedProtocols();
532 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
533 E = Protocols.end(); I != E; ++I)
534 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000535 return MethodDecl;
Chris Lattner3db6cae2008-07-21 18:19:38 +0000536
Chris Lattner1e03a562008-03-16 00:19:01 +0000537 // Didn't find one yet - now look through categories.
538 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
539 while (CatDecl) {
540 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
541 return MethodDecl;
542 CatDecl = CatDecl->getNextClassCategory();
543 }
544 ClassDecl = ClassDecl->getSuperClass();
545 }
546 return NULL;
547}
548
549// lookupClassMethod - This method returns a class method by looking in the
550// class, its categories, and its super classes (using a linear search).
551ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
552 ObjCInterfaceDecl* ClassDecl = this;
553 ObjCMethodDecl *MethodDecl = 0;
554
555 while (ClassDecl != NULL) {
556 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
557 return MethodDecl;
558
559 // Didn't find one yet - look through protocols.
Chris Lattner3db6cae2008-07-21 18:19:38 +0000560 const ObjCList<ObjCProtocolDecl> &Protocols =
561 ClassDecl->getReferencedProtocols();
562
563 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
564 E = Protocols.end(); I != E; ++I) {
565 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000566 return MethodDecl;
567 }
568 // Didn't find one yet - now look through categories.
569 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
570 while (CatDecl) {
571 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
572 return MethodDecl;
573 CatDecl = CatDecl->getNextClassCategory();
574 }
575 ClassDecl = ClassDecl->getSuperClass();
576 }
577 return NULL;
578}
579
580/// lookupInstanceMethod - This method returns an instance method by looking in
581/// the class implementation. Unlike interfaces, we don't look outside the
582/// implementation.
583ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
584 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
585 if ((*I)->getSelector() == Sel)
586 return *I;
587 return NULL;
588}
589
590/// lookupClassMethod - This method returns a class method by looking in
591/// the class implementation. Unlike interfaces, we don't look outside the
592/// implementation.
593ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
594 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
595 I != E; ++I)
596 if ((*I)->getSelector() == Sel)
597 return *I;
598 return NULL;
599}
600
601// lookupInstanceMethod - This method returns an instance method by looking in
602// the class implementation. Unlike interfaces, we don't look outside the
603// implementation.
604ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
605 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
606 if ((*I)->getSelector() == Sel)
607 return *I;
608 return NULL;
609}
610
611// lookupClassMethod - This method returns an instance method by looking in
612// the class implementation. Unlike interfaces, we don't look outside the
613// implementation.
614ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
615 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
616 I != E; ++I)
617 if ((*I)->getSelector() == Sel)
618 return *I;
619 return NULL;
620}
621
622// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
623// it inherited.
624ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
625 ObjCMethodDecl *MethodDecl = NULL;
626
627 if ((MethodDecl = getInstanceMethod(Sel)))
628 return MethodDecl;
629
630 if (getNumReferencedProtocols() > 0) {
631 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
632
633 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
634 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
635 return MethodDecl;
636 }
637 }
638 return NULL;
639}
640
641// lookupInstanceMethod - Lookup a class method in the protocol and protocols
642// it inherited.
643ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
644 ObjCMethodDecl *MethodDecl = NULL;
645
646 if ((MethodDecl = getClassMethod(Sel)))
647 return MethodDecl;
648
649 if (getNumReferencedProtocols() > 0) {
650 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
651
652 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
653 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
654 return MethodDecl;
655 }
656 }
657 return NULL;
658}
659
660/// getSynthesizedMethodSize - Compute size of synthesized method name
661/// as done be the rewrite.
662///
663unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
664 // syntesized method name is a concatenation of -/+[class-name selector]
665 // Get length of this name.
666 unsigned length = 3; // _I_ or _C_
667 length += strlen(getClassInterface()->getName()) +1; // extra for _
668 NamedDecl *MethodContext = getMethodContext();
669 if (ObjCCategoryImplDecl *CID =
670 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
671 length += strlen(CID->getName()) +1;
672 length += getSelector().getName().size(); // selector name
673 return length;
674}
675
Chris Lattner56196882008-04-06 05:25:03 +0000676ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner1e03a562008-03-16 00:19:01 +0000677 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
678 return ID;
679 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
680 return CD->getClassInterface();
681 if (ObjCImplementationDecl *IMD =
Chris Lattner56196882008-04-06 05:25:03 +0000682 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000683 return IMD->getClassInterface();
Chris Lattner56196882008-04-06 05:25:03 +0000684 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000685 return CID->getClassInterface();
686 assert(false && "unknown method context");
687 return 0;
688}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000689
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000690ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
691 SourceLocation atLoc,
692 SourceLocation L,
693 ObjCPropertyDecl *property,
694 PropertyImplKind kind,
695 ObjCIvarDecl *ivar) {
696 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
697 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
698}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000699
Chris Lattner0ed844b2008-04-04 06:12:32 +0000700