blob: 08df62d5b93a4c8e99d862df63b1ac7326548e83 [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,
Chris Lattner0db541b2008-03-16 01:15:50 +000055 unsigned numRefProtos,
Steve Naroff7c371742008-04-11 19:35:35 +000056 IdentifierInfo *Id,
57 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000058 bool ForwardDecl, bool isInternal){
59 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000060 return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
Steve Naroff7c371742008-04-11 19:35:35 +000061 Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000062 isInternal);
63}
64
Ted Kremenek8c945b12008-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 Kremenek22db1602008-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 Kremenek8c945b12008-06-06 16:45:15 +000087 Decl::Destroy(C);
88}
89
90
Chris Lattnerf3874bc2008-04-06 04:47:34 +000091ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Chris Lattner0db541b2008-03-16 01:15:50 +000092 IdentifierInfo *Id, QualType T) {
93 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Chris Lattnerf3874bc2008-04-06 04:47:34 +000094 return new (Mem) ObjCIvarDecl(L, Id, T);
Chris Lattner114add62008-03-16 00:49:28 +000095}
96
Chris Lattnereee57c02008-04-04 06:12:32 +000097ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
98 SourceLocation L,
Chris Lattner180f7e22008-03-16 01:23:04 +000099 unsigned numRefProtos,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000100 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +0000101 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner7afba9c2008-03-16 20:19:15 +0000102 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000103}
104
Ted Kremenekc906e5e2008-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 Lattnereee57c02008-04-04 06:12:32 +0000130ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
131 SourceLocation L,
Chris Lattnere29dc832008-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 Kremenekff291622008-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 Lattnere29dc832008-03-16 20:34:23 +0000154ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000155ObjCForwardProtocolDecl::Create(ASTContext &C,
156 SourceLocation L,
Chris Lattnere29dc832008-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
Chris Lattnereee57c02008-04-04 06:12:32 +0000162ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
163 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000164 IdentifierInfo *Id) {
165 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +0000166 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000167}
168
Chris Lattner1b6de332008-03-16 20:53:07 +0000169ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000170ObjCCategoryImplDecl::Create(ASTContext &C,
171 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-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 Lattnereee57c02008-04-04 06:12:32 +0000178ObjCImplementationDecl::Create(ASTContext &C,
179 SourceLocation L,
Chris Lattner1b6de332008-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 Lattner10318b82008-03-16 00:19:01 +0000186
Chris Lattner2d1c4312008-03-16 21:17:37 +0000187ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000188ObjCCompatibleAliasDecl::Create(ASTContext &C,
189 SourceLocation L,
Chris Lattner2d1c4312008-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 Lattnereee57c02008-04-04 06:12:32 +0000196ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000197 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000198 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000199 QualType T,
200 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000201 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000202 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000203}
204
Chris Lattner10318b82008-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 Jahanianef8a3df2008-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 Naroff30faf472008-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 Naroffd1f0eb42008-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 Jahanian8acf3352008-04-21 23:57:08 +0000247 if (getSuperClass())
248 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-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 Jahanian8acf3352008-04-21 23:57:08 +0000276 if (getSuperClass())
277 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000278 return 0;
279}
280
Chris Lattner10318b82008-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 Jahanian52ff8442008-04-16 21:08:45 +0000329/// addProperties - Insert property declaration AST nodes into
330/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-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 Jahanian33973a22008-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 Lopes1ee78042008-05-10 10:31:54 +0000357 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000358 PropertyDecl = newPropertyDecl;
359 NumPropertyDecl += NumNewProperties;
360 }
361 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000362 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000363 }
364}
365
Fariborz Jahaniane4534e72008-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 Jahanian5f2e2242008-05-07 20:53:44 +0000390 true, false, true, ObjCMethodDecl::Required);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000391 property->setGetterMethodDecl(ObjCMethod);
392 insMethods.push_back(ObjCMethod);
393 }
394}
395
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000396/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-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 Jahanian5742a0f2008-04-16 21:11:25 +0000409/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-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 Lattnercffe3662008-03-16 21:23:50 +0000420/// addMethods - Insert instance and methods declarations into
Chris Lattner10318b82008-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 Lattner321b5d12008-03-16 20:47:45 +0000441void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
442 unsigned NumRPs) {
443 assert(NumReferencedProtocols == 0 && "Protocol list already set");
444 if (NumRPs == 0) return;
445
446 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
447 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
448 NumReferencedProtocols = NumRPs;
449}
450
451
Chris Lattner10318b82008-03-16 00:19:01 +0000452/// addMethods - Insert instance and methods declarations into
453/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
454///
455void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
456 unsigned numInsMembers,
457 ObjCMethodDecl **clsMethods,
458 unsigned numClsMembers,
459 SourceLocation endLoc) {
460 NumInstanceMethods = numInsMembers;
461 if (numInsMembers) {
462 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
463 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
464 }
465 NumClassMethods = numClsMembers;
466 if (numClsMembers) {
467 ClassMethods = new ObjCMethodDecl*[numClsMembers];
468 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
469 }
470 AtEndLoc = endLoc;
471}
472
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000473/// FindPropertyDeclaration - Finds declaration of the property given its name
474/// in 'PropertyId' and returns it. It returns 0, if not found.
475///
476ObjCPropertyDecl *
477ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
478 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
479 E = classprop_end(); I != E; ++I) {
480 ObjCPropertyDecl *property = *I;
481 if (property->getIdentifier() == PropertyId)
482 return property;
483 }
484 return 0;
485}
486
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000487/// FindPropertyDeclaration - Finds declaration of the property given its name
488/// in 'PropertyId' and returns it. It returns 0, if not found.
489///
490ObjCPropertyDecl *
491ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
492 for (ObjCProtocolDecl::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
Chris Lattner10318b82008-03-16 00:19:01 +0000501ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
502 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
503 ObjCInterfaceDecl* ClassDecl = this;
504 while (ClassDecl != NULL) {
505 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
506 I != E; ++I) {
507 if ((*I)->getIdentifier() == ID) {
508 clsDeclared = ClassDecl;
509 return *I;
510 }
511 }
512 ClassDecl = ClassDecl->getSuperClass();
513 }
514 return NULL;
515}
516
517/// lookupInstanceMethod - This method returns an instance method by looking in
518/// the class, its categories, and its super classes (using a linear search).
519ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
520 ObjCInterfaceDecl* ClassDecl = this;
521 ObjCMethodDecl *MethodDecl = 0;
522
523 while (ClassDecl != NULL) {
524 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
525 return MethodDecl;
526
527 // Didn't find one yet - look through protocols.
528 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
529 int numProtocols = ClassDecl->getNumIntfRefProtocols();
530 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
531 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
532 return MethodDecl;
533 }
534 // Didn't find one yet - now look through categories.
535 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
536 while (CatDecl) {
537 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
538 return MethodDecl;
539 CatDecl = CatDecl->getNextClassCategory();
540 }
541 ClassDecl = ClassDecl->getSuperClass();
542 }
543 return NULL;
544}
545
546// lookupClassMethod - This method returns a class method by looking in the
547// class, its categories, and its super classes (using a linear search).
548ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
549 ObjCInterfaceDecl* ClassDecl = this;
550 ObjCMethodDecl *MethodDecl = 0;
551
552 while (ClassDecl != NULL) {
553 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
554 return MethodDecl;
555
556 // Didn't find one yet - look through protocols.
557 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
558 int numProtocols = ClassDecl->getNumIntfRefProtocols();
559 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
560 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
561 return MethodDecl;
562 }
563 // Didn't find one yet - now look through categories.
564 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
565 while (CatDecl) {
566 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
567 return MethodDecl;
568 CatDecl = CatDecl->getNextClassCategory();
569 }
570 ClassDecl = ClassDecl->getSuperClass();
571 }
572 return NULL;
573}
574
575/// lookupInstanceMethod - This method returns an instance method by looking in
576/// the class implementation. Unlike interfaces, we don't look outside the
577/// implementation.
578ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
579 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
580 if ((*I)->getSelector() == Sel)
581 return *I;
582 return NULL;
583}
584
585/// lookupClassMethod - This method returns a class method by looking in
586/// the class implementation. Unlike interfaces, we don't look outside the
587/// implementation.
588ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
589 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
590 I != E; ++I)
591 if ((*I)->getSelector() == Sel)
592 return *I;
593 return NULL;
594}
595
596// lookupInstanceMethod - This method returns an instance method by looking in
597// the class implementation. Unlike interfaces, we don't look outside the
598// implementation.
599ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
600 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
601 if ((*I)->getSelector() == Sel)
602 return *I;
603 return NULL;
604}
605
606// lookupClassMethod - This method returns an instance method by looking in
607// the class implementation. Unlike interfaces, we don't look outside the
608// implementation.
609ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
610 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
611 I != E; ++I)
612 if ((*I)->getSelector() == Sel)
613 return *I;
614 return NULL;
615}
616
617// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
618// it inherited.
619ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
620 ObjCMethodDecl *MethodDecl = NULL;
621
622 if ((MethodDecl = getInstanceMethod(Sel)))
623 return MethodDecl;
624
625 if (getNumReferencedProtocols() > 0) {
626 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
627
628 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
629 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
630 return MethodDecl;
631 }
632 }
633 return NULL;
634}
635
636// lookupInstanceMethod - Lookup a class method in the protocol and protocols
637// it inherited.
638ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
639 ObjCMethodDecl *MethodDecl = NULL;
640
641 if ((MethodDecl = getClassMethod(Sel)))
642 return MethodDecl;
643
644 if (getNumReferencedProtocols() > 0) {
645 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
646
647 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
648 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
649 return MethodDecl;
650 }
651 }
652 return NULL;
653}
654
655/// getSynthesizedMethodSize - Compute size of synthesized method name
656/// as done be the rewrite.
657///
658unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
659 // syntesized method name is a concatenation of -/+[class-name selector]
660 // Get length of this name.
661 unsigned length = 3; // _I_ or _C_
662 length += strlen(getClassInterface()->getName()) +1; // extra for _
663 NamedDecl *MethodContext = getMethodContext();
664 if (ObjCCategoryImplDecl *CID =
665 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
666 length += strlen(CID->getName()) +1;
667 length += getSelector().getName().size(); // selector name
668 return length;
669}
670
Chris Lattner052fbcd2008-04-06 05:25:03 +0000671ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000672 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
673 return ID;
674 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
675 return CD->getClassInterface();
676 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000677 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000678 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000679 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000680 return CID->getClassInterface();
681 assert(false && "unknown method context");
682 return 0;
683}
Chris Lattner44859612008-03-17 01:19:02 +0000684
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000685ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
686 SourceLocation atLoc,
687 SourceLocation L,
688 ObjCPropertyDecl *property,
689 PropertyImplKind kind,
690 ObjCIvarDecl *ivar) {
691 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
692 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
693}
Chris Lattner44859612008-03-17 01:19:02 +0000694
Chris Lattnereee57c02008-04-04 06:12:32 +0000695