blob: b7c0cf79b94ceade9c80484a2d9c3059efaa9759 [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,
Steve Naroffab63fd62009-01-08 17:28:14 +000027 DeclContext *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() {
Steve Naroffd9d4d502009-01-07 17:57:40 +000064}
65
66ObjCInterfaceDecl::~ObjCInterfaceDecl() {
67 delete [] Ivars;
Ted Kremenek8c945b12008-06-06 16:45:15 +000068 delete [] PropertyDecl;
69 // FIXME: CategoryList?
70}
71
72void ObjCInterfaceDecl::Destroy(ASTContext& C) {
73 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
74 if (*I) (*I)->Destroy(C);
75
Ted Kremenek788ef0a2009-01-08 20:49:27 +000076 for (method_iterator I=meth_begin(), E=meth_end(); I!=E; ++I)
77 if (*I) const_cast<ObjCMethodDecl*>((*I))->Destroy(C);
Ted Kremenek22db1602008-06-06 17:21:42 +000078
79 // FIXME: Because there is no clear ownership
80 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
81 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
82
Ted Kremenek8c945b12008-06-06 16:45:15 +000083 Decl::Destroy(C);
84}
85
86
Chris Lattnerf3874bc2008-04-06 04:47:34 +000087ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenek173dd312008-07-23 18:04:17 +000088 IdentifierInfo *Id, QualType T,
89 AccessControl ac, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000090 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenek173dd312008-07-23 18:04:17 +000091 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000092}
93
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000094
95ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +000096*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000097 IdentifierInfo *Id, QualType T, Expr *BW) {
98 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
Douglas Gregor8acb7272008-12-11 16:49:14 +000099 return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000100}
101
102void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
103 this->~ObjCAtDefsFieldDecl();
104 C.getAllocator().Deallocate((void *)this);
105}
106
Chris Lattnereee57c02008-04-04 06:12:32 +0000107ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
108 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000109 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +0000110 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner0be08822008-07-21 21:32:27 +0000111 return new (Mem) ObjCProtocolDecl(L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000112}
113
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000114ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000115 delete [] PropertyDecl;
116}
117
118void ObjCProtocolDecl::Destroy(ASTContext& C) {
119
120 // Referenced Protocols are not owned, so don't Destroy them.
121
Ted Kremenek788ef0a2009-01-08 20:49:27 +0000122 for (method_iterator I=meth_begin(), E=meth_end(); I!=E; ++I)
123 if (*I) const_cast<ObjCMethodDecl*>((*I))->Destroy(C);
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000124
125 // FIXME: Because there is no clear ownership
126 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
127 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
128
129 Decl::Destroy(C);
130}
131
132
Chris Lattnereee57c02008-04-04 06:12:32 +0000133ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
134 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000135 ObjCInterfaceDecl **Elts, unsigned nElts) {
136 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
137 return new (Mem) ObjCClassDecl(L, Elts, nElts);
138}
139
Ted Kremenekff291622008-06-06 20:11:53 +0000140ObjCClassDecl::~ObjCClassDecl() {
141 delete [] ForwardDecls;
142}
143
144void ObjCClassDecl::Destroy(ASTContext& C) {
145
146 // FIXME: There is no clear ownership policy now for referenced
147 // ObjCInterfaceDecls. Some of them can be forward declarations that
148 // are never later defined (in which case the ObjCClassDecl owns them)
149 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
150 // we should have separate objects for forward declarations and definitions,
151 // obviating this problem. Because of this situation, referenced
152 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
153
154 Decl::Destroy(C);
155}
156
Chris Lattnere29dc832008-03-16 20:34:23 +0000157ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000158ObjCForwardProtocolDecl::Create(ASTContext &C,
159 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000160 ObjCProtocolDecl **Elts, unsigned NumElts) {
161 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
162 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
163}
164
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000165ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
166 delete [] ReferencedProtocols;
167}
168
Chris Lattnereee57c02008-04-04 06:12:32 +0000169ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
170 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000171 IdentifierInfo *Id) {
172 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +0000173 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000174}
175
Chris Lattner1b6de332008-03-16 20:53:07 +0000176ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000177ObjCCategoryImplDecl::Create(ASTContext &C,
178 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000179 ObjCInterfaceDecl *ClassInterface) {
180 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
181 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
182}
183
184ObjCImplementationDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000185ObjCImplementationDecl::Create(ASTContext &C,
186 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000187 IdentifierInfo *Id,
188 ObjCInterfaceDecl *ClassInterface,
189 ObjCInterfaceDecl *SuperDecl) {
190 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
191 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
192}
Chris Lattner10318b82008-03-16 00:19:01 +0000193
Chris Lattner2d1c4312008-03-16 21:17:37 +0000194ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000195ObjCCompatibleAliasDecl::Create(ASTContext &C,
196 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000197 IdentifierInfo *Id,
198 ObjCInterfaceDecl* AliasedClass) {
199 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
200 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
201}
202
Chris Lattnereee57c02008-04-04 06:12:32 +0000203ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000204 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000205 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000206 QualType T,
207 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000208 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000209 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000210}
211
Chris Lattner10318b82008-03-16 00:19:01 +0000212//===----------------------------------------------------------------------===//
213// Objective-C Decl Implementation
214//===----------------------------------------------------------------------===//
215
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000216void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
217 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000218 QualType selfTy;
219 if (isInstance()) {
220 // There may be no interface context due to error in declaration
221 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000222 if (OID) {
223 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000224 selfTy = Context.getPointerType(selfTy);
225 } else {
226 selfTy = Context.getObjCIdType();
227 }
228 } else // we have a factory method.
229 selfTy = Context.getObjCClassType();
230
231 SelfDecl = ImplicitParamDecl::Create(Context, this,
232 SourceLocation(),
233 &Context.Idents.get("self"),
234 selfTy, 0);
235
236 CmdDecl = ImplicitParamDecl::Create(Context, this,
237 SourceLocation(),
238 &Context.Idents.get("_cmd"),
239 Context.getObjCSelType(), 0);
240}
241
Chris Lattner10318b82008-03-16 00:19:01 +0000242void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
243 unsigned NumParams) {
244 assert(ParamInfo == 0 && "Already has param info!");
245
246 // Zero params -> null pointer.
247 if (NumParams) {
248 ParamInfo = new ParmVarDecl*[NumParams];
249 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
250 NumMethodParams = NumParams;
251 }
252}
253
Fariborz Jahanian4739da12008-11-25 21:48:26 +0000254/// isPropertyReadonly - Return true if property is a readonly, by seaching
255/// for the property in the class and in its categories.
256///
257bool ObjCInterfaceDecl::isPropertyReadonly(ObjCPropertyDecl *PDecl) const
258{
259 if (PDecl->isReadOnly()) {
260 // Main class has the property as 'readyonly'. Must search
261 // through the category list to see if the property's
262 // attribute has been over-ridden to 'readwrite'.
263 for (ObjCCategoryDecl *Category = getCategoryList();
264 Category; Category = Category->getNextClassCategory()) {
265 PDecl= Category->FindPropertyDeclaration(PDecl->getIdentifier());
266 if (PDecl && !PDecl->isReadOnly())
267 return false;
268 }
269 return true;
270 }
271 return false;
272}
273
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000274/// FindPropertyDeclaration - Finds declaration of the property given its name
275/// in 'PropertyId' and returns it. It returns 0, if not found.
276///
277ObjCPropertyDecl *
278 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
279 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
280 E = classprop_end(); I != E; ++I) {
281 ObjCPropertyDecl *property = *I;
282 if (property->getIdentifier() == PropertyId)
283 return property;
284 }
Steve Naroff30faf472008-06-04 04:46:04 +0000285 // Look through categories.
286 for (ObjCCategoryDecl *Category = getCategoryList();
287 Category; Category = Category->getNextClassCategory()) {
288 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
289 if (property)
290 return property;
291 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000292 // Look through protocols.
293 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
294 E = protocol_end(); I != E; ++I) {
295 ObjCProtocolDecl *Protocol = *I;
296 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
297 if (property)
298 return property;
299 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000300 if (getSuperClass())
301 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000302 return 0;
303}
304
305/// FindCategoryDeclaration - Finds category declaration in the list of
306/// categories for this class and returns it. Name of the category is passed
307/// in 'CategoryId'. If category not found, return 0;
308///
309ObjCCategoryDecl *
310 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
311 for (ObjCCategoryDecl *Category = getCategoryList();
312 Category; Category = Category->getNextClassCategory())
313 if (Category->getIdentifier() == CategoryId)
314 return Category;
315 return 0;
316}
317
318/// FindIvarDeclaration - Find an Ivar declaration in this class given its
319/// name in 'IvarId'. On failure to find, return 0;
320///
321ObjCIvarDecl *
322 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
323 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
324 IVE = ivar_end(); IVI != IVE; ++IVI) {
325 ObjCIvarDecl* Ivar = (*IVI);
326 if (Ivar->getIdentifier() == IvarId)
327 return Ivar;
328 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000329 if (getSuperClass())
330 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000331 return 0;
332}
333
Chris Lattner10318b82008-03-16 00:19:01 +0000334/// ObjCAddInstanceVariablesToClass - Inserts instance variables
335/// into ObjCInterfaceDecl's fields.
336///
337void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
338 unsigned numIvars,
339 SourceLocation RBrac) {
340 NumIvars = numIvars;
341 if (numIvars) {
342 Ivars = new ObjCIvarDecl*[numIvars];
343 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
344 }
345 setLocEnd(RBrac);
346}
347
Fariborz Jahanian09772392008-12-13 22:20:28 +0000348/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
349/// storage which matches this 'ivar'.
350///
351FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000352 const ObjCIvarDecl *ivar) {
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000353 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000354 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
355 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000356 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroffab63fd62009-01-08 17:28:14 +0000357 ->lookup(Member);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000358 assert((Lookup.first != Lookup.second) && "field decl not found");
359 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
360 assert(MemberDecl && "field decl not found");
361 return MemberDecl;
362}
363
Chris Lattner10318b82008-03-16 00:19:01 +0000364/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
365/// Variables (Ivars) relative to what declared in @implementation;s class.
366/// Ivars into ObjCImplementationDecl's fields.
367///
368void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
369 ObjCIvarDecl **ivars, unsigned numIvars) {
370 NumIvars = numIvars;
371 if (numIvars) {
372 Ivars = new ObjCIvarDecl*[numIvars];
373 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
374 }
375}
376
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000377/// addProperties - Insert property declaration AST nodes into
378/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000379///
380void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
381 unsigned NumProperties) {
382 if (NumProperties == 0) return;
383
384 NumPropertyDecl = NumProperties;
385 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
386 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
387}
388
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000389/// mergeProperties - Adds properties to the end of list of current properties
390/// for this class.
391
392void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
393 unsigned NumNewProperties) {
394 if (NumNewProperties == 0) return;
395
396 if (PropertyDecl) {
397 ObjCPropertyDecl **newPropertyDecl =
398 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
399 ObjCPropertyDecl **buf = newPropertyDecl;
400 // put back original properties in buffer.
401 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
402 // Add new properties to this buffer.
403 memcpy(buf+NumPropertyDecl, Properties,
404 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes1ee78042008-05-10 10:31:54 +0000405 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000406 PropertyDecl = newPropertyDecl;
407 NumPropertyDecl += NumNewProperties;
408 }
409 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000410 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000411 }
412}
413
Steve Naroffab63fd62009-01-08 17:28:14 +0000414// Get the local instance method declared in this interface.
415// FIXME: handle overloading, instance & class methods can have the same name.
416ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
417 lookup_const_result MethodResult = lookup(Sel);
418 if (MethodResult.first)
419 return const_cast<ObjCMethodDecl*>(
420 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
421 return 0;
422}
423
424// Get the local class method declared in this interface.
425ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
426 lookup_const_result MethodResult = lookup(Sel);
427 if (MethodResult.first)
428 return const_cast<ObjCMethodDecl*>(
429 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
430 return 0;
431}
432
433unsigned ObjCContainerDecl::getNumInstanceMethods() const {
434 unsigned sum = 0;
435 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
436 sum++;
437 return sum;
438}
439unsigned ObjCContainerDecl::getNumClassMethods() const {
440 unsigned sum = 0;
441 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
442 sum++;
443 return sum;
444}
445
Fariborz Jahanianacad6d12008-12-06 23:03:39 +0000446/// mergeProperties - Adds properties to the end of list of current properties
447/// for this category.
448
449void ObjCCategoryDecl::mergeProperties(ObjCPropertyDecl **Properties,
450 unsigned NumNewProperties) {
451 if (NumNewProperties == 0) return;
452
453 if (PropertyDecl) {
454 ObjCPropertyDecl **newPropertyDecl =
455 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
456 ObjCPropertyDecl **buf = newPropertyDecl;
457 // put back original properties in buffer.
458 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
459 // Add new properties to this buffer.
460 memcpy(buf+NumPropertyDecl, Properties,
461 NumNewProperties*sizeof(ObjCPropertyDecl*));
462 delete[] PropertyDecl;
463 PropertyDecl = newPropertyDecl;
464 NumPropertyDecl += NumNewProperties;
465 }
466 else {
467 addProperties(Properties, NumNewProperties);
468 }
469}
470
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000471/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000472/// ObjCProtocolDecl's PropertyDecl field.
473///
474void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
475 unsigned NumProperties) {
476 if (NumProperties == 0) return;
477
478 NumPropertyDecl = NumProperties;
479 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
480 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
481}
482
483/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000484/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000485///
486void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
487 unsigned NumProperties) {
488 if (NumProperties == 0) return;
489
490 NumPropertyDecl = NumProperties;
491 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
492 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
493}
494
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000495/// FindPropertyDeclaration - Finds declaration of the property given its name
496/// in 'PropertyId' and returns it. It returns 0, if not found.
497///
498ObjCPropertyDecl *
499ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
500 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
501 E = classprop_end(); I != E; ++I) {
502 ObjCPropertyDecl *property = *I;
503 if (property->getIdentifier() == PropertyId)
504 return property;
505 }
506 return 0;
507}
508
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000509/// FindPropertyDeclaration - Finds declaration of the property given its name
510/// in 'PropertyId' and returns it. It returns 0, if not found.
511///
512ObjCPropertyDecl *
513ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
514 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
515 E = classprop_end(); I != E; ++I) {
516 ObjCPropertyDecl *property = *I;
517 if (property->getIdentifier() == PropertyId)
518 return property;
519 }
520 return 0;
521}
522
Chris Lattner10318b82008-03-16 00:19:01 +0000523ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
524 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
525 ObjCInterfaceDecl* ClassDecl = this;
526 while (ClassDecl != NULL) {
527 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
528 I != E; ++I) {
529 if ((*I)->getIdentifier() == ID) {
530 clsDeclared = ClassDecl;
531 return *I;
532 }
533 }
534 ClassDecl = ClassDecl->getSuperClass();
535 }
536 return NULL;
537}
538
539/// lookupInstanceMethod - This method returns an instance method by looking in
540/// the class, its categories, and its super classes (using a linear search).
541ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
542 ObjCInterfaceDecl* ClassDecl = this;
543 ObjCMethodDecl *MethodDecl = 0;
544
545 while (ClassDecl != NULL) {
546 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
547 return MethodDecl;
548
549 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000550 const ObjCList<ObjCProtocolDecl> &Protocols =
551 ClassDecl->getReferencedProtocols();
552 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
553 E = Protocols.end(); I != E; ++I)
554 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000555 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000556
Chris Lattner10318b82008-03-16 00:19:01 +0000557 // Didn't find one yet - now look through categories.
558 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
559 while (CatDecl) {
560 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
561 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000562
563 // Didn't find one yet - look through protocols.
564 const ObjCList<ObjCProtocolDecl> &Protocols =
565 CatDecl->getReferencedProtocols();
566 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
567 E = Protocols.end(); I != E; ++I)
568 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
569 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000570 CatDecl = CatDecl->getNextClassCategory();
571 }
572 ClassDecl = ClassDecl->getSuperClass();
573 }
574 return NULL;
575}
576
577// lookupClassMethod - This method returns a class method by looking in the
578// class, its categories, and its super classes (using a linear search).
579ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
580 ObjCInterfaceDecl* ClassDecl = this;
581 ObjCMethodDecl *MethodDecl = 0;
582
583 while (ClassDecl != NULL) {
584 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
585 return MethodDecl;
586
587 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000588 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
589 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000590 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000591 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000592
Chris Lattner10318b82008-03-16 00:19:01 +0000593 // Didn't find one yet - now look through categories.
594 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
595 while (CatDecl) {
596 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
597 return MethodDecl;
598 CatDecl = CatDecl->getNextClassCategory();
599 }
600 ClassDecl = ClassDecl->getSuperClass();
601 }
602 return NULL;
603}
604
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000605/// getInstanceMethod - This method returns an instance method by
606/// looking in the class implementation. Unlike interfaces, we don't
607/// look outside the implementation.
608ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000609 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
610 if ((*I)->getSelector() == Sel)
611 return *I;
612 return NULL;
613}
614
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000615/// getClassMethod - This method returns a class method by looking in
616/// the class implementation. Unlike interfaces, we don't look outside
617/// the implementation.
618ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000619 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
620 I != E; ++I)
621 if ((*I)->getSelector() == Sel)
622 return *I;
623 return NULL;
624}
625
Fariborz Jahanian68342282008-12-05 22:32:48 +0000626/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
627/// added to the list of those properties @synthesized/@dynamic in this
628/// @implementation block.
629///
630ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
631 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
632 ObjCPropertyImplDecl *PID = *i;
633 if (PID->getPropertyDecl()->getIdentifier() == Id)
634 return PID;
635 }
636 return 0;
637}
638
639/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000640/// properties implemented in this @implementation block and returns the
641/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000642///
643ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
644 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
645 ObjCPropertyImplDecl *PID = *i;
646 if (PID->getPropertyIvarDecl() &&
647 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
648 return PID;
649 }
650 return 0;
651}
652
653/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000654/// properties implemented in this category @implementation block and returns the
655/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000656///
657ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
658 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
659 ObjCPropertyImplDecl *PID = *i;
660 if (PID->getPropertyIvarDecl() &&
661 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
662 return PID;
663 }
664 return 0;
665}
666
667/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
668/// added to the list of those properties @synthesized/@dynamic in this
669/// category @implementation block.
670///
671ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
672 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
673 ObjCPropertyImplDecl *PID = *i;
674 if (PID->getPropertyDecl()->getIdentifier() == Id)
675 return PID;
676 }
677 return 0;
678}
679
Chris Lattner10318b82008-03-16 00:19:01 +0000680// lookupInstanceMethod - This method returns an instance method by looking in
681// the class implementation. Unlike interfaces, we don't look outside the
682// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000683ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000684 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
685 if ((*I)->getSelector() == Sel)
686 return *I;
687 return NULL;
688}
689
690// lookupClassMethod - This method returns an instance method by looking in
691// the class implementation. Unlike interfaces, we don't look outside the
692// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000693ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000694 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
695 I != E; ++I)
696 if ((*I)->getSelector() == Sel)
697 return *I;
698 return NULL;
699}
700
701// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
702// it inherited.
703ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
704 ObjCMethodDecl *MethodDecl = NULL;
705
706 if ((MethodDecl = getInstanceMethod(Sel)))
707 return MethodDecl;
708
Chris Lattner0be08822008-07-21 21:32:27 +0000709 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000710 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000711 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000712 return NULL;
713}
714
715// lookupInstanceMethod - Lookup a class method in the protocol and protocols
716// it inherited.
717ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
718 ObjCMethodDecl *MethodDecl = NULL;
719
720 if ((MethodDecl = getClassMethod(Sel)))
721 return MethodDecl;
722
Chris Lattner0be08822008-07-21 21:32:27 +0000723 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000724 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000725 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000726 return NULL;
727}
728
729/// getSynthesizedMethodSize - Compute size of synthesized method name
730/// as done be the rewrite.
731///
732unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
733 // syntesized method name is a concatenation of -/+[class-name selector]
734 // Get length of this name.
735 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000736 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff438be772009-01-08 19:41:02 +0000737 if (const ObjCCategoryImplDecl *CID =
738 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000739 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000740 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000741 return length;
742}
743
Chris Lattner052fbcd2008-04-06 05:25:03 +0000744ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff438be772009-01-08 19:41:02 +0000745 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000746 return ID;
Steve Naroff438be772009-01-08 19:41:02 +0000747 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000748 return CD->getClassInterface();
749 if (ObjCImplementationDecl *IMD =
Steve Naroff438be772009-01-08 19:41:02 +0000750 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000751 return IMD->getClassInterface();
Steve Naroff438be772009-01-08 19:41:02 +0000752 if (ObjCCategoryImplDecl *CID =
753 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000754 return CID->getClassInterface();
755 assert(false && "unknown method context");
756 return 0;
757}
Chris Lattner44859612008-03-17 01:19:02 +0000758
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000759ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
760 SourceLocation atLoc,
761 SourceLocation L,
762 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000763 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000764 ObjCIvarDecl *ivar) {
765 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000766 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000767}
Chris Lattner44859612008-03-17 01:19:02 +0000768
Chris Lattnereee57c02008-04-04 06:12:32 +0000769