blob: 2bfad5a7be6724d610baf6c900d3a768ab542c2c [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
Steve Naroffd9d4d502009-01-07 17:57:40 +000063ObjCContainerDecl::~ObjCContainerDecl() {
Ted Kremenek8c945b12008-06-06 16:45:15 +000064 delete [] InstanceMethods;
65 delete [] ClassMethods;
Steve Naroffd9d4d502009-01-07 17:57:40 +000066}
67
68ObjCInterfaceDecl::~ObjCInterfaceDecl() {
69 delete [] Ivars;
Ted Kremenek8c945b12008-06-06 16:45:15 +000070 delete [] PropertyDecl;
71 // FIXME: CategoryList?
72}
73
74void ObjCInterfaceDecl::Destroy(ASTContext& C) {
75 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
76 if (*I) (*I)->Destroy(C);
77
78 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
79 if (*I) (*I)->Destroy(C);
80
81 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
82 if (*I) (*I)->Destroy(C);
Ted Kremenek22db1602008-06-06 17:21:42 +000083
84 // FIXME: Because there is no clear ownership
85 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
86 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
87
Ted Kremenek8c945b12008-06-06 16:45:15 +000088 Decl::Destroy(C);
89}
90
91
Chris Lattnerf3874bc2008-04-06 04:47:34 +000092ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenek173dd312008-07-23 18:04:17 +000093 IdentifierInfo *Id, QualType T,
94 AccessControl ac, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000095 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenek173dd312008-07-23 18:04:17 +000096 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000097}
98
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000099
100ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +0000101*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000102 IdentifierInfo *Id, QualType T, Expr *BW) {
103 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
Douglas Gregor8acb7272008-12-11 16:49:14 +0000104 return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000105}
106
107void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
108 this->~ObjCAtDefsFieldDecl();
109 C.getAllocator().Deallocate((void *)this);
110}
111
Chris Lattnereee57c02008-04-04 06:12:32 +0000112ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
113 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000114 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +0000115 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner0be08822008-07-21 21:32:27 +0000116 return new (Mem) ObjCProtocolDecl(L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000117}
118
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000119ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000120 delete [] PropertyDecl;
121}
122
123void ObjCProtocolDecl::Destroy(ASTContext& C) {
124
125 // Referenced Protocols are not owned, so don't Destroy them.
126
127 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
128 if (*I) (*I)->Destroy(C);
129
130 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
131 if (*I) (*I)->Destroy(C);
132
133 // FIXME: Because there is no clear ownership
134 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
135 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
136
137 Decl::Destroy(C);
138}
139
140
Chris Lattnereee57c02008-04-04 06:12:32 +0000141ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
142 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000143 ObjCInterfaceDecl **Elts, unsigned nElts) {
144 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
145 return new (Mem) ObjCClassDecl(L, Elts, nElts);
146}
147
Ted Kremenekff291622008-06-06 20:11:53 +0000148ObjCClassDecl::~ObjCClassDecl() {
149 delete [] ForwardDecls;
150}
151
152void ObjCClassDecl::Destroy(ASTContext& C) {
153
154 // FIXME: There is no clear ownership policy now for referenced
155 // ObjCInterfaceDecls. Some of them can be forward declarations that
156 // are never later defined (in which case the ObjCClassDecl owns them)
157 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
158 // we should have separate objects for forward declarations and definitions,
159 // obviating this problem. Because of this situation, referenced
160 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
161
162 Decl::Destroy(C);
163}
164
Chris Lattnere29dc832008-03-16 20:34:23 +0000165ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000166ObjCForwardProtocolDecl::Create(ASTContext &C,
167 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000168 ObjCProtocolDecl **Elts, unsigned NumElts) {
169 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
170 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
171}
172
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000173ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
174 delete [] ReferencedProtocols;
175}
176
Chris Lattnereee57c02008-04-04 06:12:32 +0000177ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
178 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000179 IdentifierInfo *Id) {
180 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +0000181 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000182}
183
Chris Lattner1b6de332008-03-16 20:53:07 +0000184ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000185ObjCCategoryImplDecl::Create(ASTContext &C,
186 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000187 ObjCInterfaceDecl *ClassInterface) {
188 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
189 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
190}
191
192ObjCImplementationDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000193ObjCImplementationDecl::Create(ASTContext &C,
194 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000195 IdentifierInfo *Id,
196 ObjCInterfaceDecl *ClassInterface,
197 ObjCInterfaceDecl *SuperDecl) {
198 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
199 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
200}
Chris Lattner10318b82008-03-16 00:19:01 +0000201
Chris Lattner2d1c4312008-03-16 21:17:37 +0000202ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000203ObjCCompatibleAliasDecl::Create(ASTContext &C,
204 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000205 IdentifierInfo *Id,
206 ObjCInterfaceDecl* AliasedClass) {
207 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
208 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
209}
210
Chris Lattnereee57c02008-04-04 06:12:32 +0000211ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000212 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000213 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000214 QualType T,
215 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000216 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000217 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000218}
219
Chris Lattner10318b82008-03-16 00:19:01 +0000220//===----------------------------------------------------------------------===//
221// Objective-C Decl Implementation
222//===----------------------------------------------------------------------===//
223
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000224void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
225 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000226 QualType selfTy;
227 if (isInstance()) {
228 // There may be no interface context due to error in declaration
229 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000230 if (OID) {
231 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000232 selfTy = Context.getPointerType(selfTy);
233 } else {
234 selfTy = Context.getObjCIdType();
235 }
236 } else // we have a factory method.
237 selfTy = Context.getObjCClassType();
238
239 SelfDecl = ImplicitParamDecl::Create(Context, this,
240 SourceLocation(),
241 &Context.Idents.get("self"),
242 selfTy, 0);
243
244 CmdDecl = ImplicitParamDecl::Create(Context, this,
245 SourceLocation(),
246 &Context.Idents.get("_cmd"),
247 Context.getObjCSelType(), 0);
248}
249
Chris Lattner10318b82008-03-16 00:19:01 +0000250void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
251 unsigned NumParams) {
252 assert(ParamInfo == 0 && "Already has param info!");
253
254 // Zero params -> null pointer.
255 if (NumParams) {
256 ParamInfo = new ParmVarDecl*[NumParams];
257 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
258 NumMethodParams = NumParams;
259 }
260}
261
Fariborz Jahanian4739da12008-11-25 21:48:26 +0000262/// isPropertyReadonly - Return true if property is a readonly, by seaching
263/// for the property in the class and in its categories.
264///
265bool ObjCInterfaceDecl::isPropertyReadonly(ObjCPropertyDecl *PDecl) const
266{
267 if (PDecl->isReadOnly()) {
268 // Main class has the property as 'readyonly'. Must search
269 // through the category list to see if the property's
270 // attribute has been over-ridden to 'readwrite'.
271 for (ObjCCategoryDecl *Category = getCategoryList();
272 Category; Category = Category->getNextClassCategory()) {
273 PDecl= Category->FindPropertyDeclaration(PDecl->getIdentifier());
274 if (PDecl && !PDecl->isReadOnly())
275 return false;
276 }
277 return true;
278 }
279 return false;
280}
281
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000282/// FindPropertyDeclaration - Finds declaration of the property given its name
283/// in 'PropertyId' and returns it. It returns 0, if not found.
284///
285ObjCPropertyDecl *
286 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
287 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
288 E = classprop_end(); I != E; ++I) {
289 ObjCPropertyDecl *property = *I;
290 if (property->getIdentifier() == PropertyId)
291 return property;
292 }
Steve Naroff30faf472008-06-04 04:46:04 +0000293 // Look through categories.
294 for (ObjCCategoryDecl *Category = getCategoryList();
295 Category; Category = Category->getNextClassCategory()) {
296 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
297 if (property)
298 return property;
299 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000300 // Look through protocols.
301 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
302 E = protocol_end(); I != E; ++I) {
303 ObjCProtocolDecl *Protocol = *I;
304 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
305 if (property)
306 return property;
307 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000308 if (getSuperClass())
309 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000310 return 0;
311}
312
313/// FindCategoryDeclaration - Finds category declaration in the list of
314/// categories for this class and returns it. Name of the category is passed
315/// in 'CategoryId'. If category not found, return 0;
316///
317ObjCCategoryDecl *
318 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
319 for (ObjCCategoryDecl *Category = getCategoryList();
320 Category; Category = Category->getNextClassCategory())
321 if (Category->getIdentifier() == CategoryId)
322 return Category;
323 return 0;
324}
325
326/// FindIvarDeclaration - Find an Ivar declaration in this class given its
327/// name in 'IvarId'. On failure to find, return 0;
328///
329ObjCIvarDecl *
330 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
331 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
332 IVE = ivar_end(); IVI != IVE; ++IVI) {
333 ObjCIvarDecl* Ivar = (*IVI);
334 if (Ivar->getIdentifier() == IvarId)
335 return Ivar;
336 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000337 if (getSuperClass())
338 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000339 return 0;
340}
341
Chris Lattner10318b82008-03-16 00:19:01 +0000342/// ObjCAddInstanceVariablesToClass - Inserts instance variables
343/// into ObjCInterfaceDecl's fields.
344///
345void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
346 unsigned numIvars,
347 SourceLocation RBrac) {
348 NumIvars = numIvars;
349 if (numIvars) {
350 Ivars = new ObjCIvarDecl*[numIvars];
351 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
352 }
353 setLocEnd(RBrac);
354}
355
Fariborz Jahanian09772392008-12-13 22:20:28 +0000356/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
357/// storage which matches this 'ivar'.
358///
359FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000360 const ObjCIvarDecl *ivar) {
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000361 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000362 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
363 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000364 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
365 ->lookup(Context, Member);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000366 assert((Lookup.first != Lookup.second) && "field decl not found");
367 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
368 assert(MemberDecl && "field decl not found");
369 return MemberDecl;
370}
371
Chris Lattner10318b82008-03-16 00:19:01 +0000372/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
373/// Variables (Ivars) relative to what declared in @implementation;s class.
374/// Ivars into ObjCImplementationDecl's fields.
375///
376void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
377 ObjCIvarDecl **ivars, unsigned numIvars) {
378 NumIvars = numIvars;
379 if (numIvars) {
380 Ivars = new ObjCIvarDecl*[numIvars];
381 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
382 }
383}
384
385/// addMethods - Insert instance and methods declarations into
386/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
387///
Steve Naroffd9d4d502009-01-07 17:57:40 +0000388void ObjCContainerDecl::addMethods(ObjCMethodDecl **insMethods,
Chris Lattner10318b82008-03-16 00:19:01 +0000389 unsigned numInsMembers,
390 ObjCMethodDecl **clsMethods,
391 unsigned numClsMembers,
392 SourceLocation endLoc) {
393 NumInstanceMethods = numInsMembers;
394 if (numInsMembers) {
395 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
396 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
397 }
398 NumClassMethods = numClsMembers;
399 if (numClsMembers) {
400 ClassMethods = new ObjCMethodDecl*[numClsMembers];
401 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
402 }
403 AtEndLoc = endLoc;
404}
405
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000406/// addProperties - Insert property declaration AST nodes into
407/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000408///
409void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
410 unsigned NumProperties) {
411 if (NumProperties == 0) return;
412
413 NumPropertyDecl = NumProperties;
414 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
415 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
416}
417
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000418/// mergeProperties - Adds properties to the end of list of current properties
419/// for this class.
420
421void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
422 unsigned NumNewProperties) {
423 if (NumNewProperties == 0) return;
424
425 if (PropertyDecl) {
426 ObjCPropertyDecl **newPropertyDecl =
427 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
428 ObjCPropertyDecl **buf = newPropertyDecl;
429 // put back original properties in buffer.
430 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
431 // Add new properties to this buffer.
432 memcpy(buf+NumPropertyDecl, Properties,
433 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes1ee78042008-05-10 10:31:54 +0000434 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000435 PropertyDecl = newPropertyDecl;
436 NumPropertyDecl += NumNewProperties;
437 }
438 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000439 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000440 }
441}
442
Daniel Dunbard01a7022008-08-27 02:09:39 +0000443static void
444addPropertyMethods(Decl *D,
445 ASTContext &Context,
446 ObjCPropertyDecl *property,
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000447 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
448 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
Daniel Dunbare7abcc42008-08-27 05:13:46 +0000449 ObjCMethodDecl *GetterDecl, *SetterDecl = 0;
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000450
451 GetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getGetterName()]);
452 if (!property->isReadOnly())
453 SetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getSetterName()]);
454
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000455 // FIXME: The synthesized property we set here is misleading. We
456 // almost always synthesize these methods unless the user explicitly
457 // provided prototypes (which is odd, but allowed). Sema should be
458 // typechecking that the declarations jive in that situation (which
459 // it is not currently).
460
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000461 // Find the default getter and if one not found, add one.
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000462 if (!GetterDecl) {
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000463 // No instance method of same name as property getter name was found.
464 // Declare a getter method and add it to the list of methods
465 // for this class.
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000466 GetterDecl =
467 ObjCMethodDecl::Create(Context, property->getLocation(),
468 property->getLocation(),
469 property->getGetterName(),
470 property->getType(),
Daniel Dunbard01a7022008-08-27 02:09:39 +0000471 D,
Fariborz Jahanian2255ed32008-12-22 20:41:58 +0000472 true, false, true,
473 (property->getPropertyImplementation() ==
474 ObjCPropertyDecl::Optional) ?
475 ObjCMethodDecl::Optional :
476 ObjCMethodDecl::Required);
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000477 insMethods.push_back(GetterDecl);
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000478 InsMap[property->getGetterName()] = GetterDecl;
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000479 }
Fariborz Jahanian0b7716c2008-12-09 22:43:22 +0000480 else
481 // A user declared getter will be synthesize when @synthesize of
482 // the property with the same name is seen in the @implementation
483 GetterDecl->setIsSynthesized();
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000484 property->setGetterMethodDecl(GetterDecl);
485
Daniel Dunbardb3b4492008-08-26 07:16:44 +0000486 // Skip setter if property is read-only.
487 if (property->isReadOnly())
488 return;
489
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000490 // Find the default setter and if one not found, add one.
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000491 if (!SetterDecl) {
492 // No instance method of same name as property setter name was found.
493 // Declare a setter method and add it to the list of methods
494 // for this class.
495 SetterDecl =
496 ObjCMethodDecl::Create(Context, property->getLocation(),
497 property->getLocation(),
498 property->getSetterName(),
Daniel Dunbar4b8babe2008-08-26 02:53:23 +0000499 Context.VoidTy,
Daniel Dunbard01a7022008-08-27 02:09:39 +0000500 D,
Fariborz Jahanian2255ed32008-12-22 20:41:58 +0000501 true, false, true,
502 (property->getPropertyImplementation() ==
503 ObjCPropertyDecl::Optional) ?
504 ObjCMethodDecl::Optional :
505 ObjCMethodDecl::Required);
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000506 insMethods.push_back(SetterDecl);
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000507 InsMap[property->getSetterName()] = SetterDecl;
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000508 // Invent the arguments for the setter. We don't bother making a
509 // nice name for the argument.
510 ParmVarDecl *Argument = ParmVarDecl::Create(Context,
511 SetterDecl,
512 SourceLocation(),
513 property->getIdentifier(),
514 property->getType(),
515 VarDecl::None,
516 0, 0);
517 SetterDecl->setMethodParams(&Argument, 1);
518 }
Fariborz Jahanian0b7716c2008-12-09 22:43:22 +0000519 else
520 // A user declared setter will be synthesize when @synthesize of
521 // the property with the same name is seen in the @implementation
522 SetterDecl->setIsSynthesized();
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000523 property->setSetterMethodDecl(SetterDecl);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000524}
525
Daniel Dunbard01a7022008-08-27 02:09:39 +0000526/// addPropertyMethods - Goes through list of properties declared in this class
527/// and builds setter/getter method declartions depending on the setter/getter
528/// attributes of the property.
529///
530void ObjCInterfaceDecl::addPropertyMethods(
531 ASTContext &Context,
532 ObjCPropertyDecl *property,
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000533 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
534 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
535 ::addPropertyMethods(this, Context, property, insMethods, InsMap);
Daniel Dunbard01a7022008-08-27 02:09:39 +0000536}
537
538/// addPropertyMethods - Goes through list of properties declared in this class
539/// and builds setter/getter method declartions depending on the setter/getter
540/// attributes of the property.
541///
542void ObjCCategoryDecl::addPropertyMethods(
543 ASTContext &Context,
544 ObjCPropertyDecl *property,
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000545 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
546 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
547 ::addPropertyMethods(this, Context, property, insMethods, InsMap);
Daniel Dunbard01a7022008-08-27 02:09:39 +0000548}
549
Fariborz Jahanianacad6d12008-12-06 23:03:39 +0000550/// mergeProperties - Adds properties to the end of list of current properties
551/// for this category.
552
553void ObjCCategoryDecl::mergeProperties(ObjCPropertyDecl **Properties,
554 unsigned NumNewProperties) {
555 if (NumNewProperties == 0) return;
556
557 if (PropertyDecl) {
558 ObjCPropertyDecl **newPropertyDecl =
559 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
560 ObjCPropertyDecl **buf = newPropertyDecl;
561 // put back original properties in buffer.
562 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
563 // Add new properties to this buffer.
564 memcpy(buf+NumPropertyDecl, Properties,
565 NumNewProperties*sizeof(ObjCPropertyDecl*));
566 delete[] PropertyDecl;
567 PropertyDecl = newPropertyDecl;
568 NumPropertyDecl += NumNewProperties;
569 }
570 else {
571 addProperties(Properties, NumNewProperties);
572 }
573}
574
Daniel Dunbard01a7022008-08-27 02:09:39 +0000575/// addPropertyMethods - Goes through list of properties declared in this class
576/// and builds setter/getter method declartions depending on the setter/getter
577/// attributes of the property.
578///
579void ObjCProtocolDecl::addPropertyMethods(
580 ASTContext &Context,
581 ObjCPropertyDecl *property,
Fariborz Jahanianecfbb492008-12-02 00:19:12 +0000582 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
583 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
584 ::addPropertyMethods(this, Context, property, insMethods, InsMap);
Daniel Dunbard01a7022008-08-27 02:09:39 +0000585}
586
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000587/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000588/// ObjCProtocolDecl's PropertyDecl field.
589///
590void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
591 unsigned NumProperties) {
592 if (NumProperties == 0) return;
593
594 NumPropertyDecl = NumProperties;
595 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
596 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
597}
598
599/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000600/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000601///
602void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
603 unsigned NumProperties) {
604 if (NumProperties == 0) return;
605
606 NumPropertyDecl = NumProperties;
607 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
608 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
609}
610
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000611/// FindPropertyDeclaration - Finds declaration of the property given its name
612/// in 'PropertyId' and returns it. It returns 0, if not found.
613///
614ObjCPropertyDecl *
615ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
616 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
617 E = classprop_end(); I != E; ++I) {
618 ObjCPropertyDecl *property = *I;
619 if (property->getIdentifier() == PropertyId)
620 return property;
621 }
622 return 0;
623}
624
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000625/// FindPropertyDeclaration - Finds declaration of the property given its name
626/// in 'PropertyId' and returns it. It returns 0, if not found.
627///
628ObjCPropertyDecl *
629ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
630 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
631 E = classprop_end(); I != E; ++I) {
632 ObjCPropertyDecl *property = *I;
633 if (property->getIdentifier() == PropertyId)
634 return property;
635 }
636 return 0;
637}
638
Chris Lattner10318b82008-03-16 00:19:01 +0000639ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
640 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
641 ObjCInterfaceDecl* ClassDecl = this;
642 while (ClassDecl != NULL) {
643 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
644 I != E; ++I) {
645 if ((*I)->getIdentifier() == ID) {
646 clsDeclared = ClassDecl;
647 return *I;
648 }
649 }
650 ClassDecl = ClassDecl->getSuperClass();
651 }
652 return NULL;
653}
654
655/// lookupInstanceMethod - This method returns an instance method by looking in
656/// the class, its categories, and its super classes (using a linear search).
657ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
658 ObjCInterfaceDecl* ClassDecl = this;
659 ObjCMethodDecl *MethodDecl = 0;
660
661 while (ClassDecl != NULL) {
662 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
663 return MethodDecl;
664
665 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000666 const ObjCList<ObjCProtocolDecl> &Protocols =
667 ClassDecl->getReferencedProtocols();
668 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
669 E = Protocols.end(); I != E; ++I)
670 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000671 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000672
Chris Lattner10318b82008-03-16 00:19:01 +0000673 // Didn't find one yet - now look through categories.
674 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
675 while (CatDecl) {
676 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
677 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000678
679 // Didn't find one yet - look through protocols.
680 const ObjCList<ObjCProtocolDecl> &Protocols =
681 CatDecl->getReferencedProtocols();
682 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
683 E = Protocols.end(); I != E; ++I)
684 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
685 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000686 CatDecl = CatDecl->getNextClassCategory();
687 }
688 ClassDecl = ClassDecl->getSuperClass();
689 }
690 return NULL;
691}
692
693// lookupClassMethod - This method returns a class method by looking in the
694// class, its categories, and its super classes (using a linear search).
695ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
696 ObjCInterfaceDecl* ClassDecl = this;
697 ObjCMethodDecl *MethodDecl = 0;
698
699 while (ClassDecl != NULL) {
700 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
701 return MethodDecl;
702
703 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000704 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
705 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000706 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000707 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000708
Chris Lattner10318b82008-03-16 00:19:01 +0000709 // Didn't find one yet - now look through categories.
710 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
711 while (CatDecl) {
712 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
713 return MethodDecl;
714 CatDecl = CatDecl->getNextClassCategory();
715 }
716 ClassDecl = ClassDecl->getSuperClass();
717 }
718 return NULL;
719}
720
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000721/// getInstanceMethod - This method returns an instance method by
722/// looking in the class implementation. Unlike interfaces, we don't
723/// look outside the implementation.
724ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000725 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
726 if ((*I)->getSelector() == Sel)
727 return *I;
728 return NULL;
729}
730
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000731/// getClassMethod - This method returns a class method by looking in
732/// the class implementation. Unlike interfaces, we don't look outside
733/// the implementation.
734ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000735 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
736 I != E; ++I)
737 if ((*I)->getSelector() == Sel)
738 return *I;
739 return NULL;
740}
741
Fariborz Jahanian68342282008-12-05 22:32:48 +0000742/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
743/// added to the list of those properties @synthesized/@dynamic in this
744/// @implementation block.
745///
746ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
747 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
748 ObjCPropertyImplDecl *PID = *i;
749 if (PID->getPropertyDecl()->getIdentifier() == Id)
750 return PID;
751 }
752 return 0;
753}
754
755/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000756/// properties implemented in this @implementation block and returns the
757/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000758///
759ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
760 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
761 ObjCPropertyImplDecl *PID = *i;
762 if (PID->getPropertyIvarDecl() &&
763 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
764 return PID;
765 }
766 return 0;
767}
768
769/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000770/// properties implemented in this category @implementation block and returns the
771/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000772///
773ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
774 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
775 ObjCPropertyImplDecl *PID = *i;
776 if (PID->getPropertyIvarDecl() &&
777 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
778 return PID;
779 }
780 return 0;
781}
782
783/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
784/// added to the list of those properties @synthesized/@dynamic in this
785/// category @implementation block.
786///
787ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
788 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
789 ObjCPropertyImplDecl *PID = *i;
790 if (PID->getPropertyDecl()->getIdentifier() == Id)
791 return PID;
792 }
793 return 0;
794}
795
Chris Lattner10318b82008-03-16 00:19:01 +0000796// lookupInstanceMethod - This method returns an instance method by looking in
797// the class implementation. Unlike interfaces, we don't look outside the
798// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000799ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000800 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
801 if ((*I)->getSelector() == Sel)
802 return *I;
803 return NULL;
804}
805
806// lookupClassMethod - This method returns an instance method by looking in
807// the class implementation. Unlike interfaces, we don't look outside the
808// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000809ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000810 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
811 I != E; ++I)
812 if ((*I)->getSelector() == Sel)
813 return *I;
814 return NULL;
815}
816
817// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
818// it inherited.
819ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
820 ObjCMethodDecl *MethodDecl = NULL;
821
822 if ((MethodDecl = getInstanceMethod(Sel)))
823 return MethodDecl;
824
Chris Lattner0be08822008-07-21 21:32:27 +0000825 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000826 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000827 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000828 return NULL;
829}
830
831// lookupInstanceMethod - Lookup a class method in the protocol and protocols
832// it inherited.
833ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
834 ObjCMethodDecl *MethodDecl = NULL;
835
836 if ((MethodDecl = getClassMethod(Sel)))
837 return MethodDecl;
838
Chris Lattner0be08822008-07-21 21:32:27 +0000839 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000840 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000841 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000842 return NULL;
843}
844
845/// getSynthesizedMethodSize - Compute size of synthesized method name
846/// as done be the rewrite.
847///
848unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
849 // syntesized method name is a concatenation of -/+[class-name selector]
850 // Get length of this name.
851 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000852 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Chris Lattner10318b82008-03-16 00:19:01 +0000853 NamedDecl *MethodContext = getMethodContext();
854 if (ObjCCategoryImplDecl *CID =
855 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000856 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000857 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000858 return length;
859}
860
Chris Lattner052fbcd2008-04-06 05:25:03 +0000861ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000862 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
863 return ID;
864 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
865 return CD->getClassInterface();
866 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000867 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000868 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000869 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000870 return CID->getClassInterface();
871 assert(false && "unknown method context");
872 return 0;
873}
Chris Lattner44859612008-03-17 01:19:02 +0000874
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000875ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
876 SourceLocation atLoc,
877 SourceLocation L,
878 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000879 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000880 ObjCIvarDecl *ivar) {
881 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000882 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000883}
Chris Lattner44859612008-03-17 01:19:02 +0000884
Chris Lattnereee57c02008-04-04 06:12:32 +0000885