blob: ce9379f19c15956555d6132ae0af0beaa4db2797 [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,
Chris Lattner0e77ba02008-03-16 01:15:50 +000055 unsigned numRefProtos,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000056 IdentifierInfo *Id,
57 SourceLocation ClassLoc,
Chris Lattner0e77ba02008-03-16 01:15:50 +000058 bool ForwardDecl, bool isInternal){
59 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000060 return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000061 Id, ClassLoc, ForwardDecl,
Chris Lattner0e77ba02008-03-16 01:15:50 +000062 isInternal);
63}
64
Ted Kremenek8a779312008-06-06 16:45:15 +000065ObjCInterfaceDecl::~ObjCInterfaceDecl() {
66 delete [] Ivars;
67 delete [] InstanceMethods;
68 delete [] ClassMethods;
69 delete [] PropertyDecl;
70 // FIXME: CategoryList?
71}
72
73void ObjCInterfaceDecl::Destroy(ASTContext& C) {
74 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
75 if (*I) (*I)->Destroy(C);
76
77 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
78 if (*I) (*I)->Destroy(C);
79
80 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
81 if (*I) (*I)->Destroy(C);
Ted Kremenek1a726d72008-06-06 17:21:42 +000082
83 // FIXME: Because there is no clear ownership
84 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
85 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
86
Ted Kremenek8a779312008-06-06 16:45:15 +000087 Decl::Destroy(C);
88}
89
90
Chris Lattnerb048c982008-04-06 04:47:34 +000091ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Chris Lattner0e77ba02008-03-16 01:15:50 +000092 IdentifierInfo *Id, QualType T) {
93 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Chris Lattnerb048c982008-04-06 04:47:34 +000094 return new (Mem) ObjCIvarDecl(L, Id, T);
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000095}
96
Chris Lattner0ed844b2008-04-04 06:12:32 +000097ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
98 SourceLocation L,
Chris Lattnercca59d72008-03-16 01:23:04 +000099 unsigned numRefProtos,
Chris Lattnerc8581052008-03-16 20:19:15 +0000100 IdentifierInfo *Id) {
Chris Lattnercca59d72008-03-16 01:23:04 +0000101 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattnerc8581052008-03-16 20:19:15 +0000102 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattnercca59d72008-03-16 01:23:04 +0000103}
104
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000105ObjCProtocolDecl::~ObjCProtocolDecl() {
106 delete [] ReferencedProtocols;
107 delete [] InstanceMethods;
108 delete [] ClassMethods;
109 delete [] PropertyDecl;
110}
111
112void ObjCProtocolDecl::Destroy(ASTContext& C) {
113
114 // Referenced Protocols are not owned, so don't Destroy them.
115
116 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
117 if (*I) (*I)->Destroy(C);
118
119 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
120 if (*I) (*I)->Destroy(C);
121
122 // FIXME: Because there is no clear ownership
123 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
124 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
125
126 Decl::Destroy(C);
127}
128
129
Chris Lattner0ed844b2008-04-04 06:12:32 +0000130ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
131 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000132 ObjCInterfaceDecl **Elts, unsigned nElts) {
133 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
134 return new (Mem) ObjCClassDecl(L, Elts, nElts);
135}
136
Ted Kremenek400d95f2008-06-06 20:11:53 +0000137ObjCClassDecl::~ObjCClassDecl() {
138 delete [] ForwardDecls;
139}
140
141void ObjCClassDecl::Destroy(ASTContext& C) {
142
143 // FIXME: There is no clear ownership policy now for referenced
144 // ObjCInterfaceDecls. Some of them can be forward declarations that
145 // are never later defined (in which case the ObjCClassDecl owns them)
146 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
147 // we should have separate objects for forward declarations and definitions,
148 // obviating this problem. Because of this situation, referenced
149 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
150
151 Decl::Destroy(C);
152}
153
Chris Lattner61f9d412008-03-16 20:34:23 +0000154ObjCForwardProtocolDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000155ObjCForwardProtocolDecl::Create(ASTContext &C,
156 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000157 ObjCProtocolDecl **Elts, unsigned NumElts) {
158 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
159 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
160}
161
Ted Kremenek05ac3ef2008-06-06 21:05:33 +0000162ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
163 delete [] ReferencedProtocols;
164}
165
Chris Lattner0ed844b2008-04-04 06:12:32 +0000166ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
167 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000168 IdentifierInfo *Id) {
169 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner68c82cf2008-03-16 20:47:45 +0000170 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattner61f9d412008-03-16 20:34:23 +0000171}
172
Chris Lattner75c9cae2008-03-16 20:53:07 +0000173ObjCCategoryImplDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000174ObjCCategoryImplDecl::Create(ASTContext &C,
175 SourceLocation L,IdentifierInfo *Id,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000176 ObjCInterfaceDecl *ClassInterface) {
177 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
178 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
179}
180
181ObjCImplementationDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000182ObjCImplementationDecl::Create(ASTContext &C,
183 SourceLocation L,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000184 IdentifierInfo *Id,
185 ObjCInterfaceDecl *ClassInterface,
186 ObjCInterfaceDecl *SuperDecl) {
187 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
188 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
189}
Chris Lattner1e03a562008-03-16 00:19:01 +0000190
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000191ObjCCompatibleAliasDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000192ObjCCompatibleAliasDecl::Create(ASTContext &C,
193 SourceLocation L,
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000194 IdentifierInfo *Id,
195 ObjCInterfaceDecl* AliasedClass) {
196 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
197 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
198}
199
Chris Lattner0ed844b2008-04-04 06:12:32 +0000200ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniandae1a1a2008-04-11 23:40:25 +0000201 SourceLocation L,
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000202 IdentifierInfo *Id,
Fariborz Jahanian46b55e52008-05-05 18:51:55 +0000203 QualType T,
204 PropertyControl propControl) {
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000205 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000206 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000207}
208
Chris Lattner1e03a562008-03-16 00:19:01 +0000209//===----------------------------------------------------------------------===//
210// Objective-C Decl Implementation
211//===----------------------------------------------------------------------===//
212
213void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
214 unsigned NumParams) {
215 assert(ParamInfo == 0 && "Already has param info!");
216
217 // Zero params -> null pointer.
218 if (NumParams) {
219 ParamInfo = new ParmVarDecl*[NumParams];
220 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
221 NumMethodParams = NumParams;
222 }
223}
224
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000225/// FindPropertyDeclaration - Finds declaration of the property given its name
226/// in 'PropertyId' and returns it. It returns 0, if not found.
227///
228ObjCPropertyDecl *
229 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
230 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
231 E = classprop_end(); I != E; ++I) {
232 ObjCPropertyDecl *property = *I;
233 if (property->getIdentifier() == PropertyId)
234 return property;
235 }
Steve Naroff6c930f22008-06-04 04:46:04 +0000236 // Look through categories.
237 for (ObjCCategoryDecl *Category = getCategoryList();
238 Category; Category = Category->getNextClassCategory()) {
239 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
240 if (property)
241 return property;
242 }
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000243 // Look through protocols.
244 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
245 E = protocol_end(); I != E; ++I) {
246 ObjCProtocolDecl *Protocol = *I;
247 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
248 if (property)
249 return property;
250 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000251 if (getSuperClass())
252 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000253 return 0;
254}
255
256/// FindCategoryDeclaration - Finds category declaration in the list of
257/// categories for this class and returns it. Name of the category is passed
258/// in 'CategoryId'. If category not found, return 0;
259///
260ObjCCategoryDecl *
261 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
262 for (ObjCCategoryDecl *Category = getCategoryList();
263 Category; Category = Category->getNextClassCategory())
264 if (Category->getIdentifier() == CategoryId)
265 return Category;
266 return 0;
267}
268
269/// FindIvarDeclaration - Find an Ivar declaration in this class given its
270/// name in 'IvarId'. On failure to find, return 0;
271///
272ObjCIvarDecl *
273 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
274 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
275 IVE = ivar_end(); IVI != IVE; ++IVI) {
276 ObjCIvarDecl* Ivar = (*IVI);
277 if (Ivar->getIdentifier() == IvarId)
278 return Ivar;
279 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000280 if (getSuperClass())
281 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000282 return 0;
283}
284
Chris Lattner1e03a562008-03-16 00:19:01 +0000285/// ObjCAddInstanceVariablesToClass - Inserts instance variables
286/// into ObjCInterfaceDecl's fields.
287///
288void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
289 unsigned numIvars,
290 SourceLocation RBrac) {
291 NumIvars = numIvars;
292 if (numIvars) {
293 Ivars = new ObjCIvarDecl*[numIvars];
294 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
295 }
296 setLocEnd(RBrac);
297}
298
299/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
300/// Variables (Ivars) relative to what declared in @implementation;s class.
301/// Ivars into ObjCImplementationDecl's fields.
302///
303void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
304 ObjCIvarDecl **ivars, unsigned numIvars) {
305 NumIvars = numIvars;
306 if (numIvars) {
307 Ivars = new ObjCIvarDecl*[numIvars];
308 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
309 }
310}
311
312/// addMethods - Insert instance and methods declarations into
313/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
314///
315void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
316 unsigned numInsMembers,
317 ObjCMethodDecl **clsMethods,
318 unsigned numClsMembers,
319 SourceLocation endLoc) {
320 NumInstanceMethods = numInsMembers;
321 if (numInsMembers) {
322 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
323 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
324 }
325 NumClassMethods = numClsMembers;
326 if (numClsMembers) {
327 ClassMethods = new ObjCMethodDecl*[numClsMembers];
328 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
329 }
330 AtEndLoc = endLoc;
331}
332
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000333/// addProperties - Insert property declaration AST nodes into
334/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattner55d13b42008-03-16 21:23:50 +0000335///
336void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
337 unsigned NumProperties) {
338 if (NumProperties == 0) return;
339
340 NumPropertyDecl = NumProperties;
341 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
342 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
343}
344
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000345/// mergeProperties - Adds properties to the end of list of current properties
346/// for this class.
347
348void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
349 unsigned NumNewProperties) {
350 if (NumNewProperties == 0) return;
351
352 if (PropertyDecl) {
353 ObjCPropertyDecl **newPropertyDecl =
354 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
355 ObjCPropertyDecl **buf = newPropertyDecl;
356 // put back original properties in buffer.
357 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
358 // Add new properties to this buffer.
359 memcpy(buf+NumPropertyDecl, Properties,
360 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000361 delete[] PropertyDecl;
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000362 PropertyDecl = newPropertyDecl;
363 NumPropertyDecl += NumNewProperties;
364 }
365 else {
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000366 addProperties(Properties, NumNewProperties);
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000367 }
368}
369
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000370/// addPropertyMethods - Goes through list of properties declared in this class
371/// and builds setter/getter method declartions depending on the setter/getter
372/// attributes of the property.
373///
374void ObjCInterfaceDecl::addPropertyMethods(
375 ASTContext &Context,
376 ObjCPropertyDecl *property,
377 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
378 // Find the default getter and if one not found, add one.
379 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
380 if (GetterDecl) {
381 // An instance method with same name as property getter name found.
382 property->setGetterMethodDecl(GetterDecl);
383 }
384 else {
385 // No instance method of same name as property getter name was found.
386 // Declare a getter method and add it to the list of methods
387 // for this class.
388 QualType resultDeclType = property->getType();
389 ObjCMethodDecl* ObjCMethod =
390 ObjCMethodDecl::Create(Context, property->getLocation(),
391 property->getLocation(),
392 property->getGetterName(), resultDeclType,
393 this, 0,
Fariborz Jahanian46070342008-05-07 20:53:44 +0000394 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000395 property->setGetterMethodDecl(ObjCMethod);
396 insMethods.push_back(ObjCMethod);
397 }
398}
399
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000400/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian3dd4ba42008-04-17 18:25:18 +0000401/// ObjCProtocolDecl's PropertyDecl field.
402///
403void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
404 unsigned NumProperties) {
405 if (NumProperties == 0) return;
406
407 NumPropertyDecl = NumProperties;
408 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
409 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
410}
411
412/// addProperties - Insert property declaration AST nodes into
Fariborz Jahaniand9a3c332008-04-16 21:11:25 +0000413/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000414///
415void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
416 unsigned NumProperties) {
417 if (NumProperties == 0) return;
418
419 NumPropertyDecl = NumProperties;
420 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
421 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
422}
423
Chris Lattner55d13b42008-03-16 21:23:50 +0000424/// addMethods - Insert instance and methods declarations into
Chris Lattner1e03a562008-03-16 00:19:01 +0000425/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
426///
427void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
428 unsigned numInsMembers,
429 ObjCMethodDecl **clsMethods,
430 unsigned numClsMembers,
431 SourceLocation endLoc) {
432 NumInstanceMethods = numInsMembers;
433 if (numInsMembers) {
434 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
435 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
436 }
437 NumClassMethods = numClsMembers;
438 if (numClsMembers) {
439 ClassMethods = new ObjCMethodDecl*[numClsMembers];
440 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
441 }
442 AtEndLoc = endLoc;
443}
444
Chris Lattner68c82cf2008-03-16 20:47:45 +0000445void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
446 unsigned NumRPs) {
447 assert(NumReferencedProtocols == 0 && "Protocol list already set");
448 if (NumRPs == 0) return;
449
450 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
451 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
452 NumReferencedProtocols = NumRPs;
453}
454
455
Chris Lattner1e03a562008-03-16 00:19:01 +0000456/// addMethods - Insert instance and methods declarations into
457/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
458///
459void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
460 unsigned numInsMembers,
461 ObjCMethodDecl **clsMethods,
462 unsigned numClsMembers,
463 SourceLocation endLoc) {
464 NumInstanceMethods = numInsMembers;
465 if (numInsMembers) {
466 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
467 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
468 }
469 NumClassMethods = numClsMembers;
470 if (numClsMembers) {
471 ClassMethods = new ObjCMethodDecl*[numClsMembers];
472 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
473 }
474 AtEndLoc = endLoc;
475}
476
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000477/// FindPropertyDeclaration - Finds declaration of the property given its name
478/// in 'PropertyId' and returns it. It returns 0, if not found.
479///
480ObjCPropertyDecl *
481ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
482 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
483 E = classprop_end(); I != E; ++I) {
484 ObjCPropertyDecl *property = *I;
485 if (property->getIdentifier() == PropertyId)
486 return property;
487 }
488 return 0;
489}
490
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000491/// FindPropertyDeclaration - Finds declaration of the property given its name
492/// in 'PropertyId' and returns it. It returns 0, if not found.
493///
494ObjCPropertyDecl *
495ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
496 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
497 E = classprop_end(); I != E; ++I) {
498 ObjCPropertyDecl *property = *I;
499 if (property->getIdentifier() == PropertyId)
500 return property;
501 }
502 return 0;
503}
504
Chris Lattner1e03a562008-03-16 00:19:01 +0000505ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
506 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
507 ObjCInterfaceDecl* ClassDecl = this;
508 while (ClassDecl != NULL) {
509 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
510 I != E; ++I) {
511 if ((*I)->getIdentifier() == ID) {
512 clsDeclared = ClassDecl;
513 return *I;
514 }
515 }
516 ClassDecl = ClassDecl->getSuperClass();
517 }
518 return NULL;
519}
520
521/// lookupInstanceMethod - This method returns an instance method by looking in
522/// the class, its categories, and its super classes (using a linear search).
523ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
524 ObjCInterfaceDecl* ClassDecl = this;
525 ObjCMethodDecl *MethodDecl = 0;
526
527 while (ClassDecl != NULL) {
528 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
529 return MethodDecl;
530
531 // Didn't find one yet - look through protocols.
532 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
533 int numProtocols = ClassDecl->getNumIntfRefProtocols();
534 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
535 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
536 return MethodDecl;
537 }
538 // Didn't find one yet - now look through categories.
539 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
540 while (CatDecl) {
541 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
542 return MethodDecl;
543 CatDecl = CatDecl->getNextClassCategory();
544 }
545 ClassDecl = ClassDecl->getSuperClass();
546 }
547 return NULL;
548}
549
550// lookupClassMethod - This method returns a class method by looking in the
551// class, its categories, and its super classes (using a linear search).
552ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
553 ObjCInterfaceDecl* ClassDecl = this;
554 ObjCMethodDecl *MethodDecl = 0;
555
556 while (ClassDecl != NULL) {
557 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
558 return MethodDecl;
559
560 // Didn't find one yet - look through protocols.
561 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
562 int numProtocols = ClassDecl->getNumIntfRefProtocols();
563 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
564 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
565 return MethodDecl;
566 }
567 // Didn't find one yet - now look through categories.
568 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
569 while (CatDecl) {
570 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
571 return MethodDecl;
572 CatDecl = CatDecl->getNextClassCategory();
573 }
574 ClassDecl = ClassDecl->getSuperClass();
575 }
576 return NULL;
577}
578
579/// lookupInstanceMethod - This method returns an instance method by looking in
580/// the class implementation. Unlike interfaces, we don't look outside the
581/// implementation.
582ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
583 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
584 if ((*I)->getSelector() == Sel)
585 return *I;
586 return NULL;
587}
588
589/// lookupClassMethod - This method returns a class method by looking in
590/// the class implementation. Unlike interfaces, we don't look outside the
591/// implementation.
592ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
593 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
594 I != E; ++I)
595 if ((*I)->getSelector() == Sel)
596 return *I;
597 return NULL;
598}
599
600// lookupInstanceMethod - This method returns an instance method by looking in
601// the class implementation. Unlike interfaces, we don't look outside the
602// implementation.
603ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
604 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
605 if ((*I)->getSelector() == Sel)
606 return *I;
607 return NULL;
608}
609
610// lookupClassMethod - 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::getClassMethod(Selector Sel) {
614 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
615 I != E; ++I)
616 if ((*I)->getSelector() == Sel)
617 return *I;
618 return NULL;
619}
620
621// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
622// it inherited.
623ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
624 ObjCMethodDecl *MethodDecl = NULL;
625
626 if ((MethodDecl = getInstanceMethod(Sel)))
627 return MethodDecl;
628
629 if (getNumReferencedProtocols() > 0) {
630 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
631
632 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
633 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
634 return MethodDecl;
635 }
636 }
637 return NULL;
638}
639
640// lookupInstanceMethod - Lookup a class method in the protocol and protocols
641// it inherited.
642ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
643 ObjCMethodDecl *MethodDecl = NULL;
644
645 if ((MethodDecl = getClassMethod(Sel)))
646 return MethodDecl;
647
648 if (getNumReferencedProtocols() > 0) {
649 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
650
651 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
652 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
653 return MethodDecl;
654 }
655 }
656 return NULL;
657}
658
659/// getSynthesizedMethodSize - Compute size of synthesized method name
660/// as done be the rewrite.
661///
662unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
663 // syntesized method name is a concatenation of -/+[class-name selector]
664 // Get length of this name.
665 unsigned length = 3; // _I_ or _C_
666 length += strlen(getClassInterface()->getName()) +1; // extra for _
667 NamedDecl *MethodContext = getMethodContext();
668 if (ObjCCategoryImplDecl *CID =
669 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
670 length += strlen(CID->getName()) +1;
671 length += getSelector().getName().size(); // selector name
672 return length;
673}
674
Chris Lattner56196882008-04-06 05:25:03 +0000675ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner1e03a562008-03-16 00:19:01 +0000676 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
677 return ID;
678 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
679 return CD->getClassInterface();
680 if (ObjCImplementationDecl *IMD =
Chris Lattner56196882008-04-06 05:25:03 +0000681 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000682 return IMD->getClassInterface();
Chris Lattner56196882008-04-06 05:25:03 +0000683 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000684 return CID->getClassInterface();
685 assert(false && "unknown method context");
686 return 0;
687}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000688
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000689ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
690 SourceLocation atLoc,
691 SourceLocation L,
692 ObjCPropertyDecl *property,
693 PropertyImplKind kind,
694 ObjCIvarDecl *ivar) {
695 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
696 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
697}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000698
Chris Lattner0ed844b2008-04-04 06:12:32 +0000699