blob: a1011b830e10c5e3eb8b543f33f62ae69bcd652c [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,
Steve Naroffd3354222008-07-16 18:22:22 +000090 IdentifierInfo *Id, QualType T, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000091 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Steve Naroffd3354222008-07-16 18:22:22 +000092 return new (Mem) ObjCIvarDecl(L, Id, T, BW);
Chris Lattner114add62008-03-16 00:49:28 +000093}
94
Chris Lattnereee57c02008-04-04 06:12:32 +000095ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
96 SourceLocation L,
Chris Lattner180f7e22008-03-16 01:23:04 +000097 unsigned numRefProtos,
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 Lattner7afba9c2008-03-16 20:19:15 +0000100 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000101}
102
Ted Kremenekc906e5e2008-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 Lattnereee57c02008-04-04 06:12:32 +0000128ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
129 SourceLocation L,
Chris Lattnere29dc832008-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 Kremenekff291622008-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 Lattnere29dc832008-03-16 20:34:23 +0000152ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000153ObjCForwardProtocolDecl::Create(ASTContext &C,
154 SourceLocation L,
Chris Lattnere29dc832008-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 Kremenek1e5e0bf2008-06-06 21:05:33 +0000160ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
161 delete [] ReferencedProtocols;
162}
163
Chris Lattnereee57c02008-04-04 06:12:32 +0000164ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
165 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000166 IdentifierInfo *Id) {
167 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +0000168 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000169}
170
Chris Lattner1b6de332008-03-16 20:53:07 +0000171ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000172ObjCCategoryImplDecl::Create(ASTContext &C,
173 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-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 Lattnereee57c02008-04-04 06:12:32 +0000180ObjCImplementationDecl::Create(ASTContext &C,
181 SourceLocation L,
Chris Lattner1b6de332008-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 Lattner10318b82008-03-16 00:19:01 +0000188
Chris Lattner2d1c4312008-03-16 21:17:37 +0000189ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000190ObjCCompatibleAliasDecl::Create(ASTContext &C,
191 SourceLocation L,
Chris Lattner2d1c4312008-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 Lattnereee57c02008-04-04 06:12:32 +0000198ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000199 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000200 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000201 QualType T,
202 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000203 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000204 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000205}
206
Chris Lattner10318b82008-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 Jahanianef8a3df2008-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 Naroff30faf472008-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 Naroffd1f0eb42008-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 Jahanian8acf3352008-04-21 23:57:08 +0000249 if (getSuperClass())
250 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-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 Jahanian8acf3352008-04-21 23:57:08 +0000278 if (getSuperClass())
279 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000280 return 0;
281}
282
Chris Lattner5cece462008-07-21 07:06:49 +0000283/// addReferencedProtocols - Set the list of protocols that this interface
284/// implements.
285void ObjCInterfaceDecl::addReferencedProtocols(ObjCProtocolDecl **OID,
286 unsigned numRefProtos) {
287 assert(NumReferencedProtocols == 0 && "refproto already set!");
288 NumReferencedProtocols = numRefProtos;
289 if (numRefProtos) {
290 ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos];
291 memcpy(ReferencedProtocols, OID, numRefProtos*sizeof(ObjCProtocolDecl*));
292 }
293}
294
Chris Lattner10318b82008-03-16 00:19:01 +0000295/// ObjCAddInstanceVariablesToClass - Inserts instance variables
296/// into ObjCInterfaceDecl's fields.
297///
298void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
299 unsigned numIvars,
300 SourceLocation RBrac) {
301 NumIvars = numIvars;
302 if (numIvars) {
303 Ivars = new ObjCIvarDecl*[numIvars];
304 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
305 }
306 setLocEnd(RBrac);
307}
308
309/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
310/// Variables (Ivars) relative to what declared in @implementation;s class.
311/// Ivars into ObjCImplementationDecl's fields.
312///
313void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
314 ObjCIvarDecl **ivars, unsigned numIvars) {
315 NumIvars = numIvars;
316 if (numIvars) {
317 Ivars = new ObjCIvarDecl*[numIvars];
318 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
319 }
320}
321
322/// addMethods - Insert instance and methods declarations into
323/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
324///
325void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
326 unsigned numInsMembers,
327 ObjCMethodDecl **clsMethods,
328 unsigned numClsMembers,
329 SourceLocation endLoc) {
330 NumInstanceMethods = numInsMembers;
331 if (numInsMembers) {
332 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
333 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
334 }
335 NumClassMethods = numClsMembers;
336 if (numClsMembers) {
337 ClassMethods = new ObjCMethodDecl*[numClsMembers];
338 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
339 }
340 AtEndLoc = endLoc;
341}
342
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000343/// addProperties - Insert property declaration AST nodes into
344/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000345///
346void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
347 unsigned NumProperties) {
348 if (NumProperties == 0) return;
349
350 NumPropertyDecl = NumProperties;
351 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
352 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
353}
354
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000355/// mergeProperties - Adds properties to the end of list of current properties
356/// for this class.
357
358void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
359 unsigned NumNewProperties) {
360 if (NumNewProperties == 0) return;
361
362 if (PropertyDecl) {
363 ObjCPropertyDecl **newPropertyDecl =
364 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
365 ObjCPropertyDecl **buf = newPropertyDecl;
366 // put back original properties in buffer.
367 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
368 // Add new properties to this buffer.
369 memcpy(buf+NumPropertyDecl, Properties,
370 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes1ee78042008-05-10 10:31:54 +0000371 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000372 PropertyDecl = newPropertyDecl;
373 NumPropertyDecl += NumNewProperties;
374 }
375 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000376 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000377 }
378}
379
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000380/// addPropertyMethods - Goes through list of properties declared in this class
381/// and builds setter/getter method declartions depending on the setter/getter
382/// attributes of the property.
383///
384void ObjCInterfaceDecl::addPropertyMethods(
385 ASTContext &Context,
386 ObjCPropertyDecl *property,
387 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
388 // Find the default getter and if one not found, add one.
389 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
390 if (GetterDecl) {
391 // An instance method with same name as property getter name found.
392 property->setGetterMethodDecl(GetterDecl);
393 }
394 else {
395 // No instance method of same name as property getter name was found.
396 // Declare a getter method and add it to the list of methods
397 // for this class.
398 QualType resultDeclType = property->getType();
399 ObjCMethodDecl* ObjCMethod =
400 ObjCMethodDecl::Create(Context, property->getLocation(),
401 property->getLocation(),
402 property->getGetterName(), resultDeclType,
403 this, 0,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +0000404 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000405 property->setGetterMethodDecl(ObjCMethod);
406 insMethods.push_back(ObjCMethod);
407 }
408}
409
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000410/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000411/// ObjCProtocolDecl's PropertyDecl field.
412///
413void ObjCProtocolDecl::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
422/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000423/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000424///
425void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
426 unsigned NumProperties) {
427 if (NumProperties == 0) return;
428
429 NumPropertyDecl = NumProperties;
430 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
431 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
432}
433
Chris Lattnercffe3662008-03-16 21:23:50 +0000434/// addMethods - Insert instance and methods declarations into
Chris Lattner10318b82008-03-16 00:19:01 +0000435/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
436///
437void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
438 unsigned numInsMembers,
439 ObjCMethodDecl **clsMethods,
440 unsigned numClsMembers,
441 SourceLocation endLoc) {
442 NumInstanceMethods = numInsMembers;
443 if (numInsMembers) {
444 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
445 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
446 }
447 NumClassMethods = numClsMembers;
448 if (numClsMembers) {
449 ClassMethods = new ObjCMethodDecl*[numClsMembers];
450 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
451 }
452 AtEndLoc = endLoc;
453}
454
Chris Lattner321b5d12008-03-16 20:47:45 +0000455void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
456 unsigned NumRPs) {
457 assert(NumReferencedProtocols == 0 && "Protocol list already set");
458 if (NumRPs == 0) return;
459
460 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
461 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
462 NumReferencedProtocols = NumRPs;
463}
464
465
Chris Lattner10318b82008-03-16 00:19:01 +0000466/// addMethods - Insert instance and methods declarations into
467/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
468///
469void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
470 unsigned numInsMembers,
471 ObjCMethodDecl **clsMethods,
472 unsigned numClsMembers,
473 SourceLocation endLoc) {
474 NumInstanceMethods = numInsMembers;
475 if (numInsMembers) {
476 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
477 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
478 }
479 NumClassMethods = numClsMembers;
480 if (numClsMembers) {
481 ClassMethods = new ObjCMethodDecl*[numClsMembers];
482 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
483 }
484 AtEndLoc = endLoc;
485}
486
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000487/// FindPropertyDeclaration - Finds declaration of the property given its name
488/// in 'PropertyId' and returns it. It returns 0, if not found.
489///
490ObjCPropertyDecl *
491ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
492 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
493 E = classprop_end(); I != E; ++I) {
494 ObjCPropertyDecl *property = *I;
495 if (property->getIdentifier() == PropertyId)
496 return property;
497 }
498 return 0;
499}
500
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000501/// FindPropertyDeclaration - Finds declaration of the property given its name
502/// in 'PropertyId' and returns it. It returns 0, if not found.
503///
504ObjCPropertyDecl *
505ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
506 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
507 E = classprop_end(); I != E; ++I) {
508 ObjCPropertyDecl *property = *I;
509 if (property->getIdentifier() == PropertyId)
510 return property;
511 }
512 return 0;
513}
514
Chris Lattner10318b82008-03-16 00:19:01 +0000515ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
516 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
517 ObjCInterfaceDecl* ClassDecl = this;
518 while (ClassDecl != NULL) {
519 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
520 I != E; ++I) {
521 if ((*I)->getIdentifier() == ID) {
522 clsDeclared = ClassDecl;
523 return *I;
524 }
525 }
526 ClassDecl = ClassDecl->getSuperClass();
527 }
528 return NULL;
529}
530
531/// lookupInstanceMethod - This method returns an instance method by looking in
532/// the class, its categories, and its super classes (using a linear search).
533ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
534 ObjCInterfaceDecl* ClassDecl = this;
535 ObjCMethodDecl *MethodDecl = 0;
536
537 while (ClassDecl != NULL) {
538 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
539 return MethodDecl;
540
541 // Didn't find one yet - look through protocols.
542 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
543 int numProtocols = ClassDecl->getNumIntfRefProtocols();
544 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
545 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
546 return MethodDecl;
547 }
548 // Didn't find one yet - now look through categories.
549 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
550 while (CatDecl) {
551 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
552 return MethodDecl;
553 CatDecl = CatDecl->getNextClassCategory();
554 }
555 ClassDecl = ClassDecl->getSuperClass();
556 }
557 return NULL;
558}
559
560// lookupClassMethod - This method returns a class method by looking in the
561// class, its categories, and its super classes (using a linear search).
562ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
563 ObjCInterfaceDecl* ClassDecl = this;
564 ObjCMethodDecl *MethodDecl = 0;
565
566 while (ClassDecl != NULL) {
567 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
568 return MethodDecl;
569
570 // Didn't find one yet - look through protocols.
571 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
572 int numProtocols = ClassDecl->getNumIntfRefProtocols();
573 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
574 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
575 return MethodDecl;
576 }
577 // Didn't find one yet - now look through categories.
578 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
579 while (CatDecl) {
580 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
581 return MethodDecl;
582 CatDecl = CatDecl->getNextClassCategory();
583 }
584 ClassDecl = ClassDecl->getSuperClass();
585 }
586 return NULL;
587}
588
589/// lookupInstanceMethod - This method returns an instance method by looking in
590/// the class implementation. Unlike interfaces, we don't look outside the
591/// implementation.
592ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
593 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
594 if ((*I)->getSelector() == Sel)
595 return *I;
596 return NULL;
597}
598
599/// lookupClassMethod - This method returns a class method by looking in
600/// the class implementation. Unlike interfaces, we don't look outside the
601/// implementation.
602ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
603 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
604 I != E; ++I)
605 if ((*I)->getSelector() == Sel)
606 return *I;
607 return NULL;
608}
609
610// lookupInstanceMethod - This method returns an instance method by looking in
611// the class implementation. Unlike interfaces, we don't look outside the
612// implementation.
613ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
614 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
615 if ((*I)->getSelector() == Sel)
616 return *I;
617 return NULL;
618}
619
620// lookupClassMethod - This method returns an instance method by looking in
621// the class implementation. Unlike interfaces, we don't look outside the
622// implementation.
623ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
624 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
625 I != E; ++I)
626 if ((*I)->getSelector() == Sel)
627 return *I;
628 return NULL;
629}
630
631// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
632// it inherited.
633ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
634 ObjCMethodDecl *MethodDecl = NULL;
635
636 if ((MethodDecl = getInstanceMethod(Sel)))
637 return MethodDecl;
638
639 if (getNumReferencedProtocols() > 0) {
640 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
641
642 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
643 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
644 return MethodDecl;
645 }
646 }
647 return NULL;
648}
649
650// lookupInstanceMethod - Lookup a class method in the protocol and protocols
651// it inherited.
652ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
653 ObjCMethodDecl *MethodDecl = NULL;
654
655 if ((MethodDecl = getClassMethod(Sel)))
656 return MethodDecl;
657
658 if (getNumReferencedProtocols() > 0) {
659 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
660
661 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
662 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
663 return MethodDecl;
664 }
665 }
666 return NULL;
667}
668
669/// getSynthesizedMethodSize - Compute size of synthesized method name
670/// as done be the rewrite.
671///
672unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
673 // syntesized method name is a concatenation of -/+[class-name selector]
674 // Get length of this name.
675 unsigned length = 3; // _I_ or _C_
676 length += strlen(getClassInterface()->getName()) +1; // extra for _
677 NamedDecl *MethodContext = getMethodContext();
678 if (ObjCCategoryImplDecl *CID =
679 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
680 length += strlen(CID->getName()) +1;
681 length += getSelector().getName().size(); // selector name
682 return length;
683}
684
Chris Lattner052fbcd2008-04-06 05:25:03 +0000685ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000686 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
687 return ID;
688 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
689 return CD->getClassInterface();
690 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000691 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000692 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000693 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000694 return CID->getClassInterface();
695 assert(false && "unknown method context");
696 return 0;
697}
Chris Lattner44859612008-03-17 01:19:02 +0000698
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000699ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
700 SourceLocation atLoc,
701 SourceLocation L,
702 ObjCPropertyDecl *property,
703 PropertyImplKind kind,
704 ObjCIvarDecl *ivar) {
705 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
706 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
707}
Chris Lattner44859612008-03-17 01:19:02 +0000708
Chris Lattnereee57c02008-04-04 06:12:32 +0000709