blob: cf3bd0abeaf43288bb293643212001eda1a6ede7 [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,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +000054 DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +000055 SourceLocation atLoc,
Steve Naroff7c371742008-04-11 19:35:35 +000056 IdentifierInfo *Id,
57 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000058 bool ForwardDecl, bool isInternal){
59 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +000060 return new (Mem) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000061 isInternal);
62}
63
Steve Naroffd9d4d502009-01-07 17:57:40 +000064ObjCContainerDecl::~ObjCContainerDecl() {
Steve Naroffd9d4d502009-01-07 17:57:40 +000065}
66
67ObjCInterfaceDecl::~ObjCInterfaceDecl() {
68 delete [] Ivars;
Ted Kremenek8c945b12008-06-06 16:45:15 +000069 delete [] PropertyDecl;
70 // FIXME: CategoryList?
71}
72
73void ObjCInterfaceDecl::Destroy(ASTContext& C) {
74 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
75 if (*I) (*I)->Destroy(C);
76
Ted Kremenek788ef0a2009-01-08 20:49:27 +000077 for (method_iterator I=meth_begin(), E=meth_end(); I!=E; ++I)
78 if (*I) const_cast<ObjCMethodDecl*>((*I))->Destroy(C);
Ted Kremenek22db1602008-06-06 17:21:42 +000079
80 // FIXME: Because there is no clear ownership
81 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
82 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
83
Ted Kremenek8c945b12008-06-06 16:45:15 +000084 Decl::Destroy(C);
85}
86
87
Chris Lattnerf3874bc2008-04-06 04:47:34 +000088ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenek173dd312008-07-23 18:04:17 +000089 IdentifierInfo *Id, QualType T,
90 AccessControl ac, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000091 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenek173dd312008-07-23 18:04:17 +000092 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000093}
94
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000095
96ObjCAtDefsFieldDecl
Douglas Gregor8acb7272008-12-11 16:49:14 +000097*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremeneke5bedfe2008-08-20 03:26:33 +000098 IdentifierInfo *Id, QualType T, Expr *BW) {
99 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
Douglas Gregor8acb7272008-12-11 16:49:14 +0000100 return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremeneke5bedfe2008-08-20 03:26:33 +0000101}
102
103void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
104 this->~ObjCAtDefsFieldDecl();
105 C.getAllocator().Deallocate((void *)this);
106}
107
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000108ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000109 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000110 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +0000111 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000112 return new (Mem) ObjCProtocolDecl(DC, L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000113}
114
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000115ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000116 delete [] PropertyDecl;
117}
118
119void ObjCProtocolDecl::Destroy(ASTContext& C) {
120
121 // Referenced Protocols are not owned, so don't Destroy them.
122
Ted Kremenek788ef0a2009-01-08 20:49:27 +0000123 for (method_iterator I=meth_begin(), E=meth_end(); I!=E; ++I)
124 if (*I) const_cast<ObjCMethodDecl*>((*I))->Destroy(C);
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000125
126 // FIXME: Because there is no clear ownership
127 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
128 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
129
130 Decl::Destroy(C);
131}
132
133
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000134ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000135 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000136 ObjCInterfaceDecl **Elts, unsigned nElts) {
137 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000138 return new (Mem) ObjCClassDecl(DC, L, Elts, nElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000139}
140
Ted Kremenekff291622008-06-06 20:11:53 +0000141ObjCClassDecl::~ObjCClassDecl() {
142 delete [] ForwardDecls;
143}
144
145void ObjCClassDecl::Destroy(ASTContext& C) {
146
147 // FIXME: There is no clear ownership policy now for referenced
148 // ObjCInterfaceDecls. Some of them can be forward declarations that
149 // are never later defined (in which case the ObjCClassDecl owns them)
150 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
151 // we should have separate objects for forward declarations and definitions,
152 // obviating this problem. Because of this situation, referenced
153 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
154
155 Decl::Destroy(C);
156}
157
Chris Lattnere29dc832008-03-16 20:34:23 +0000158ObjCForwardProtocolDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000159ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000160 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000161 ObjCProtocolDecl **Elts, unsigned NumElts) {
162 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000163 return new (Mem) ObjCForwardProtocolDecl(DC, L, Elts, NumElts);
Chris Lattnere29dc832008-03-16 20:34:23 +0000164}
165
Ted Kremenek1e5e0bf2008-06-06 21:05:33 +0000166ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
167 delete [] ReferencedProtocols;
168}
169
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000170ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000171 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000172 IdentifierInfo *Id) {
173 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000174 return new (Mem) ObjCCategoryDecl(DC, L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000175}
176
Chris Lattner1b6de332008-03-16 20:53:07 +0000177ObjCCategoryImplDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000178ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000179 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-03-16 20:53:07 +0000180 ObjCInterfaceDecl *ClassInterface) {
181 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000182 return new (Mem) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
Chris Lattner1b6de332008-03-16 20:53:07 +0000183}
184
185ObjCImplementationDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000186ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000187 SourceLocation L,
Chris Lattner1b6de332008-03-16 20:53:07 +0000188 IdentifierInfo *Id,
189 ObjCInterfaceDecl *ClassInterface,
190 ObjCInterfaceDecl *SuperDecl) {
191 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000192 return new (Mem) ObjCImplementationDecl(DC, L, Id, ClassInterface, SuperDecl);
Chris Lattner1b6de332008-03-16 20:53:07 +0000193}
Chris Lattner10318b82008-03-16 00:19:01 +0000194
Chris Lattner2d1c4312008-03-16 21:17:37 +0000195ObjCCompatibleAliasDecl *
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000196ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
Chris Lattnereee57c02008-04-04 06:12:32 +0000197 SourceLocation L,
Chris Lattner2d1c4312008-03-16 21:17:37 +0000198 IdentifierInfo *Id,
199 ObjCInterfaceDecl* AliasedClass) {
200 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000201 return new (Mem) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000202}
203
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000204ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000205 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000206 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000207 QualType T,
208 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000209 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000210 return new (Mem) ObjCPropertyDecl(DC, L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000211}
212
Chris Lattner10318b82008-03-16 00:19:01 +0000213//===----------------------------------------------------------------------===//
214// Objective-C Decl Implementation
215//===----------------------------------------------------------------------===//
216
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000217void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
218 const ObjCInterfaceDecl *OID) {
Daniel Dunbar88116372008-08-26 06:08:30 +0000219 QualType selfTy;
220 if (isInstance()) {
221 // There may be no interface context due to error in declaration
222 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanian91dd9d32008-12-09 20:23:04 +0000223 if (OID) {
224 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar88116372008-08-26 06:08:30 +0000225 selfTy = Context.getPointerType(selfTy);
226 } else {
227 selfTy = Context.getObjCIdType();
228 }
229 } else // we have a factory method.
230 selfTy = Context.getObjCClassType();
231
232 SelfDecl = ImplicitParamDecl::Create(Context, this,
233 SourceLocation(),
234 &Context.Idents.get("self"),
235 selfTy, 0);
236
237 CmdDecl = ImplicitParamDecl::Create(Context, this,
238 SourceLocation(),
239 &Context.Idents.get("_cmd"),
240 Context.getObjCSelType(), 0);
241}
242
Chris Lattner10318b82008-03-16 00:19:01 +0000243void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
244 unsigned NumParams) {
245 assert(ParamInfo == 0 && "Already has param info!");
246
247 // Zero params -> null pointer.
248 if (NumParams) {
249 ParamInfo = new ParmVarDecl*[NumParams];
250 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
251 NumMethodParams = NumParams;
252 }
253}
254
Daniel Dunbar0a576d52009-01-09 01:04:21 +0000255/// isPropertyReadonly - Return true if property is readonly, by searching
Fariborz Jahanian4739da12008-11-25 21:48:26 +0000256/// for the property in the class and in its categories.
257///
258bool ObjCInterfaceDecl::isPropertyReadonly(ObjCPropertyDecl *PDecl) const
259{
Daniel Dunbar0a576d52009-01-09 01:04:21 +0000260 if (!PDecl->isReadOnly())
261 return false;
262
263 // Main class has the property as 'readonly'. Must search
264 // through the category list to see if the property's
265 // attribute has been over-ridden to 'readwrite'.
266 for (ObjCCategoryDecl *Category = getCategoryList();
267 Category; Category = Category->getNextClassCategory()) {
268 ObjCPropertyDecl *P =
269 Category->FindPropertyDeclaration(PDecl->getIdentifier());
270 if (P && !P->isReadOnly())
271 return false;
Fariborz Jahanian4739da12008-11-25 21:48:26 +0000272 }
Daniel Dunbar0a576d52009-01-09 01:04:21 +0000273
274 return true;
Fariborz Jahanian4739da12008-11-25 21:48:26 +0000275}
276
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000277/// FindPropertyDeclaration - Finds declaration of the property given its name
278/// in 'PropertyId' and returns it. It returns 0, if not found.
279///
280ObjCPropertyDecl *
281 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
282 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
283 E = classprop_end(); I != E; ++I) {
284 ObjCPropertyDecl *property = *I;
285 if (property->getIdentifier() == PropertyId)
286 return property;
287 }
Steve Naroff30faf472008-06-04 04:46:04 +0000288 // Look through categories.
289 for (ObjCCategoryDecl *Category = getCategoryList();
290 Category; Category = Category->getNextClassCategory()) {
291 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
292 if (property)
293 return property;
294 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000295 // Look through protocols.
296 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
297 E = protocol_end(); I != E; ++I) {
298 ObjCProtocolDecl *Protocol = *I;
299 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
300 if (property)
301 return property;
302 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000303 if (getSuperClass())
304 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000305 return 0;
306}
307
308/// FindCategoryDeclaration - Finds category declaration in the list of
309/// categories for this class and returns it. Name of the category is passed
310/// in 'CategoryId'. If category not found, return 0;
311///
312ObjCCategoryDecl *
313 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
314 for (ObjCCategoryDecl *Category = getCategoryList();
315 Category; Category = Category->getNextClassCategory())
316 if (Category->getIdentifier() == CategoryId)
317 return Category;
318 return 0;
319}
320
321/// FindIvarDeclaration - Find an Ivar declaration in this class given its
322/// name in 'IvarId'. On failure to find, return 0;
323///
324ObjCIvarDecl *
325 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
326 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
327 IVE = ivar_end(); IVI != IVE; ++IVI) {
328 ObjCIvarDecl* Ivar = (*IVI);
329 if (Ivar->getIdentifier() == IvarId)
330 return Ivar;
331 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000332 if (getSuperClass())
333 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000334 return 0;
335}
336
Chris Lattner10318b82008-03-16 00:19:01 +0000337/// ObjCAddInstanceVariablesToClass - Inserts instance variables
338/// into ObjCInterfaceDecl's fields.
339///
340void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
341 unsigned numIvars,
342 SourceLocation RBrac) {
343 NumIvars = numIvars;
344 if (numIvars) {
345 Ivars = new ObjCIvarDecl*[numIvars];
346 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
347 }
348 setLocEnd(RBrac);
349}
350
Fariborz Jahanian09772392008-12-13 22:20:28 +0000351/// lookupFieldDeclForIvar - looks up a field decl' in the laid out
352/// storage which matches this 'ivar'.
353///
354FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context,
Fariborz Jahanian86008c02008-12-15 20:35:07 +0000355 const ObjCIvarDecl *ivar) {
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000356 const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000357 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
358 DeclarationName Member = ivar->getDeclName();
Fariborz Jahanian0556b152008-12-17 21:40:49 +0000359 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
Steve Naroffab63fd62009-01-08 17:28:14 +0000360 ->lookup(Member);
Fariborz Jahanian09772392008-12-13 22:20:28 +0000361 assert((Lookup.first != Lookup.second) && "field decl not found");
362 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
363 assert(MemberDecl && "field decl not found");
364 return MemberDecl;
365}
366
Chris Lattner10318b82008-03-16 00:19:01 +0000367/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
368/// Variables (Ivars) relative to what declared in @implementation;s class.
369/// Ivars into ObjCImplementationDecl's fields.
370///
371void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
372 ObjCIvarDecl **ivars, unsigned numIvars) {
373 NumIvars = numIvars;
374 if (numIvars) {
375 Ivars = new ObjCIvarDecl*[numIvars];
376 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
377 }
378}
379
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000380/// addProperties - Insert property declaration AST nodes into
381/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000382///
383void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
384 unsigned NumProperties) {
385 if (NumProperties == 0) return;
386
387 NumPropertyDecl = NumProperties;
388 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
389 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
390}
391
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000392/// mergeProperties - Adds properties to the end of list of current properties
393/// for this class.
394
395void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
396 unsigned NumNewProperties) {
397 if (NumNewProperties == 0) return;
398
399 if (PropertyDecl) {
400 ObjCPropertyDecl **newPropertyDecl =
401 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
402 ObjCPropertyDecl **buf = newPropertyDecl;
403 // put back original properties in buffer.
404 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
405 // Add new properties to this buffer.
406 memcpy(buf+NumPropertyDecl, Properties,
407 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes1ee78042008-05-10 10:31:54 +0000408 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000409 PropertyDecl = newPropertyDecl;
410 NumPropertyDecl += NumNewProperties;
411 }
412 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000413 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000414 }
415}
416
Steve Naroffab63fd62009-01-08 17:28:14 +0000417// Get the local instance method declared in this interface.
418// FIXME: handle overloading, instance & class methods can have the same name.
419ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
420 lookup_const_result MethodResult = lookup(Sel);
421 if (MethodResult.first)
422 return const_cast<ObjCMethodDecl*>(
423 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
424 return 0;
425}
426
427// Get the local class method declared in this interface.
428ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
429 lookup_const_result MethodResult = lookup(Sel);
430 if (MethodResult.first)
431 return const_cast<ObjCMethodDecl*>(
432 dyn_cast<ObjCMethodDecl>(*MethodResult.first));
433 return 0;
434}
435
436unsigned ObjCContainerDecl::getNumInstanceMethods() const {
437 unsigned sum = 0;
438 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
439 sum++;
440 return sum;
441}
442unsigned ObjCContainerDecl::getNumClassMethods() const {
443 unsigned sum = 0;
444 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
445 sum++;
446 return sum;
447}
448
Fariborz Jahanianacad6d12008-12-06 23:03:39 +0000449/// mergeProperties - Adds properties to the end of list of current properties
450/// for this category.
451
452void ObjCCategoryDecl::mergeProperties(ObjCPropertyDecl **Properties,
453 unsigned NumNewProperties) {
454 if (NumNewProperties == 0) return;
455
456 if (PropertyDecl) {
457 ObjCPropertyDecl **newPropertyDecl =
458 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
459 ObjCPropertyDecl **buf = newPropertyDecl;
460 // put back original properties in buffer.
461 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
462 // Add new properties to this buffer.
463 memcpy(buf+NumPropertyDecl, Properties,
464 NumNewProperties*sizeof(ObjCPropertyDecl*));
465 delete[] PropertyDecl;
466 PropertyDecl = newPropertyDecl;
467 NumPropertyDecl += NumNewProperties;
468 }
469 else {
470 addProperties(Properties, NumNewProperties);
471 }
472}
473
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000474/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000475/// ObjCProtocolDecl's PropertyDecl field.
476///
477void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
478 unsigned NumProperties) {
479 if (NumProperties == 0) return;
480
481 NumPropertyDecl = NumProperties;
482 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
483 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
484}
485
486/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000487/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000488///
489void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
490 unsigned NumProperties) {
491 if (NumProperties == 0) return;
492
493 NumPropertyDecl = NumProperties;
494 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
495 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
496}
497
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000498/// FindPropertyDeclaration - Finds declaration of the property given its name
499/// in 'PropertyId' and returns it. It returns 0, if not found.
500///
501ObjCPropertyDecl *
502ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
503 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
504 E = classprop_end(); I != E; ++I) {
505 ObjCPropertyDecl *property = *I;
506 if (property->getIdentifier() == PropertyId)
507 return property;
508 }
509 return 0;
510}
511
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000512/// FindPropertyDeclaration - Finds declaration of the property given its name
513/// in 'PropertyId' and returns it. It returns 0, if not found.
514///
515ObjCPropertyDecl *
516ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
517 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
518 E = classprop_end(); I != E; ++I) {
519 ObjCPropertyDecl *property = *I;
520 if (property->getIdentifier() == PropertyId)
521 return property;
522 }
523 return 0;
524}
525
Chris Lattner10318b82008-03-16 00:19:01 +0000526ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
527 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
528 ObjCInterfaceDecl* ClassDecl = this;
529 while (ClassDecl != NULL) {
530 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
531 I != E; ++I) {
532 if ((*I)->getIdentifier() == ID) {
533 clsDeclared = ClassDecl;
534 return *I;
535 }
536 }
537 ClassDecl = ClassDecl->getSuperClass();
538 }
539 return NULL;
540}
541
542/// lookupInstanceMethod - This method returns an instance method by looking in
543/// the class, its categories, and its super classes (using a linear search).
544ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
545 ObjCInterfaceDecl* ClassDecl = this;
546 ObjCMethodDecl *MethodDecl = 0;
547
548 while (ClassDecl != NULL) {
549 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
550 return MethodDecl;
551
552 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000553 const ObjCList<ObjCProtocolDecl> &Protocols =
554 ClassDecl->getReferencedProtocols();
555 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
556 E = Protocols.end(); I != E; ++I)
557 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000558 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000559
Chris Lattner10318b82008-03-16 00:19:01 +0000560 // Didn't find one yet - now look through categories.
561 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
562 while (CatDecl) {
563 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
564 return MethodDecl;
Steve Naroffaf151802008-12-08 20:57:28 +0000565
566 // Didn't find one yet - look through protocols.
567 const ObjCList<ObjCProtocolDecl> &Protocols =
568 CatDecl->getReferencedProtocols();
569 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
570 E = Protocols.end(); I != E; ++I)
571 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
572 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000573 CatDecl = CatDecl->getNextClassCategory();
574 }
575 ClassDecl = ClassDecl->getSuperClass();
576 }
577 return NULL;
578}
579
580// lookupClassMethod - This method returns a class method by looking in the
581// class, its categories, and its super classes (using a linear search).
582ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
583 ObjCInterfaceDecl* ClassDecl = this;
584 ObjCMethodDecl *MethodDecl = 0;
585
586 while (ClassDecl != NULL) {
587 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
588 return MethodDecl;
589
590 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000591 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
592 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000593 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000594 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000595
Chris Lattner10318b82008-03-16 00:19:01 +0000596 // Didn't find one yet - now look through categories.
597 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
598 while (CatDecl) {
599 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
600 return MethodDecl;
601 CatDecl = CatDecl->getNextClassCategory();
602 }
603 ClassDecl = ClassDecl->getSuperClass();
604 }
605 return NULL;
606}
607
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000608/// getInstanceMethod - This method returns an instance method by
609/// looking in the class implementation. Unlike interfaces, we don't
610/// look outside the implementation.
611ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000612 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
613 if ((*I)->getSelector() == Sel)
614 return *I;
615 return NULL;
616}
617
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000618/// getClassMethod - This method returns a class method by looking in
619/// the class implementation. Unlike interfaces, we don't look outside
620/// the implementation.
621ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000622 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
623 I != E; ++I)
624 if ((*I)->getSelector() == Sel)
625 return *I;
626 return NULL;
627}
628
Fariborz Jahanian68342282008-12-05 22:32:48 +0000629/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
630/// added to the list of those properties @synthesized/@dynamic in this
631/// @implementation block.
632///
633ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
634 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
635 ObjCPropertyImplDecl *PID = *i;
636 if (PID->getPropertyDecl()->getIdentifier() == Id)
637 return PID;
638 }
639 return 0;
640}
641
642/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000643/// properties implemented in this @implementation block and returns the
644/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000645///
646ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
647 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
648 ObjCPropertyImplDecl *PID = *i;
649 if (PID->getPropertyIvarDecl() &&
650 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
651 return PID;
652 }
653 return 0;
654}
655
656/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian17eb8882008-12-05 22:36:19 +0000657/// properties implemented in this category @implementation block and returns the
658/// implemented property that uses it.
Fariborz Jahanian68342282008-12-05 22:32:48 +0000659///
660ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
661 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
662 ObjCPropertyImplDecl *PID = *i;
663 if (PID->getPropertyIvarDecl() &&
664 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
665 return PID;
666 }
667 return 0;
668}
669
670/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
671/// added to the list of those properties @synthesized/@dynamic in this
672/// category @implementation block.
673///
674ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
675 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
676 ObjCPropertyImplDecl *PID = *i;
677 if (PID->getPropertyDecl()->getIdentifier() == Id)
678 return PID;
679 }
680 return 0;
681}
682
Chris Lattner10318b82008-03-16 00:19:01 +0000683// lookupInstanceMethod - This method returns an instance method by looking in
684// the class implementation. Unlike interfaces, we don't look outside the
685// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000686ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000687 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
688 if ((*I)->getSelector() == Sel)
689 return *I;
690 return NULL;
691}
692
693// lookupClassMethod - This method returns an instance method by looking in
694// the class implementation. Unlike interfaces, we don't look outside the
695// implementation.
Daniel Dunbardd24b9a2008-08-26 06:53:45 +0000696ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner10318b82008-03-16 00:19:01 +0000697 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
698 I != E; ++I)
699 if ((*I)->getSelector() == Sel)
700 return *I;
701 return NULL;
702}
703
704// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
705// it inherited.
706ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
707 ObjCMethodDecl *MethodDecl = NULL;
708
709 if ((MethodDecl = getInstanceMethod(Sel)))
710 return MethodDecl;
711
Chris Lattner0be08822008-07-21 21:32:27 +0000712 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000713 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000714 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000715 return NULL;
716}
717
718// lookupInstanceMethod - Lookup a class method in the protocol and protocols
719// it inherited.
720ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
721 ObjCMethodDecl *MethodDecl = NULL;
722
723 if ((MethodDecl = getClassMethod(Sel)))
724 return MethodDecl;
725
Chris Lattner0be08822008-07-21 21:32:27 +0000726 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
Steve Naroff30fb1da2008-12-18 15:50:41 +0000727 if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
Chris Lattner0be08822008-07-21 21:32:27 +0000728 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000729 return NULL;
730}
731
732/// getSynthesizedMethodSize - Compute size of synthesized method name
733/// as done be the rewrite.
734///
735unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
736 // syntesized method name is a concatenation of -/+[class-name selector]
737 // Get length of this name.
738 unsigned length = 3; // _I_ or _C_
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000739 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Steve Naroff438be772009-01-08 19:41:02 +0000740 if (const ObjCCategoryImplDecl *CID =
741 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattnerd120b9e2008-11-24 03:54:41 +0000742 length += CID->getNameAsString().size()+1;
Chris Lattner3a8f2942008-11-24 03:33:13 +0000743 length += getSelector().getAsString().size(); // selector name
Chris Lattner10318b82008-03-16 00:19:01 +0000744 return length;
745}
746
Chris Lattner052fbcd2008-04-06 05:25:03 +0000747ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Steve Naroff438be772009-01-08 19:41:02 +0000748 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000749 return ID;
Steve Naroff438be772009-01-08 19:41:02 +0000750 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000751 return CD->getClassInterface();
752 if (ObjCImplementationDecl *IMD =
Steve Naroff438be772009-01-08 19:41:02 +0000753 dyn_cast<ObjCImplementationDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000754 return IMD->getClassInterface();
Steve Naroff438be772009-01-08 19:41:02 +0000755 if (ObjCCategoryImplDecl *CID =
756 dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
Chris Lattner10318b82008-03-16 00:19:01 +0000757 return CID->getClassInterface();
758 assert(false && "unknown method context");
759 return 0;
760}
Chris Lattner44859612008-03-17 01:19:02 +0000761
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000762ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000763 DeclContext *DC,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000764 SourceLocation atLoc,
765 SourceLocation L,
766 ObjCPropertyDecl *property,
Daniel Dunbar14117fc2008-08-26 04:47:31 +0000767 Kind PK,
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000768 ObjCIvarDecl *ivar) {
769 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
Douglas Gregor6e4fa2c2009-01-09 00:49:46 +0000770 return new (Mem) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000771}
Chris Lattner44859612008-03-17 01:19:02 +0000772
Chris Lattnereee57c02008-04-04 06:12:32 +0000773