blob: a7e878fc24f916547833235afc272b46fc19d530 [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"
Daniel Dunbarde300732008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Chris Lattner10318b82008-03-16 00:19:01 +000017using namespace clang;
18
Chris Lattner114add62008-03-16 00:49:28 +000019//===----------------------------------------------------------------------===//
20// ObjC Decl Allocation/Deallocation Method Implementations
21//===----------------------------------------------------------------------===//
22
Chris Lattnereee57c02008-04-04 06:12:32 +000023ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
24 SourceLocation beginLoc,
Chris Lattner114add62008-03-16 00:49:28 +000025 SourceLocation endLoc,
26 Selector SelInfo, QualType T,
27 Decl *contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000028 bool isInstance,
Chris Lattner114add62008-03-16 00:49:28 +000029 bool isVariadic,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000030 bool isSynthesized,
Chris Lattnerf7355832008-03-16 00:58:16 +000031 ImplementationControl impControl) {
Chris Lattner114add62008-03-16 00:49:28 +000032 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000033 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
34 SelInfo, T, contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000035 isInstance,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000036 isVariadic, isSynthesized, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000037}
Chris Lattner114add62008-03-16 00:49:28 +000038
Ted Kremenek8c945b12008-06-06 16:45:15 +000039ObjCMethodDecl::~ObjCMethodDecl() {
40 delete [] ParamInfo;
Ted Kremenek8c945b12008-06-06 16:45:15 +000041}
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,
Ted Kremenek173dd312008-07-23 18:04:17 +000090 IdentifierInfo *Id, QualType T,
91 AccessControl ac, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000092 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenek173dd312008-07-23 18:04:17 +000093 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000094}
95
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000096
97ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +000098*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000099 IdentifierInfo *Id, QualType T, Expr *BW) {
100 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
Douglas Gregor8acb7272008-12-11 16:49:14 +0000101 return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000102}
103
104void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
105 this->~ObjCAtDefsFieldDecl();
106 C.getAllocator().Deallocate((void *)this);
107}
108
Chris Lattnereee57c02008-04-04 06:12:32 +0000109ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
110 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000111 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +0000112 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner0be08822008-07-21 21:32:27 +0000113 return new (Mem) ObjCProtocolDecl(L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000114}
115
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000116ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000117 delete [] InstanceMethods;
118 delete [] ClassMethods;
119 delete [] PropertyDecl;
120}
121
122void ObjCProtocolDecl::Destroy(ASTContext& C) {
123
124 // Referenced Protocols are not owned, so don't Destroy them.
125
126 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
127 if (*I) (*I)->Destroy(C);
128
129 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
130 if (*I) (*I)->Destroy(C);
131
132 // FIXME: Because there is no clear ownership
133 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
134 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
135
136 Decl::Destroy(C);
137}
138
139
Chris Lattnereee57c02008-04-04 06:12:32 +0000140ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
141 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000142 ObjCInterfaceDecl **Elts, unsigned nElts) {
143 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
144 return new (Mem) ObjCClassDecl(L, Elts, nElts);
145}
146
Ted Kremenekff291622008-06-06 20:11:53 +0000147ObjCClassDecl::~ObjCClassDecl() {
148 delete [] ForwardDecls;
149}
150
151void ObjCClassDecl::Destroy(ASTContext& C) {
152
153 // FIXME: There is no clear ownership policy now for referenced
154 // ObjCInterfaceDecls. Some of them can be forward declarations that
155 // are never later defined (in which case the ObjCClassDecl owns them)
156 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
157 // we should have separate objects for forward declarations and definitions,
158 // obviating this problem. Because of this situation, referenced
159 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
160
161 Decl::Destroy(C);
162}
163
Chris Lattnere29dc832008-03-16 20:34:23 +0000164ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000165ObjCForwardProtocolDecl::Create(ASTContext &C,
166 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000167 ObjCProtocolDecl **Elts, unsigned NumElts) {
168 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
169 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
170}
171
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000172ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
173 delete [] ReferencedProtocols;
174}
175
Chris Lattnereee57c02008-04-04 06:12:32 +0000176ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
177 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000178 IdentifierInfo *Id) {
179 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +0000180 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000181}
182
Chris Lattner1b6de332008-03-16 20:53:07 +0000183ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000184ObjCCategoryImplDecl::Create(ASTContext &C,
185 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000186 ObjCInterfaceDecl *ClassInterface) {
187 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
188 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
189}
190
191ObjCImplementationDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000192ObjCImplementationDecl::Create(ASTContext &C,
193 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000194 IdentifierInfo *Id,
195 ObjCInterfaceDecl *ClassInterface,
196 ObjCInterfaceDecl *SuperDecl) {
197 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
198 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
199}
Chris Lattner10318b82008-03-16 00:19:01 +0000200
Chris Lattner2d1c4312008-03-16 21:17:37 +0000201ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000202ObjCCompatibleAliasDecl::Create(ASTContext &C,
203 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000204 IdentifierInfo *Id,
205 ObjCInterfaceDecl* AliasedClass) {
206 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
207 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
208}
209
Chris Lattnereee57c02008-04-04 06:12:32 +0000210ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000211 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000212 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000213 QualType T,
214 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000215 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000216 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000217}
218
Chris Lattner10318b82008-03-16 00:19:01 +0000219//===----------------------------------------------------------------------===//
220// Objective-C Decl Implementation
221//===----------------------------------------------------------------------===//
222
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000223void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
224 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000225 QualType selfTy;
226 if (isInstance()) {
227 // There may be no interface context due to error in declaration
228 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000229 if (OID) {
230 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000231 selfTy = Context.getPointerType(selfTy);
232 } else {
233 selfTy = Context.getObjCIdType();
234 }
235 } else // we have a factory method.
236 selfTy = Context.getObjCClassType();
237
238 SelfDecl = ImplicitParamDecl::Create(Context, this,
239 SourceLocation(),
240 &Context.Idents.get("self"),
241 selfTy, 0);
242
243 CmdDecl = ImplicitParamDecl::Create(Context, this,
244 SourceLocation(),
245 &Context.Idents.get("_cmd"),
246 Context.getObjCSelType(), 0);
247}
248
Chris Lattner10318b82008-03-16 00:19:01 +0000249void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
250 unsigned NumParams) {
251 assert(ParamInfo == 0 && "Already has param info!");
252
253 // Zero params -> null pointer.
254 if (NumParams) {
255 ParamInfo = new ParmVarDecl*[NumParams];
256 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
257 NumMethodParams = NumParams;
258 }
259}
260
Fariborz Jahanian4739da12008-11-25 21:48:26 +0000261/// isPropertyReadonly - Return true if property is a readonly, by seaching
262/// for the property in the class and in its categories.
263///
264bool ObjCInterfaceDecl::isPropertyReadonly(ObjCPropertyDecl *PDecl) const
265{
266 if (PDecl->isReadOnly()) {
267 // Main class has the property as 'readyonly'. Must search
268 // through the category list to see if the property's
269 // attribute has been over-ridden to 'readwrite'.
270 for (ObjCCategoryDecl *Category = getCategoryList();
271 Category; Category = Category->getNextClassCategory()) {
272 PDecl= Category->FindPropertyDeclaration(PDecl->getIdentifier());
273 if (PDecl && !PDecl->isReadOnly())
274 return false;
275 }
276 return true;
277 }
278 return false;
279}
280
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000281/// FindPropertyDeclaration - Finds declaration of the property given its name
282/// in 'PropertyId' and returns it. It returns 0, if not found.
283///
284ObjCPropertyDecl *
285 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
286 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
287 E = classprop_end(); I != E; ++I) {
288 ObjCPropertyDecl *property = *I;
289 if (property->getIdentifier() == PropertyId)
290 return property;
291 }
Steve Naroff30faf472008-06-04 04:46:04 +0000292 // Look through categories.
293 for (ObjCCategoryDecl *Category = getCategoryList();
294 Category; Category = Category->getNextClassCategory()) {
295 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
296 if (property)
297 return property;
298 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000299 // Look through protocols.
300 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
301 E = protocol_end(); I != E; ++I) {
302 ObjCProtocolDecl *Protocol = *I;
303 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
304 if (property)
305 return property;
306 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000307 if (getSuperClass())
308 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000309 return 0;
310}
311
312/// FindCategoryDeclaration - Finds category declaration in the list of
313/// categories for this class and returns it. Name of the category is passed
314/// in 'CategoryId'. If category not found, return 0;
315///
316ObjCCategoryDecl *
317 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
318 for (ObjCCategoryDecl *Category = getCategoryList();
319 Category; Category = Category->getNextClassCategory())
320 if (Category->getIdentifier() == CategoryId)
321 return Category;
322 return 0;
323}
324
325/// FindIvarDeclaration - Find an Ivar declaration in this class given its
326/// name in 'IvarId'. On failure to find, return 0;
327///
328ObjCIvarDecl *
329 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
330 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
331 IVE = ivar_end(); IVI != IVE; ++IVI) {
332 ObjCIvarDecl* Ivar = (*IVI);
333 if (Ivar->getIdentifier() == IvarId)
334 return Ivar;
335 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000336 if (getSuperClass())
337 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000338 return 0;
339}
340
Fariborz Jahanian624921a2008-12-13 20:28:25 +0000341void ObjCInterfaceDecl::CollectObjCIvars(std::vector<FieldDecl*> &Fields) {
342 ObjCInterfaceDecl *SuperClass = getSuperClass();
343 if (SuperClass)
344 SuperClass->CollectObjCIvars(Fields);
345 for (ObjCInterfaceDecl::ivar_iterator I = ivar_begin(),
346 E = ivar_end(); I != E; ++I) {
347 ObjCIvarDecl *IVDecl = (*I);
Fariborz Jahanian0c067092008-12-16 01:08:35 +0000348 if (!IVDecl->isInvalidDecl())
349 Fields.push_back(cast<FieldDecl>(IVDecl));
Fariborz Jahanian624921a2008-12-13 20:28:25 +0000350 }
351}
352
Chris Lattner10318b82008-03-16 00:19:01 +0000353/// ObjCAddInstanceVariablesToClass - Inserts instance variables
354/// into ObjCInterfaceDecl's fields.
355///
356void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
357 unsigned numIvars,
358 SourceLocation RBrac) {
359 NumIvars = numIvars;
360 if (numIvars) {
361 Ivars = new ObjCIvarDecl*[numIvars];
362 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
363 }
364 setLocEnd(RBrac);
365}
366
Fariborz Jahanian09772392008-12-13 22:20:28 +0000367/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
368/// storage which matches this 'ivar'.
369///
370FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000371 const ObjCIvarDecl *ivar) {
Fariborz Jahanianf7bae352008-12-17 18:25:24 +0000372 /* When a super class's ivar is referenced in the subclass method with no ivar
373 of its own, record for the sub-class is not built yet. Build it lazily
374 here. */
Steve Narofff188f2f2008-12-17 14:13:49 +0000375 if (!RecordForDecl)
376 addRecordToClass(Context);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000377 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
378 DeclarationName Member = ivar->getDeclName();
379 DeclContext::lookup_result Lookup = RecordForDecl->lookup(Context, Member);
380 assert((Lookup.first != Lookup.second) && "field decl not found");
381 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
382 assert(MemberDecl && "field decl not found");
383 return MemberDecl;
384}
385
Fariborz Jahaniancb8e8032008-12-15 21:58:08 +0000386/// addRecordToClass - produces record info. for the class for its
Fariborz Jahanian624921a2008-12-13 20:28:25 +0000387/// ivars and all those inherited.
388///
Fariborz Jahaniancb8e8032008-12-15 21:58:08 +0000389void ObjCInterfaceDecl::addRecordToClass(ASTContext &Context)
Fariborz Jahanian624921a2008-12-13 20:28:25 +0000390{
391 std::vector<FieldDecl*> RecFields;
392 CollectObjCIvars(RecFields);
393 RecordDecl *RD = RecordDecl::Create(Context, TagDecl::TK_struct, 0,
394 getLocation(),
395 getIdentifier());
396 /// FIXME! Can do collection of ivars and adding to the record while
397 /// doing it.
398 for (unsigned int i = 0; i != RecFields.size(); i++) {
Fariborz Jahanian0c067092008-12-16 01:08:35 +0000399 FieldDecl *Field = FieldDecl::Create(Context, RD,
400 RecFields[i]->getLocation(),
Fariborz Jahanian624921a2008-12-13 20:28:25 +0000401 RecFields[i]->getIdentifier(),
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000402 RecFields[i]->getType(),
403 RecFields[i]->getBitWidth(), false, 0);
Fariborz Jahanian624921a2008-12-13 20:28:25 +0000404 RD->addDecl(Context, Field);
405 }
406 RD->completeDefinition(Context);
Fariborz Jahanian138f7bb2008-12-15 18:04:20 +0000407 RecordForDecl = RD;
Fariborz Jahanian624921a2008-12-13 20:28:25 +0000408}
409
Chris Lattner10318b82008-03-16 00:19:01 +0000410/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
411/// Variables (Ivars) relative to what declared in @implementation;s class.
412/// Ivars into ObjCImplementationDecl's fields.
413///
414void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
415 ObjCIvarDecl **ivars, unsigned numIvars) {
416 NumIvars = numIvars;
417 if (numIvars) {
418 Ivars = new ObjCIvarDecl*[numIvars];
419 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
420 }
421}
422
423/// addMethods - Insert instance and methods declarations into
424/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
425///
426void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
427 unsigned numInsMembers,
428 ObjCMethodDecl **clsMethods,
429 unsigned numClsMembers,
430 SourceLocation endLoc) {
431 NumInstanceMethods = numInsMembers;
432 if (numInsMembers) {
433 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
434 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
435 }
436 NumClassMethods = numClsMembers;
437 if (numClsMembers) {
438 ClassMethods = new ObjCMethodDecl*[numClsMembers];
439 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
440 }
441 AtEndLoc = endLoc;
442}
443
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000444/// addProperties - Insert property declaration AST nodes into
445/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000446///
447void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
448 unsigned NumProperties) {
449 if (NumProperties == 0) return;
450
451 NumPropertyDecl = NumProperties;
452 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
453 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
454}
455
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000456/// mergeProperties - Adds properties to the end of list of current properties
457/// for this class.
458
459void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
460 unsigned NumNewProperties) {
461 if (NumNewProperties == 0) return;
462
463 if (PropertyDecl) {
464 ObjCPropertyDecl **newPropertyDecl =
465 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
466 ObjCPropertyDecl **buf = newPropertyDecl;
467 // put back original properties in buffer.
468 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
469 // Add new properties to this buffer.
470 memcpy(buf+NumPropertyDecl, Properties,
471 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes1ee78042008-05-10 10:31:54 +0000472 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000473 PropertyDecl = newPropertyDecl;
474 NumPropertyDecl += NumNewProperties;
475 }
476 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000477 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000478 }
479}
480
Daniel Dunbard01a7022008-08-27 02:09:39 +0000481static void
482addPropertyMethods(Decl *D,
483 ASTContext &Context,
484 ObjCPropertyDecl *property,
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000485 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
486 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
Daniel Dunbare7abcc42008-08-27 05:13:46 +0000487 ObjCMethodDecl *GetterDecl, *SetterDecl = 0;
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000488
489 GetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getGetterName()]);
490 if (!property->isReadOnly())
491 SetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getSetterName()]);
492
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000493 // FIXME: The synthesized property we set here is misleading. We
494 // almost always synthesize these methods unless the user explicitly
495 // provided prototypes (which is odd, but allowed). Sema should be
496 // typechecking that the declarations jive in that situation (which
497 // it is not currently).
498
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000499 // Find the default getter and if one not found, add one.
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000500 if (!GetterDecl) {
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000501 // No instance method of same name as property getter name was found.
502 // Declare a getter method and add it to the list of methods
503 // for this class.
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000504 GetterDecl =
505 ObjCMethodDecl::Create(Context, property->getLocation(),
506 property->getLocation(),
507 property->getGetterName(),
508 property->getType(),
Daniel Dunbard01a7022008-08-27 02:09:39 +0000509 D,
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000510 true, false, true, ObjCMethodDecl::Required);
511 insMethods.push_back(GetterDecl);
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000512 InsMap[property->getGetterName()] = GetterDecl;
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000513 }
Fariborz Jahanian0b7716c2008-12-09 22:43:22 +0000514 else
515 // A user declared getter will be synthesize when @synthesize of
516 // the property with the same name is seen in the @implementation
517 GetterDecl->setIsSynthesized();
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000518 property->setGetterMethodDecl(GetterDecl);
519
Daniel Dunbardb3b4492008-08-26 07:16:44 +0000520 // Skip setter if property is read-only.
521 if (property->isReadOnly())
522 return;
523
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000524 // Find the default setter and if one not found, add one.
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000525 if (!SetterDecl) {
526 // No instance method of same name as property setter name was found.
527 // Declare a setter method and add it to the list of methods
528 // for this class.
529 SetterDecl =
530 ObjCMethodDecl::Create(Context, property->getLocation(),
531 property->getLocation(),
532 property->getSetterName(),
Daniel Dunbar4b8babe2008-08-26 02:53:23 +0000533 Context.VoidTy,
Daniel Dunbard01a7022008-08-27 02:09:39 +0000534 D,
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000535 true, false, true, ObjCMethodDecl::Required);
536 insMethods.push_back(SetterDecl);
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000537 InsMap[property->getSetterName()] = SetterDecl;
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000538 // Invent the arguments for the setter. We don't bother making a
539 // nice name for the argument.
540 ParmVarDecl *Argument = ParmVarDecl::Create(Context,
541 SetterDecl,
542 SourceLocation(),
543 property->getIdentifier(),
544 property->getType(),
545 VarDecl::None,
546 0, 0);
547 SetterDecl->setMethodParams(&Argument, 1);
548 }
Fariborz Jahanian0b7716c2008-12-09 22:43:22 +0000549 else
550 // A user declared setter will be synthesize when @synthesize of
551 // the property with the same name is seen in the @implementation
552 SetterDecl->setIsSynthesized();
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000553 property->setSetterMethodDecl(SetterDecl);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000554}
555
Daniel Dunbard01a7022008-08-27 02:09:39 +0000556/// addPropertyMethods - Goes through list of properties declared in this class
557/// and builds setter/getter method declartions depending on the setter/getter
558/// attributes of the property.
559///
560void ObjCInterfaceDecl::addPropertyMethods(
561 ASTContext &Context,
562 ObjCPropertyDecl *property,
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000563 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
564 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
565 ::addPropertyMethods(this, Context, property, insMethods, InsMap);
Daniel Dunbard01a7022008-08-27 02:09:39 +0000566}
567
568/// addPropertyMethods - Goes through list of properties declared in this class
569/// and builds setter/getter method declartions depending on the setter/getter
570/// attributes of the property.
571///
572void ObjCCategoryDecl::addPropertyMethods(
573 ASTContext &Context,
574 ObjCPropertyDecl *property,
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000575 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
576 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
577 ::addPropertyMethods(this, Context, property, insMethods, InsMap);
Daniel Dunbard01a7022008-08-27 02:09:39 +0000578}
579
Fariborz Jahanianacad6d12008-12-06 23:03:39 +0000580/// mergeProperties - Adds properties to the end of list of current properties
581/// for this category.
582
583void ObjCCategoryDecl::mergeProperties(ObjCPropertyDecl **Properties,
584 unsigned NumNewProperties) {
585 if (NumNewProperties == 0) return;
586
587 if (PropertyDecl) {
588 ObjCPropertyDecl **newPropertyDecl =
589 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
590 ObjCPropertyDecl **buf = newPropertyDecl;
591 // put back original properties in buffer.
592 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
593 // Add new properties to this buffer.
594 memcpy(buf+NumPropertyDecl, Properties,
595 NumNewProperties*sizeof(ObjCPropertyDecl*));
596 delete[] PropertyDecl;
597 PropertyDecl = newPropertyDecl;
598 NumPropertyDecl += NumNewProperties;
599 }
600 else {
601 addProperties(Properties, NumNewProperties);
602 }
603}
604
Daniel Dunbard01a7022008-08-27 02:09:39 +0000605/// addPropertyMethods - Goes through list of properties declared in this class
606/// and builds setter/getter method declartions depending on the setter/getter
607/// attributes of the property.
608///
609void ObjCProtocolDecl::addPropertyMethods(
610 ASTContext &Context,
611 ObjCPropertyDecl *property,
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000612 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
613 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
614 ::addPropertyMethods(this, Context, property, insMethods, InsMap);
Daniel Dunbard01a7022008-08-27 02:09:39 +0000615}
616
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000617/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000618/// ObjCProtocolDecl's PropertyDecl field.
619///
620void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
621 unsigned NumProperties) {
622 if (NumProperties == 0) return;
623
624 NumPropertyDecl = NumProperties;
625 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
626 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
627}
628
629/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000630/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000631///
632void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
633 unsigned NumProperties) {
634 if (NumProperties == 0) return;
635
636 NumPropertyDecl = NumProperties;
637 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
638 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
639}
640
Chris Lattnercffe3662008-03-16 21:23:50 +0000641/// addMethods - Insert instance and methods declarations into
Chris Lattner10318b82008-03-16 00:19:01 +0000642/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
643///
644void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
645 unsigned numInsMembers,
646 ObjCMethodDecl **clsMethods,
647 unsigned numClsMembers,
648 SourceLocation endLoc) {
649 NumInstanceMethods = numInsMembers;
650 if (numInsMembers) {
651 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
652 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
653 }
654 NumClassMethods = numClsMembers;
655 if (numClsMembers) {
656 ClassMethods = new ObjCMethodDecl*[numClsMembers];
657 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
658 }
659 AtEndLoc = endLoc;
660}
661
Chris Lattner321b5d12008-03-16 20:47:45 +0000662
663
Chris Lattner10318b82008-03-16 00:19:01 +0000664/// addMethods - Insert instance and methods declarations into
665/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
666///
667void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
668 unsigned numInsMembers,
669 ObjCMethodDecl **clsMethods,
670 unsigned numClsMembers,
671 SourceLocation endLoc) {
672 NumInstanceMethods = numInsMembers;
673 if (numInsMembers) {
674 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
675 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
676 }
677 NumClassMethods = numClsMembers;
678 if (numClsMembers) {
679 ClassMethods = new ObjCMethodDecl*[numClsMembers];
680 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
681 }
682 AtEndLoc = endLoc;
683}
684
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000685/// FindPropertyDeclaration - Finds declaration of the property given its name
686/// in 'PropertyId' and returns it. It returns 0, if not found.
687///
688ObjCPropertyDecl *
689ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
690 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
691 E = classprop_end(); I != E; ++I) {
692 ObjCPropertyDecl *property = *I;
693 if (property->getIdentifier() == PropertyId)
694 return property;
695 }
696 return 0;
697}
698
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000699/// FindPropertyDeclaration - Finds declaration of the property given its name
700/// in 'PropertyId' and returns it. It returns 0, if not found.
701///
702ObjCPropertyDecl *
703ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
704 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
705 E = classprop_end(); I != E; ++I) {
706 ObjCPropertyDecl *property = *I;
707 if (property->getIdentifier() == PropertyId)
708 return property;
709 }
710 return 0;
711}
712
Chris Lattner10318b82008-03-16 00:19:01 +0000713ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
714 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
715 ObjCInterfaceDecl* ClassDecl = this;
716 while (ClassDecl != NULL) {
717 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
718 I != E; ++I) {
719 if ((*I)->getIdentifier() == ID) {
720 clsDeclared = ClassDecl;
721 return *I;
722 }
723 }
724 ClassDecl = ClassDecl->getSuperClass();
725 }
726 return NULL;
727}
728
729/// lookupInstanceMethod - This method returns an instance method by looking in
730/// the class, its categories, and its super classes (using a linear search).
731ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
732 ObjCInterfaceDecl* ClassDecl = this;
733 ObjCMethodDecl *MethodDecl = 0;
734
735 while (ClassDecl != NULL) {
736 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
737 return MethodDecl;
738
739 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000740 const ObjCList<ObjCProtocolDecl> &Protocols =
741 ClassDecl->getReferencedProtocols();
742 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
743 E = Protocols.end(); I != E; ++I)
744 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000745 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000746
Chris Lattner10318b82008-03-16 00:19:01 +0000747 // Didn't find one yet - now look through categories.
748 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
749 while (CatDecl) {
750 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
751 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000752
753 // Didn't find one yet - look through protocols.
754 const ObjCList<ObjCProtocolDecl> &Protocols =
755 CatDecl->getReferencedProtocols();
756 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
757 E = Protocols.end(); I != E; ++I)
758 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
759 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000760 CatDecl = CatDecl->getNextClassCategory();
761 }
762 ClassDecl = ClassDecl->getSuperClass();
763 }
764 return NULL;
765}
766
767// lookupClassMethod - This method returns a class method by looking in the
768// class, its categories, and its super classes (using a linear search).
769ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
770 ObjCInterfaceDecl* ClassDecl = this;
771 ObjCMethodDecl *MethodDecl = 0;
772
773 while (ClassDecl != NULL) {
774 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
775 return MethodDecl;
776
777 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000778 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
779 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000780 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000781 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000782
Chris Lattner10318b82008-03-16 00:19:01 +0000783 // Didn't find one yet - now look through categories.
784 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
785 while (CatDecl) {
786 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
787 return MethodDecl;
788 CatDecl = CatDecl->getNextClassCategory();
789 }
790 ClassDecl = ClassDecl->getSuperClass();
791 }
792 return NULL;
793}
794
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000795/// getInstanceMethod - This method returns an instance method by
796/// looking in the class implementation. Unlike interfaces, we don't
797/// look outside the implementation.
798ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000799 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
800 if ((*I)->getSelector() == Sel)
801 return *I;
802 return NULL;
803}
804
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000805/// getClassMethod - This method returns a class method by looking in
806/// the class implementation. Unlike interfaces, we don't look outside
807/// the implementation.
808ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000809 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
810 I != E; ++I)
811 if ((*I)->getSelector() == Sel)
812 return *I;
813 return NULL;
814}
815
Fariborz Jahanian68342282008-12-05 22:32:48 +0000816/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
817/// added to the list of those properties @synthesized/@dynamic in this
818/// @implementation block.
819///
820ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
821 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
822 ObjCPropertyImplDecl *PID = *i;
823 if (PID->getPropertyDecl()->getIdentifier() == Id)
824 return PID;
825 }
826 return 0;
827}
828
829/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000830/// properties implemented in this @implementation block and returns the
831/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000832///
833ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
834 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
835 ObjCPropertyImplDecl *PID = *i;
836 if (PID->getPropertyIvarDecl() &&
837 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
838 return PID;
839 }
840 return 0;
841}
842
843/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000844/// properties implemented in this category @implementation block and returns the
845/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000846///
847ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
848 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
849 ObjCPropertyImplDecl *PID = *i;
850 if (PID->getPropertyIvarDecl() &&
851 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
852 return PID;
853 }
854 return 0;
855}
856
857/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
858/// added to the list of those properties @synthesized/@dynamic in this
859/// category @implementation block.
860///
861ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
862 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
863 ObjCPropertyImplDecl *PID = *i;
864 if (PID->getPropertyDecl()->getIdentifier() == Id)
865 return PID;
866 }
867 return 0;
868}
869
Chris Lattner10318b82008-03-16 00:19:01 +0000870// lookupInstanceMethod - This method returns an instance method by looking in
871// the class implementation. Unlike interfaces, we don't look outside the
872// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000873ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000874 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
875 if ((*I)->getSelector() == Sel)
876 return *I;
877 return NULL;
878}
879
880// lookupClassMethod - This method returns an instance method by looking in
881// the class implementation. Unlike interfaces, we don't look outside the
882// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000883ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000884 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
885 I != E; ++I)
886 if ((*I)->getSelector() == Sel)
887 return *I;
888 return NULL;
889}
890
891// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
892// it inherited.
893ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
894 ObjCMethodDecl *MethodDecl = NULL;
895
896 if ((MethodDecl = getInstanceMethod(Sel)))
897 return MethodDecl;
898
Chris Lattner0be08822008-07-21 21:32:27 +0000899 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
900 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
901 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000902 return NULL;
903}
904
905// lookupInstanceMethod - Lookup a class method in the protocol and protocols
906// it inherited.
907ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
908 ObjCMethodDecl *MethodDecl = NULL;
909
910 if ((MethodDecl = getClassMethod(Sel)))
911 return MethodDecl;
912
Chris Lattner0be08822008-07-21 21:32:27 +0000913 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
914 if ((MethodDecl = (*I)->getClassMethod(Sel)))
915 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000916 return NULL;
917}
918
919/// getSynthesizedMethodSize - Compute size of synthesized method name
920/// as done be the rewrite.
921///
922unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
923 // syntesized method name is a concatenation of -/+[class-name selector]
924 // Get length of this name.
925 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000926 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Chris Lattner10318b82008-03-16 00:19:01 +0000927 NamedDecl *MethodContext = getMethodContext();
928 if (ObjCCategoryImplDecl *CID =
929 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000930 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000931 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000932 return length;
933}
934
Chris Lattner052fbcd2008-04-06 05:25:03 +0000935ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000936 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
937 return ID;
938 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
939 return CD->getClassInterface();
940 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000941 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000942 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000943 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000944 return CID->getClassInterface();
945 assert(false && "unknown method context");
946 return 0;
947}
Chris Lattner44859612008-03-17 01:19:02 +0000948
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000949ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
950 SourceLocation atLoc,
951 SourceLocation L,
952 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000953 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000954 ObjCIvarDecl *ivar) {
955 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000956 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000957}
Chris Lattner44859612008-03-17 01:19:02 +0000958
Chris Lattnereee57c02008-04-04 06:12:32 +0000959