blob: e3e4548f644dd9023f28fdca7d2da97e74dee70a [file] [log] [blame]
Chris Lattner1e03a562008-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 Dunbare91593e2008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Chris Lattner1e03a562008-03-16 00:19:01 +000017using namespace clang;
18
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000019//===----------------------------------------------------------------------===//
20// ObjC Decl Allocation/Deallocation Method Implementations
21//===----------------------------------------------------------------------===//
22
Chris Lattner0ed844b2008-04-04 06:12:32 +000023ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
24 SourceLocation beginLoc,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000025 SourceLocation endLoc,
26 Selector SelInfo, QualType T,
27 Decl *contextDecl,
Daniel Dunbarf6414922008-08-20 18:02:42 +000028 bool isInstance,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000029 bool isVariadic,
Fariborz Jahanian46070342008-05-07 20:53:44 +000030 bool isSynthesized,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000031 ImplementationControl impControl) {
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000032 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000033 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
34 SelInfo, T, contextDecl,
Daniel Dunbarf6414922008-08-20 18:02:42 +000035 isInstance,
Fariborz Jahanian46070342008-05-07 20:53:44 +000036 isVariadic, isSynthesized, impControl);
Chris Lattner0e77ba02008-03-16 01:15:50 +000037}
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000038
Ted Kremenek8a779312008-06-06 16:45:15 +000039ObjCMethodDecl::~ObjCMethodDecl() {
40 delete [] ParamInfo;
Ted Kremenek8a779312008-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 Lattner0ed844b2008-04-04 06:12:32 +000053ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
54 SourceLocation atLoc,
Steve Naroffd6a07aa2008-04-11 19:35:35 +000055 IdentifierInfo *Id,
56 SourceLocation ClassLoc,
Chris Lattner0e77ba02008-03-16 01:15:50 +000057 bool ForwardDecl, bool isInternal){
58 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattnerb752f282008-07-21 07:06:49 +000059 return new (Mem) ObjCInterfaceDecl(atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0e77ba02008-03-16 01:15:50 +000060 isInternal);
61}
62
Ted Kremenek8a779312008-06-06 16:45:15 +000063ObjCInterfaceDecl::~ObjCInterfaceDecl() {
64 delete [] Ivars;
65 delete [] InstanceMethods;
66 delete [] ClassMethods;
67 delete [] PropertyDecl;
68 // FIXME: CategoryList?
69}
70
71void ObjCInterfaceDecl::Destroy(ASTContext& C) {
72 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
73 if (*I) (*I)->Destroy(C);
74
75 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
76 if (*I) (*I)->Destroy(C);
77
78 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
79 if (*I) (*I)->Destroy(C);
Ted Kremenek1a726d72008-06-06 17:21:42 +000080
81 // FIXME: Because there is no clear ownership
82 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
83 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
84
Ted Kremenek8a779312008-06-06 16:45:15 +000085 Decl::Destroy(C);
86}
87
88
Chris Lattnerb048c982008-04-06 04:47:34 +000089ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenekb8db21d2008-07-23 18:04:17 +000090 IdentifierInfo *Id, QualType T,
91 AccessControl ac, Expr *BW) {
Chris Lattner0e77ba02008-03-16 01:15:50 +000092 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenekb8db21d2008-07-23 18:04:17 +000093 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000094}
95
Ted Kremenek01e67792008-08-20 03:26:33 +000096
97ObjCAtDefsFieldDecl
Douglas Gregor44b43212008-12-11 16:49:14 +000098*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
Ted Kremenek01e67792008-08-20 03:26:33 +000099 IdentifierInfo *Id, QualType T, Expr *BW) {
100 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
Douglas Gregor44b43212008-12-11 16:49:14 +0000101 return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
Ted Kremenek01e67792008-08-20 03:26:33 +0000102}
103
104void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
105 this->~ObjCAtDefsFieldDecl();
106 C.getAllocator().Deallocate((void *)this);
107}
108
Chris Lattner0ed844b2008-04-04 06:12:32 +0000109ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
110 SourceLocation L,
Chris Lattnerc8581052008-03-16 20:19:15 +0000111 IdentifierInfo *Id) {
Chris Lattnercca59d72008-03-16 01:23:04 +0000112 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner780f3292008-07-21 21:32:27 +0000113 return new (Mem) ObjCProtocolDecl(L, Id);
Chris Lattnercca59d72008-03-16 01:23:04 +0000114}
115
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000116ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenek1c8a4132008-06-06 19:48:57 +0000117 delete [] InstanceMethods;
118 delete [] ClassMethods;
119 delete [] PropertyDecl;
120}
121
122void ObjCProtocolDecl::Destroy(ASTContext& C) {
123
124 // Referenced Protocols are not owned, so don't Destroy them.
125
126 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I!=E; ++I)
127 if (*I) (*I)->Destroy(C);
128
129 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I!=E; ++I)
130 if (*I) (*I)->Destroy(C);
131
132 // FIXME: Because there is no clear ownership
133 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they
134 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
135
136 Decl::Destroy(C);
137}
138
139
Chris Lattner0ed844b2008-04-04 06:12:32 +0000140ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
141 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000142 ObjCInterfaceDecl **Elts, unsigned nElts) {
143 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
144 return new (Mem) ObjCClassDecl(L, Elts, nElts);
145}
146
Ted Kremenek400d95f2008-06-06 20:11:53 +0000147ObjCClassDecl::~ObjCClassDecl() {
148 delete [] ForwardDecls;
149}
150
151void ObjCClassDecl::Destroy(ASTContext& C) {
152
153 // FIXME: There is no clear ownership policy now for referenced
154 // ObjCInterfaceDecls. Some of them can be forward declarations that
155 // are never later defined (in which case the ObjCClassDecl owns them)
156 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally
157 // we should have separate objects for forward declarations and definitions,
158 // obviating this problem. Because of this situation, referenced
159 // ObjCInterfaceDecls are destroyed in ~TranslationUnit.
160
161 Decl::Destroy(C);
162}
163
Chris Lattner61f9d412008-03-16 20:34:23 +0000164ObjCForwardProtocolDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000165ObjCForwardProtocolDecl::Create(ASTContext &C,
166 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000167 ObjCProtocolDecl **Elts, unsigned NumElts) {
168 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
169 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
170}
171
Ted Kremenek05ac3ef2008-06-06 21:05:33 +0000172ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
173 delete [] ReferencedProtocols;
174}
175
Chris Lattner0ed844b2008-04-04 06:12:32 +0000176ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
177 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +0000178 IdentifierInfo *Id) {
179 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner68c82cf2008-03-16 20:47:45 +0000180 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattner61f9d412008-03-16 20:34:23 +0000181}
182
Chris Lattner75c9cae2008-03-16 20:53:07 +0000183ObjCCategoryImplDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000184ObjCCategoryImplDecl::Create(ASTContext &C,
185 SourceLocation L,IdentifierInfo *Id,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000186 ObjCInterfaceDecl *ClassInterface) {
187 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
188 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
189}
190
191ObjCImplementationDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000192ObjCImplementationDecl::Create(ASTContext &C,
193 SourceLocation L,
Chris Lattner75c9cae2008-03-16 20:53:07 +0000194 IdentifierInfo *Id,
195 ObjCInterfaceDecl *ClassInterface,
196 ObjCInterfaceDecl *SuperDecl) {
197 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
198 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
199}
Chris Lattner1e03a562008-03-16 00:19:01 +0000200
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000201ObjCCompatibleAliasDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000202ObjCCompatibleAliasDecl::Create(ASTContext &C,
203 SourceLocation L,
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000204 IdentifierInfo *Id,
205 ObjCInterfaceDecl* AliasedClass) {
206 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
207 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
208}
209
Chris Lattner0ed844b2008-04-04 06:12:32 +0000210ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniandae1a1a2008-04-11 23:40:25 +0000211 SourceLocation L,
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000212 IdentifierInfo *Id,
Fariborz Jahanian46b55e52008-05-05 18:51:55 +0000213 QualType T,
214 PropertyControl propControl) {
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000215 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian1de1e742008-04-14 23:36:35 +0000216 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000217}
218
Chris Lattner1e03a562008-03-16 00:19:01 +0000219//===----------------------------------------------------------------------===//
220// Objective-C Decl Implementation
221//===----------------------------------------------------------------------===//
222
Fariborz Jahanianfef30b52008-12-09 20:23:04 +0000223void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
224 const ObjCInterfaceDecl *OID) {
Daniel Dunbar08a356c2008-08-26 06:08:30 +0000225 QualType selfTy;
226 if (isInstance()) {
227 // There may be no interface context due to error in declaration
228 // of the interface (which has been reported). Recover gracefully.
Fariborz Jahanianfef30b52008-12-09 20:23:04 +0000229 if (OID) {
230 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
Daniel Dunbar08a356c2008-08-26 06:08:30 +0000231 selfTy = Context.getPointerType(selfTy);
232 } else {
233 selfTy = Context.getObjCIdType();
234 }
235 } else // we have a factory method.
236 selfTy = Context.getObjCClassType();
237
238 SelfDecl = ImplicitParamDecl::Create(Context, this,
239 SourceLocation(),
240 &Context.Idents.get("self"),
241 selfTy, 0);
242
243 CmdDecl = ImplicitParamDecl::Create(Context, this,
244 SourceLocation(),
245 &Context.Idents.get("_cmd"),
246 Context.getObjCSelType(), 0);
247}
248
Chris Lattner1e03a562008-03-16 00:19:01 +0000249void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
250 unsigned NumParams) {
251 assert(ParamInfo == 0 && "Already has param info!");
252
253 // Zero params -> null pointer.
254 if (NumParams) {
255 ParamInfo = new ParmVarDecl*[NumParams];
256 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
257 NumMethodParams = NumParams;
258 }
259}
260
Fariborz Jahanian31afbf02008-11-25 21:48:26 +0000261/// isPropertyReadonly - Return true if property is a readonly, by seaching
262/// for the property in the class and in its categories.
263///
264bool ObjCInterfaceDecl::isPropertyReadonly(ObjCPropertyDecl *PDecl) const
265{
266 if (PDecl->isReadOnly()) {
267 // Main class has the property as 'readyonly'. Must search
268 // through the category list to see if the property's
269 // attribute has been over-ridden to 'readwrite'.
270 for (ObjCCategoryDecl *Category = getCategoryList();
271 Category; Category = Category->getNextClassCategory()) {
272 PDecl= Category->FindPropertyDeclaration(PDecl->getIdentifier());
273 if (PDecl && !PDecl->isReadOnly())
274 return false;
275 }
276 return true;
277 }
278 return false;
279}
280
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000281/// FindPropertyDeclaration - Finds declaration of the property given its name
282/// in 'PropertyId' and returns it. It returns 0, if not found.
283///
284ObjCPropertyDecl *
285 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
286 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
287 E = classprop_end(); I != E; ++I) {
288 ObjCPropertyDecl *property = *I;
289 if (property->getIdentifier() == PropertyId)
290 return property;
291 }
Steve Naroff6c930f22008-06-04 04:46:04 +0000292 // Look through categories.
293 for (ObjCCategoryDecl *Category = getCategoryList();
294 Category; Category = Category->getNextClassCategory()) {
295 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
296 if (property)
297 return property;
298 }
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000299 // Look through protocols.
300 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
301 E = protocol_end(); I != E; ++I) {
302 ObjCProtocolDecl *Protocol = *I;
303 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
304 if (property)
305 return property;
306 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000307 if (getSuperClass())
308 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000309 return 0;
310}
311
312/// FindCategoryDeclaration - Finds category declaration in the list of
313/// categories for this class and returns it. Name of the category is passed
314/// in 'CategoryId'. If category not found, return 0;
315///
316ObjCCategoryDecl *
317 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
318 for (ObjCCategoryDecl *Category = getCategoryList();
319 Category; Category = Category->getNextClassCategory())
320 if (Category->getIdentifier() == CategoryId)
321 return Category;
322 return 0;
323}
324
325/// FindIvarDeclaration - Find an Ivar declaration in this class given its
326/// name in 'IvarId'. On failure to find, return 0;
327///
328ObjCIvarDecl *
329 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
330 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
331 IVE = ivar_end(); IVI != IVE; ++IVI) {
332 ObjCIvarDecl* Ivar = (*IVI);
333 if (Ivar->getIdentifier() == IvarId)
334 return Ivar;
335 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000336 if (getSuperClass())
337 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000338 return 0;
339}
340
Fariborz Jahanian60f8c862008-12-13 20:28:25 +0000341void ObjCInterfaceDecl::CollectObjCIvars(std::vector<FieldDecl*> &Fields) {
342 ObjCInterfaceDecl *SuperClass = getSuperClass();
343 if (SuperClass)
344 SuperClass->CollectObjCIvars(Fields);
345 for (ObjCInterfaceDecl::ivar_iterator I = ivar_begin(),
346 E = ivar_end(); I != E; ++I) {
347 ObjCIvarDecl *IVDecl = (*I);
348 Fields.push_back(cast<FieldDecl>(IVDecl));
349 }
350}
351
Chris Lattner1e03a562008-03-16 00:19:01 +0000352/// ObjCAddInstanceVariablesToClass - Inserts instance variables
353/// into ObjCInterfaceDecl's fields.
354///
355void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
356 unsigned numIvars,
357 SourceLocation RBrac) {
358 NumIvars = numIvars;
359 if (numIvars) {
360 Ivars = new ObjCIvarDecl*[numIvars];
361 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
362 }
363 setLocEnd(RBrac);
364}
365
Fariborz Jahanian60f8c862008-12-13 20:28:25 +0000366/// addInstanceVariablesToClass - produces layout info. for the class for its
367/// ivars and all those inherited.
368///
369void ObjCInterfaceDecl::addLayoutToClass(ASTContext &Context)
370{
371 std::vector<FieldDecl*> RecFields;
372 CollectObjCIvars(RecFields);
373 RecordDecl *RD = RecordDecl::Create(Context, TagDecl::TK_struct, 0,
374 getLocation(),
375 getIdentifier());
376 /// FIXME! Can do collection of ivars and adding to the record while
377 /// doing it.
378 for (unsigned int i = 0; i != RecFields.size(); i++) {
379 FieldDecl *Field = FieldDecl::Create(Context, RD, SourceLocation(),
380 RecFields[i]->getIdentifier(),
381 RecFields[i]->getType(), 0, false, 0);
382 RD->addDecl(Context, Field);
383 }
384 RD->completeDefinition(Context);
385 setRecordForDecl(RD);
386}
387
Chris Lattner1e03a562008-03-16 00:19:01 +0000388/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
389/// Variables (Ivars) relative to what declared in @implementation;s class.
390/// Ivars into ObjCImplementationDecl's fields.
391///
392void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
393 ObjCIvarDecl **ivars, unsigned numIvars) {
394 NumIvars = numIvars;
395 if (numIvars) {
396 Ivars = new ObjCIvarDecl*[numIvars];
397 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
398 }
399}
400
401/// addMethods - Insert instance and methods declarations into
402/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
403///
404void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
405 unsigned numInsMembers,
406 ObjCMethodDecl **clsMethods,
407 unsigned numClsMembers,
408 SourceLocation endLoc) {
409 NumInstanceMethods = numInsMembers;
410 if (numInsMembers) {
411 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
412 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
413 }
414 NumClassMethods = numClsMembers;
415 if (numClsMembers) {
416 ClassMethods = new ObjCMethodDecl*[numClsMembers];
417 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
418 }
419 AtEndLoc = endLoc;
420}
421
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000422/// addProperties - Insert property declaration AST nodes into
423/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattner55d13b42008-03-16 21:23:50 +0000424///
425void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
426 unsigned NumProperties) {
427 if (NumProperties == 0) return;
428
429 NumPropertyDecl = NumProperties;
430 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
431 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
432}
433
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000434/// mergeProperties - Adds properties to the end of list of current properties
435/// for this class.
436
437void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
438 unsigned NumNewProperties) {
439 if (NumNewProperties == 0) return;
440
441 if (PropertyDecl) {
442 ObjCPropertyDecl **newPropertyDecl =
443 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
444 ObjCPropertyDecl **buf = newPropertyDecl;
445 // put back original properties in buffer.
446 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
447 // Add new properties to this buffer.
448 memcpy(buf+NumPropertyDecl, Properties,
449 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000450 delete[] PropertyDecl;
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000451 PropertyDecl = newPropertyDecl;
452 NumPropertyDecl += NumNewProperties;
453 }
454 else {
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000455 addProperties(Properties, NumNewProperties);
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000456 }
457}
458
Daniel Dunbar7b473222008-08-27 02:09:39 +0000459static void
460addPropertyMethods(Decl *D,
461 ASTContext &Context,
462 ObjCPropertyDecl *property,
Fariborz Jahanianb85cce62008-12-02 00:19:12 +0000463 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
464 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
Daniel Dunbare86d9232008-08-27 05:13:46 +0000465 ObjCMethodDecl *GetterDecl, *SetterDecl = 0;
Fariborz Jahanianb85cce62008-12-02 00:19:12 +0000466
467 GetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getGetterName()]);
468 if (!property->isReadOnly())
469 SetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getSetterName()]);
470
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000471 // FIXME: The synthesized property we set here is misleading. We
472 // almost always synthesize these methods unless the user explicitly
473 // provided prototypes (which is odd, but allowed). Sema should be
474 // typechecking that the declarations jive in that situation (which
475 // it is not currently).
476
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000477 // Find the default getter and if one not found, add one.
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000478 if (!GetterDecl) {
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000479 // No instance method of same name as property getter name was found.
480 // Declare a getter method and add it to the list of methods
481 // for this class.
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000482 GetterDecl =
483 ObjCMethodDecl::Create(Context, property->getLocation(),
484 property->getLocation(),
485 property->getGetterName(),
486 property->getType(),
Daniel Dunbar7b473222008-08-27 02:09:39 +0000487 D,
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000488 true, false, true, ObjCMethodDecl::Required);
489 insMethods.push_back(GetterDecl);
Fariborz Jahanianb85cce62008-12-02 00:19:12 +0000490 InsMap[property->getGetterName()] = GetterDecl;
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000491 }
Fariborz Jahanian91b51a92008-12-09 22:43:22 +0000492 else
493 // A user declared getter will be synthesize when @synthesize of
494 // the property with the same name is seen in the @implementation
495 GetterDecl->setIsSynthesized();
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000496 property->setGetterMethodDecl(GetterDecl);
497
Daniel Dunbar394d33f2008-08-26 07:16:44 +0000498 // Skip setter if property is read-only.
499 if (property->isReadOnly())
500 return;
501
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000502 // Find the default setter and if one not found, add one.
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000503 if (!SetterDecl) {
504 // No instance method of same name as property setter name was found.
505 // Declare a setter method and add it to the list of methods
506 // for this class.
507 SetterDecl =
508 ObjCMethodDecl::Create(Context, property->getLocation(),
509 property->getLocation(),
510 property->getSetterName(),
Daniel Dunbar5fa63312008-08-26 02:53:23 +0000511 Context.VoidTy,
Daniel Dunbar7b473222008-08-27 02:09:39 +0000512 D,
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000513 true, false, true, ObjCMethodDecl::Required);
514 insMethods.push_back(SetterDecl);
Fariborz Jahanianb85cce62008-12-02 00:19:12 +0000515 InsMap[property->getSetterName()] = SetterDecl;
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000516 // Invent the arguments for the setter. We don't bother making a
517 // nice name for the argument.
518 ParmVarDecl *Argument = ParmVarDecl::Create(Context,
519 SetterDecl,
520 SourceLocation(),
521 property->getIdentifier(),
522 property->getType(),
523 VarDecl::None,
524 0, 0);
525 SetterDecl->setMethodParams(&Argument, 1);
526 }
Fariborz Jahanian91b51a92008-12-09 22:43:22 +0000527 else
528 // A user declared setter will be synthesize when @synthesize of
529 // the property with the same name is seen in the @implementation
530 SetterDecl->setIsSynthesized();
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000531 property->setSetterMethodDecl(SetterDecl);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000532}
533
Daniel Dunbar7b473222008-08-27 02:09:39 +0000534/// addPropertyMethods - Goes through list of properties declared in this class
535/// and builds setter/getter method declartions depending on the setter/getter
536/// attributes of the property.
537///
538void ObjCInterfaceDecl::addPropertyMethods(
539 ASTContext &Context,
540 ObjCPropertyDecl *property,
Fariborz Jahanianb85cce62008-12-02 00:19:12 +0000541 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
542 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
543 ::addPropertyMethods(this, Context, property, insMethods, InsMap);
Daniel Dunbar7b473222008-08-27 02:09:39 +0000544}
545
546/// addPropertyMethods - Goes through list of properties declared in this class
547/// and builds setter/getter method declartions depending on the setter/getter
548/// attributes of the property.
549///
550void ObjCCategoryDecl::addPropertyMethods(
551 ASTContext &Context,
552 ObjCPropertyDecl *property,
Fariborz Jahanianb85cce62008-12-02 00:19:12 +0000553 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
554 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
555 ::addPropertyMethods(this, Context, property, insMethods, InsMap);
Daniel Dunbar7b473222008-08-27 02:09:39 +0000556}
557
Fariborz Jahanian1ac2bc42008-12-06 23:03:39 +0000558/// mergeProperties - Adds properties to the end of list of current properties
559/// for this category.
560
561void ObjCCategoryDecl::mergeProperties(ObjCPropertyDecl **Properties,
562 unsigned NumNewProperties) {
563 if (NumNewProperties == 0) return;
564
565 if (PropertyDecl) {
566 ObjCPropertyDecl **newPropertyDecl =
567 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
568 ObjCPropertyDecl **buf = newPropertyDecl;
569 // put back original properties in buffer.
570 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
571 // Add new properties to this buffer.
572 memcpy(buf+NumPropertyDecl, Properties,
573 NumNewProperties*sizeof(ObjCPropertyDecl*));
574 delete[] PropertyDecl;
575 PropertyDecl = newPropertyDecl;
576 NumPropertyDecl += NumNewProperties;
577 }
578 else {
579 addProperties(Properties, NumNewProperties);
580 }
581}
582
Daniel Dunbar7b473222008-08-27 02:09:39 +0000583/// addPropertyMethods - Goes through list of properties declared in this class
584/// and builds setter/getter method declartions depending on the setter/getter
585/// attributes of the property.
586///
587void ObjCProtocolDecl::addPropertyMethods(
588 ASTContext &Context,
589 ObjCPropertyDecl *property,
Fariborz Jahanianb85cce62008-12-02 00:19:12 +0000590 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
591 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
592 ::addPropertyMethods(this, Context, property, insMethods, InsMap);
Daniel Dunbar7b473222008-08-27 02:09:39 +0000593}
594
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000595/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian3dd4ba42008-04-17 18:25:18 +0000596/// ObjCProtocolDecl's PropertyDecl field.
597///
598void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
599 unsigned NumProperties) {
600 if (NumProperties == 0) return;
601
602 NumPropertyDecl = NumProperties;
603 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
604 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
605}
606
607/// addProperties - Insert property declaration AST nodes into
Fariborz Jahaniand9a3c332008-04-16 21:11:25 +0000608/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000609///
610void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
611 unsigned NumProperties) {
612 if (NumProperties == 0) return;
613
614 NumPropertyDecl = NumProperties;
615 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
616 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
617}
618
Chris Lattner55d13b42008-03-16 21:23:50 +0000619/// addMethods - Insert instance and methods declarations into
Chris Lattner1e03a562008-03-16 00:19:01 +0000620/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
621///
622void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
623 unsigned numInsMembers,
624 ObjCMethodDecl **clsMethods,
625 unsigned numClsMembers,
626 SourceLocation endLoc) {
627 NumInstanceMethods = numInsMembers;
628 if (numInsMembers) {
629 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
630 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
631 }
632 NumClassMethods = numClsMembers;
633 if (numClsMembers) {
634 ClassMethods = new ObjCMethodDecl*[numClsMembers];
635 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
636 }
637 AtEndLoc = endLoc;
638}
639
Chris Lattner68c82cf2008-03-16 20:47:45 +0000640
641
Chris Lattner1e03a562008-03-16 00:19:01 +0000642/// addMethods - Insert instance and methods declarations into
643/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
644///
645void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
646 unsigned numInsMembers,
647 ObjCMethodDecl **clsMethods,
648 unsigned numClsMembers,
649 SourceLocation endLoc) {
650 NumInstanceMethods = numInsMembers;
651 if (numInsMembers) {
652 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
653 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
654 }
655 NumClassMethods = numClsMembers;
656 if (numClsMembers) {
657 ClassMethods = new ObjCMethodDecl*[numClsMembers];
658 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
659 }
660 AtEndLoc = endLoc;
661}
662
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000663/// FindPropertyDeclaration - Finds declaration of the property given its name
664/// in 'PropertyId' and returns it. It returns 0, if not found.
665///
666ObjCPropertyDecl *
667ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
668 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
669 E = classprop_end(); I != E; ++I) {
670 ObjCPropertyDecl *property = *I;
671 if (property->getIdentifier() == PropertyId)
672 return property;
673 }
674 return 0;
675}
676
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000677/// FindPropertyDeclaration - Finds declaration of the property given its name
678/// in 'PropertyId' and returns it. It returns 0, if not found.
679///
680ObjCPropertyDecl *
681ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
682 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
683 E = classprop_end(); I != E; ++I) {
684 ObjCPropertyDecl *property = *I;
685 if (property->getIdentifier() == PropertyId)
686 return property;
687 }
688 return 0;
689}
690
Chris Lattner1e03a562008-03-16 00:19:01 +0000691ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
692 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
693 ObjCInterfaceDecl* ClassDecl = this;
694 while (ClassDecl != NULL) {
695 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
696 I != E; ++I) {
697 if ((*I)->getIdentifier() == ID) {
698 clsDeclared = ClassDecl;
699 return *I;
700 }
701 }
702 ClassDecl = ClassDecl->getSuperClass();
703 }
704 return NULL;
705}
706
707/// lookupInstanceMethod - This method returns an instance method by looking in
708/// the class, its categories, and its super classes (using a linear search).
709ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
710 ObjCInterfaceDecl* ClassDecl = this;
711 ObjCMethodDecl *MethodDecl = 0;
712
713 while (ClassDecl != NULL) {
714 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
715 return MethodDecl;
716
717 // Didn't find one yet - look through protocols.
Chris Lattner3db6cae2008-07-21 18:19:38 +0000718 const ObjCList<ObjCProtocolDecl> &Protocols =
719 ClassDecl->getReferencedProtocols();
720 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
721 E = Protocols.end(); I != E; ++I)
722 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000723 return MethodDecl;
Chris Lattner3db6cae2008-07-21 18:19:38 +0000724
Chris Lattner1e03a562008-03-16 00:19:01 +0000725 // Didn't find one yet - now look through categories.
726 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
727 while (CatDecl) {
728 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
729 return MethodDecl;
Steve Naroffb79c01e2008-12-08 20:57:28 +0000730
731 // Didn't find one yet - look through protocols.
732 const ObjCList<ObjCProtocolDecl> &Protocols =
733 CatDecl->getReferencedProtocols();
734 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
735 E = Protocols.end(); I != E; ++I)
736 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
737 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000738 CatDecl = CatDecl->getNextClassCategory();
739 }
740 ClassDecl = ClassDecl->getSuperClass();
741 }
742 return NULL;
743}
744
745// lookupClassMethod - This method returns a class method by looking in the
746// class, its categories, and its super classes (using a linear search).
747ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
748 ObjCInterfaceDecl* ClassDecl = this;
749 ObjCMethodDecl *MethodDecl = 0;
750
751 while (ClassDecl != NULL) {
752 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
753 return MethodDecl;
754
755 // Didn't find one yet - look through protocols.
Chris Lattner780f3292008-07-21 21:32:27 +0000756 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
757 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner3db6cae2008-07-21 18:19:38 +0000758 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000759 return MethodDecl;
Chris Lattner780f3292008-07-21 21:32:27 +0000760
Chris Lattner1e03a562008-03-16 00:19:01 +0000761 // Didn't find one yet - now look through categories.
762 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
763 while (CatDecl) {
764 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
765 return MethodDecl;
766 CatDecl = CatDecl->getNextClassCategory();
767 }
768 ClassDecl = ClassDecl->getSuperClass();
769 }
770 return NULL;
771}
772
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000773/// getInstanceMethod - This method returns an instance method by
774/// looking in the class implementation. Unlike interfaces, we don't
775/// look outside the implementation.
776ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000777 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
778 if ((*I)->getSelector() == Sel)
779 return *I;
780 return NULL;
781}
782
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000783/// getClassMethod - This method returns a class method by looking in
784/// the class implementation. Unlike interfaces, we don't look outside
785/// the implementation.
786ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000787 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
788 I != E; ++I)
789 if ((*I)->getSelector() == Sel)
790 return *I;
791 return NULL;
792}
793
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000794/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
795/// added to the list of those properties @synthesized/@dynamic in this
796/// @implementation block.
797///
798ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
799 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
800 ObjCPropertyImplDecl *PID = *i;
801 if (PID->getPropertyDecl()->getIdentifier() == Id)
802 return PID;
803 }
804 return 0;
805}
806
807/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian9482a4f2008-12-05 22:36:19 +0000808/// properties implemented in this @implementation block and returns the
809/// implemented property that uses it.
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000810///
811ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
812 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
813 ObjCPropertyImplDecl *PID = *i;
814 if (PID->getPropertyIvarDecl() &&
815 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
816 return PID;
817 }
818 return 0;
819}
820
821/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
Fariborz Jahanian9482a4f2008-12-05 22:36:19 +0000822/// properties implemented in this category @implementation block and returns the
823/// implemented property that uses it.
Fariborz Jahanianae6f6fd2008-12-05 22:32:48 +0000824///
825ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
826 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
827 ObjCPropertyImplDecl *PID = *i;
828 if (PID->getPropertyIvarDecl() &&
829 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
830 return PID;
831 }
832 return 0;
833}
834
835/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
836/// added to the list of those properties @synthesized/@dynamic in this
837/// category @implementation block.
838///
839ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const {
840 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) {
841 ObjCPropertyImplDecl *PID = *i;
842 if (PID->getPropertyDecl()->getIdentifier() == Id)
843 return PID;
844 }
845 return 0;
846}
847
Chris Lattner1e03a562008-03-16 00:19:01 +0000848// lookupInstanceMethod - This method returns an instance method by looking in
849// the class implementation. Unlike interfaces, we don't look outside the
850// implementation.
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000851ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000852 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
853 if ((*I)->getSelector() == Sel)
854 return *I;
855 return NULL;
856}
857
858// lookupClassMethod - This method returns an instance method by looking in
859// the class implementation. Unlike interfaces, we don't look outside the
860// implementation.
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000861ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000862 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
863 I != E; ++I)
864 if ((*I)->getSelector() == Sel)
865 return *I;
866 return NULL;
867}
868
869// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
870// it inherited.
871ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
872 ObjCMethodDecl *MethodDecl = NULL;
873
874 if ((MethodDecl = getInstanceMethod(Sel)))
875 return MethodDecl;
876
Chris Lattner780f3292008-07-21 21:32:27 +0000877 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
878 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
879 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000880 return NULL;
881}
882
883// lookupInstanceMethod - Lookup a class method in the protocol and protocols
884// it inherited.
885ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
886 ObjCMethodDecl *MethodDecl = NULL;
887
888 if ((MethodDecl = getClassMethod(Sel)))
889 return MethodDecl;
890
Chris Lattner780f3292008-07-21 21:32:27 +0000891 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
892 if ((MethodDecl = (*I)->getClassMethod(Sel)))
893 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000894 return NULL;
895}
896
897/// getSynthesizedMethodSize - Compute size of synthesized method name
898/// as done be the rewrite.
899///
900unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
901 // syntesized method name is a concatenation of -/+[class-name selector]
902 // Get length of this name.
903 unsigned length = 3; // _I_ or _C_
Chris Lattner8ec03f52008-11-24 03:54:41 +0000904 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Chris Lattner1e03a562008-03-16 00:19:01 +0000905 NamedDecl *MethodContext = getMethodContext();
906 if (ObjCCategoryImplDecl *CID =
907 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner8ec03f52008-11-24 03:54:41 +0000908 length += CID->getNameAsString().size()+1;
Chris Lattner077bf5e2008-11-24 03:33:13 +0000909 length += getSelector().getAsString().size(); // selector name
Chris Lattner1e03a562008-03-16 00:19:01 +0000910 return length;
911}
912
Chris Lattner56196882008-04-06 05:25:03 +0000913ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner1e03a562008-03-16 00:19:01 +0000914 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
915 return ID;
916 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
917 return CD->getClassInterface();
918 if (ObjCImplementationDecl *IMD =
Chris Lattner56196882008-04-06 05:25:03 +0000919 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000920 return IMD->getClassInterface();
Chris Lattner56196882008-04-06 05:25:03 +0000921 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000922 return CID->getClassInterface();
923 assert(false && "unknown method context");
924 return 0;
925}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000926
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000927ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
928 SourceLocation atLoc,
929 SourceLocation L,
930 ObjCPropertyDecl *property,
Daniel Dunbar9f0afd42008-08-26 04:47:31 +0000931 Kind PK,
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000932 ObjCIvarDecl *ivar) {
933 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
Daniel Dunbar9f0afd42008-08-26 04:47:31 +0000934 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, PK, ivar);
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000935}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000936
Chris Lattner0ed844b2008-04-04 06:12:32 +0000937