blob: e631bac452e2054ecb3ab93329053c09082eb263 [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
98*ObjCAtDefsFieldDecl::Create(ASTContext &C, SourceLocation L,
99 IdentifierInfo *Id, QualType T, Expr *BW) {
100 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>();
101 return new (Mem) ObjCAtDefsFieldDecl(L, Id, T, BW);
102}
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
Daniel Dunbar08a356c2008-08-26 06:08:30 +0000223void ObjCMethodDecl::createImplicitParams(ASTContext &Context) {
224 QualType selfTy;
225 if (isInstance()) {
226 // There may be no interface context due to error in declaration
227 // of the interface (which has been reported). Recover gracefully.
228 if (ObjCInterfaceDecl *OID = getClassInterface()) {
229 selfTy = Context.getObjCInterfaceType(OID);
230 selfTy = Context.getPointerType(selfTy);
231 } else {
232 selfTy = Context.getObjCIdType();
233 }
234 } else // we have a factory method.
235 selfTy = Context.getObjCClassType();
236
237 SelfDecl = ImplicitParamDecl::Create(Context, this,
238 SourceLocation(),
239 &Context.Idents.get("self"),
240 selfTy, 0);
241
242 CmdDecl = ImplicitParamDecl::Create(Context, this,
243 SourceLocation(),
244 &Context.Idents.get("_cmd"),
245 Context.getObjCSelType(), 0);
246}
247
Chris Lattner1e03a562008-03-16 00:19:01 +0000248void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
249 unsigned NumParams) {
250 assert(ParamInfo == 0 && "Already has param info!");
251
252 // Zero params -> null pointer.
253 if (NumParams) {
254 ParamInfo = new ParmVarDecl*[NumParams];
255 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
256 NumMethodParams = NumParams;
257 }
258}
259
Fariborz Jahanian31afbf02008-11-25 21:48:26 +0000260/// isPropertyReadonly - Return true if property is a readonly, by seaching
261/// for the property in the class and in its categories.
262///
263bool ObjCInterfaceDecl::isPropertyReadonly(ObjCPropertyDecl *PDecl) const
264{
265 if (PDecl->isReadOnly()) {
266 // Main class has the property as 'readyonly'. Must search
267 // through the category list to see if the property's
268 // attribute has been over-ridden to 'readwrite'.
269 for (ObjCCategoryDecl *Category = getCategoryList();
270 Category; Category = Category->getNextClassCategory()) {
271 PDecl= Category->FindPropertyDeclaration(PDecl->getIdentifier());
272 if (PDecl && !PDecl->isReadOnly())
273 return false;
274 }
275 return true;
276 }
277 return false;
278}
279
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000280/// FindPropertyDeclaration - Finds declaration of the property given its name
281/// in 'PropertyId' and returns it. It returns 0, if not found.
282///
283ObjCPropertyDecl *
284 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
285 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
286 E = classprop_end(); I != E; ++I) {
287 ObjCPropertyDecl *property = *I;
288 if (property->getIdentifier() == PropertyId)
289 return property;
290 }
Steve Naroff6c930f22008-06-04 04:46:04 +0000291 // Look through categories.
292 for (ObjCCategoryDecl *Category = getCategoryList();
293 Category; Category = Category->getNextClassCategory()) {
294 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
295 if (property)
296 return property;
297 }
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000298 // Look through protocols.
299 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
300 E = protocol_end(); I != E; ++I) {
301 ObjCProtocolDecl *Protocol = *I;
302 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
303 if (property)
304 return property;
305 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000306 if (getSuperClass())
307 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000308 return 0;
309}
310
311/// FindCategoryDeclaration - Finds category declaration in the list of
312/// categories for this class and returns it. Name of the category is passed
313/// in 'CategoryId'. If category not found, return 0;
314///
315ObjCCategoryDecl *
316 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
317 for (ObjCCategoryDecl *Category = getCategoryList();
318 Category; Category = Category->getNextClassCategory())
319 if (Category->getIdentifier() == CategoryId)
320 return Category;
321 return 0;
322}
323
324/// FindIvarDeclaration - Find an Ivar declaration in this class given its
325/// name in 'IvarId'. On failure to find, return 0;
326///
327ObjCIvarDecl *
328 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
329 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
330 IVE = ivar_end(); IVI != IVE; ++IVI) {
331 ObjCIvarDecl* Ivar = (*IVI);
332 if (Ivar->getIdentifier() == IvarId)
333 return Ivar;
334 }
Fariborz Jahanianc70bee82008-04-21 23:57:08 +0000335 if (getSuperClass())
336 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000337 return 0;
338}
339
Chris Lattner1e03a562008-03-16 00:19:01 +0000340/// ObjCAddInstanceVariablesToClass - Inserts instance variables
341/// into ObjCInterfaceDecl's fields.
342///
343void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
344 unsigned numIvars,
345 SourceLocation RBrac) {
346 NumIvars = numIvars;
347 if (numIvars) {
348 Ivars = new ObjCIvarDecl*[numIvars];
349 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
350 }
351 setLocEnd(RBrac);
352}
353
354/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
355/// Variables (Ivars) relative to what declared in @implementation;s class.
356/// Ivars into ObjCImplementationDecl's fields.
357///
358void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
359 ObjCIvarDecl **ivars, unsigned numIvars) {
360 NumIvars = numIvars;
361 if (numIvars) {
362 Ivars = new ObjCIvarDecl*[numIvars];
363 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
364 }
365}
366
367/// addMethods - Insert instance and methods declarations into
368/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
369///
370void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
371 unsigned numInsMembers,
372 ObjCMethodDecl **clsMethods,
373 unsigned numClsMembers,
374 SourceLocation endLoc) {
375 NumInstanceMethods = numInsMembers;
376 if (numInsMembers) {
377 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
378 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
379 }
380 NumClassMethods = numClsMembers;
381 if (numClsMembers) {
382 ClassMethods = new ObjCMethodDecl*[numClsMembers];
383 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
384 }
385 AtEndLoc = endLoc;
386}
387
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000388/// addProperties - Insert property declaration AST nodes into
389/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattner55d13b42008-03-16 21:23:50 +0000390///
391void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
392 unsigned NumProperties) {
393 if (NumProperties == 0) return;
394
395 NumPropertyDecl = NumProperties;
396 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
397 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
398}
399
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000400/// mergeProperties - Adds properties to the end of list of current properties
401/// for this class.
402
403void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
404 unsigned NumNewProperties) {
405 if (NumNewProperties == 0) return;
406
407 if (PropertyDecl) {
408 ObjCPropertyDecl **newPropertyDecl =
409 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
410 ObjCPropertyDecl **buf = newPropertyDecl;
411 // put back original properties in buffer.
412 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
413 // Add new properties to this buffer.
414 memcpy(buf+NumPropertyDecl, Properties,
415 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000416 delete[] PropertyDecl;
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000417 PropertyDecl = newPropertyDecl;
418 NumPropertyDecl += NumNewProperties;
419 }
420 else {
Nuno Lopes6b3502c2008-05-10 10:31:54 +0000421 addProperties(Properties, NumNewProperties);
Fariborz Jahanianaebf0cb2008-05-02 19:17:30 +0000422 }
423}
424
Daniel Dunbar7b473222008-08-27 02:09:39 +0000425static void
426addPropertyMethods(Decl *D,
427 ASTContext &Context,
428 ObjCPropertyDecl *property,
429 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
Daniel Dunbare86d9232008-08-27 05:13:46 +0000430 ObjCMethodDecl *GetterDecl, *SetterDecl = 0;
Daniel Dunbar7b473222008-08-27 02:09:39 +0000431
432 if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(D)) {
433 GetterDecl = OID->getInstanceMethod(property->getGetterName());
434 if (!property->isReadOnly())
435 SetterDecl = OID->getInstanceMethod(property->getSetterName());
436 } else if (ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(D)) {
437 GetterDecl = OCD->getInstanceMethod(property->getGetterName());
438 if (!property->isReadOnly())
439 SetterDecl = OCD->getInstanceMethod(property->getSetterName());
440 } else {
441 ObjCProtocolDecl *OPD = cast<ObjCProtocolDecl>(D);
442 GetterDecl = OPD->getInstanceMethod(property->getGetterName());
443 if (!property->isReadOnly())
444 SetterDecl = OPD->getInstanceMethod(property->getSetterName());
445 }
446
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000447 // FIXME: The synthesized property we set here is misleading. We
448 // almost always synthesize these methods unless the user explicitly
449 // provided prototypes (which is odd, but allowed). Sema should be
450 // typechecking that the declarations jive in that situation (which
451 // it is not currently).
452
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000453 // Find the default getter and if one not found, add one.
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000454 if (!GetterDecl) {
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000455 // No instance method of same name as property getter name was found.
456 // Declare a getter method and add it to the list of methods
457 // for this class.
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000458 GetterDecl =
459 ObjCMethodDecl::Create(Context, property->getLocation(),
460 property->getLocation(),
461 property->getGetterName(),
462 property->getType(),
Daniel Dunbar7b473222008-08-27 02:09:39 +0000463 D,
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000464 true, false, true, ObjCMethodDecl::Required);
465 insMethods.push_back(GetterDecl);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000466 }
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000467 property->setGetterMethodDecl(GetterDecl);
468
Daniel Dunbar394d33f2008-08-26 07:16:44 +0000469 // Skip setter if property is read-only.
470 if (property->isReadOnly())
471 return;
472
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000473 // Find the default setter and if one not found, add one.
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000474 if (!SetterDecl) {
475 // No instance method of same name as property setter name was found.
476 // Declare a setter method and add it to the list of methods
477 // for this class.
478 SetterDecl =
479 ObjCMethodDecl::Create(Context, property->getLocation(),
480 property->getLocation(),
481 property->getSetterName(),
Daniel Dunbar5fa63312008-08-26 02:53:23 +0000482 Context.VoidTy,
Daniel Dunbar7b473222008-08-27 02:09:39 +0000483 D,
Daniel Dunbar4d7da2f2008-08-26 02:32:45 +0000484 true, false, true, ObjCMethodDecl::Required);
485 insMethods.push_back(SetterDecl);
486
487 // Invent the arguments for the setter. We don't bother making a
488 // nice name for the argument.
489 ParmVarDecl *Argument = ParmVarDecl::Create(Context,
490 SetterDecl,
491 SourceLocation(),
492 property->getIdentifier(),
493 property->getType(),
494 VarDecl::None,
495 0, 0);
496 SetterDecl->setMethodParams(&Argument, 1);
497 }
498 property->setSetterMethodDecl(SetterDecl);
Fariborz Jahanian33de3f02008-05-07 17:43:59 +0000499}
500
Daniel Dunbar7b473222008-08-27 02:09:39 +0000501/// addPropertyMethods - Goes through list of properties declared in this class
502/// and builds setter/getter method declartions depending on the setter/getter
503/// attributes of the property.
504///
505void ObjCInterfaceDecl::addPropertyMethods(
506 ASTContext &Context,
507 ObjCPropertyDecl *property,
508 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
509 ::addPropertyMethods(this, Context, property, insMethods);
510}
511
512/// addPropertyMethods - Goes through list of properties declared in this class
513/// and builds setter/getter method declartions depending on the setter/getter
514/// attributes of the property.
515///
516void ObjCCategoryDecl::addPropertyMethods(
517 ASTContext &Context,
518 ObjCPropertyDecl *property,
519 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
520 ::addPropertyMethods(this, Context, property, insMethods);
521}
522
523/// addPropertyMethods - Goes through list of properties declared in this class
524/// and builds setter/getter method declartions depending on the setter/getter
525/// attributes of the property.
526///
527void ObjCProtocolDecl::addPropertyMethods(
528 ASTContext &Context,
529 ObjCPropertyDecl *property,
530 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
531 ::addPropertyMethods(this, Context, property, insMethods);
532}
533
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000534/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian3dd4ba42008-04-17 18:25:18 +0000535/// ObjCProtocolDecl's PropertyDecl field.
536///
537void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
538 unsigned NumProperties) {
539 if (NumProperties == 0) return;
540
541 NumPropertyDecl = NumProperties;
542 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
543 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
544}
545
546/// addProperties - Insert property declaration AST nodes into
Fariborz Jahaniand9a3c332008-04-16 21:11:25 +0000547/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian7e7e3872008-04-16 21:08:45 +0000548///
549void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
550 unsigned NumProperties) {
551 if (NumProperties == 0) return;
552
553 NumPropertyDecl = NumProperties;
554 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
555 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
556}
557
Chris Lattner55d13b42008-03-16 21:23:50 +0000558/// addMethods - Insert instance and methods declarations into
Chris Lattner1e03a562008-03-16 00:19:01 +0000559/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
560///
561void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
562 unsigned numInsMembers,
563 ObjCMethodDecl **clsMethods,
564 unsigned numClsMembers,
565 SourceLocation endLoc) {
566 NumInstanceMethods = numInsMembers;
567 if (numInsMembers) {
568 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
569 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
570 }
571 NumClassMethods = numClsMembers;
572 if (numClsMembers) {
573 ClassMethods = new ObjCMethodDecl*[numClsMembers];
574 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
575 }
576 AtEndLoc = endLoc;
577}
578
Chris Lattner68c82cf2008-03-16 20:47:45 +0000579
580
Chris Lattner1e03a562008-03-16 00:19:01 +0000581/// addMethods - Insert instance and methods declarations into
582/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
583///
584void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
585 unsigned numInsMembers,
586 ObjCMethodDecl **clsMethods,
587 unsigned numClsMembers,
588 SourceLocation endLoc) {
589 NumInstanceMethods = numInsMembers;
590 if (numInsMembers) {
591 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
592 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
593 }
594 NumClassMethods = numClsMembers;
595 if (numClsMembers) {
596 ClassMethods = new ObjCMethodDecl*[numClsMembers];
597 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
598 }
599 AtEndLoc = endLoc;
600}
601
Fariborz Jahanian559c0c42008-04-21 19:04:53 +0000602/// FindPropertyDeclaration - Finds declaration of the property given its name
603/// in 'PropertyId' and returns it. It returns 0, if not found.
604///
605ObjCPropertyDecl *
606ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
607 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
608 E = classprop_end(); I != E; ++I) {
609 ObjCPropertyDecl *property = *I;
610 if (property->getIdentifier() == PropertyId)
611 return property;
612 }
613 return 0;
614}
615
Steve Naroff3d2c22b2008-06-05 13:55:23 +0000616/// FindPropertyDeclaration - Finds declaration of the property given its name
617/// in 'PropertyId' and returns it. It returns 0, if not found.
618///
619ObjCPropertyDecl *
620ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
621 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
622 E = classprop_end(); I != E; ++I) {
623 ObjCPropertyDecl *property = *I;
624 if (property->getIdentifier() == PropertyId)
625 return property;
626 }
627 return 0;
628}
629
Chris Lattner1e03a562008-03-16 00:19:01 +0000630ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
631 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
632 ObjCInterfaceDecl* ClassDecl = this;
633 while (ClassDecl != NULL) {
634 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
635 I != E; ++I) {
636 if ((*I)->getIdentifier() == ID) {
637 clsDeclared = ClassDecl;
638 return *I;
639 }
640 }
641 ClassDecl = ClassDecl->getSuperClass();
642 }
643 return NULL;
644}
645
646/// lookupInstanceMethod - This method returns an instance method by looking in
647/// the class, its categories, and its super classes (using a linear search).
648ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
649 ObjCInterfaceDecl* ClassDecl = this;
650 ObjCMethodDecl *MethodDecl = 0;
651
652 while (ClassDecl != NULL) {
653 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
654 return MethodDecl;
655
656 // Didn't find one yet - look through protocols.
Chris Lattner3db6cae2008-07-21 18:19:38 +0000657 const ObjCList<ObjCProtocolDecl> &Protocols =
658 ClassDecl->getReferencedProtocols();
659 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
660 E = Protocols.end(); I != E; ++I)
661 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000662 return MethodDecl;
Chris Lattner3db6cae2008-07-21 18:19:38 +0000663
Chris Lattner1e03a562008-03-16 00:19:01 +0000664 // Didn't find one yet - now look through categories.
665 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
666 while (CatDecl) {
667 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
668 return MethodDecl;
669 CatDecl = CatDecl->getNextClassCategory();
670 }
671 ClassDecl = ClassDecl->getSuperClass();
672 }
673 return NULL;
674}
675
676// lookupClassMethod - This method returns a class method by looking in the
677// class, its categories, and its super classes (using a linear search).
678ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
679 ObjCInterfaceDecl* ClassDecl = this;
680 ObjCMethodDecl *MethodDecl = 0;
681
682 while (ClassDecl != NULL) {
683 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
684 return MethodDecl;
685
686 // Didn't find one yet - look through protocols.
Chris Lattner780f3292008-07-21 21:32:27 +0000687 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
688 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner3db6cae2008-07-21 18:19:38 +0000689 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner1e03a562008-03-16 00:19:01 +0000690 return MethodDecl;
Chris Lattner780f3292008-07-21 21:32:27 +0000691
Chris Lattner1e03a562008-03-16 00:19:01 +0000692 // Didn't find one yet - now look through categories.
693 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
694 while (CatDecl) {
695 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
696 return MethodDecl;
697 CatDecl = CatDecl->getNextClassCategory();
698 }
699 ClassDecl = ClassDecl->getSuperClass();
700 }
701 return NULL;
702}
703
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000704/// getInstanceMethod - This method returns an instance method by
705/// looking in the class implementation. Unlike interfaces, we don't
706/// look outside the implementation.
707ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000708 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
709 if ((*I)->getSelector() == Sel)
710 return *I;
711 return NULL;
712}
713
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000714/// getClassMethod - This method returns a class method by looking in
715/// the class implementation. Unlike interfaces, we don't look outside
716/// the implementation.
717ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000718 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
719 I != E; ++I)
720 if ((*I)->getSelector() == Sel)
721 return *I;
722 return NULL;
723}
724
725// lookupInstanceMethod - This method returns an instance method by looking in
726// the class implementation. Unlike interfaces, we don't look outside the
727// implementation.
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000728ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000729 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
730 if ((*I)->getSelector() == Sel)
731 return *I;
732 return NULL;
733}
734
735// lookupClassMethod - This method returns an instance method by looking in
736// the class implementation. Unlike interfaces, we don't look outside the
737// implementation.
Daniel Dunbar3216dcd2008-08-26 06:53:45 +0000738ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const {
Chris Lattner1e03a562008-03-16 00:19:01 +0000739 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
740 I != E; ++I)
741 if ((*I)->getSelector() == Sel)
742 return *I;
743 return NULL;
744}
745
746// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
747// it inherited.
748ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
749 ObjCMethodDecl *MethodDecl = NULL;
750
751 if ((MethodDecl = getInstanceMethod(Sel)))
752 return MethodDecl;
753
Chris Lattner780f3292008-07-21 21:32:27 +0000754 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
755 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
756 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000757 return NULL;
758}
759
760// lookupInstanceMethod - Lookup a class method in the protocol and protocols
761// it inherited.
762ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
763 ObjCMethodDecl *MethodDecl = NULL;
764
765 if ((MethodDecl = getClassMethod(Sel)))
766 return MethodDecl;
767
Chris Lattner780f3292008-07-21 21:32:27 +0000768 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
769 if ((MethodDecl = (*I)->getClassMethod(Sel)))
770 return MethodDecl;
Chris Lattner1e03a562008-03-16 00:19:01 +0000771 return NULL;
772}
773
774/// getSynthesizedMethodSize - Compute size of synthesized method name
775/// as done be the rewrite.
776///
777unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
778 // syntesized method name is a concatenation of -/+[class-name selector]
779 // Get length of this name.
780 unsigned length = 3; // _I_ or _C_
Chris Lattner8ec03f52008-11-24 03:54:41 +0000781 length += getClassInterface()->getNameAsString().size()+1; // extra for _
Chris Lattner1e03a562008-03-16 00:19:01 +0000782 NamedDecl *MethodContext = getMethodContext();
783 if (ObjCCategoryImplDecl *CID =
784 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner8ec03f52008-11-24 03:54:41 +0000785 length += CID->getNameAsString().size()+1;
Chris Lattner077bf5e2008-11-24 03:33:13 +0000786 length += getSelector().getAsString().size(); // selector name
Chris Lattner1e03a562008-03-16 00:19:01 +0000787 return length;
788}
789
Chris Lattner56196882008-04-06 05:25:03 +0000790ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner1e03a562008-03-16 00:19:01 +0000791 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
792 return ID;
793 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
794 return CD->getClassInterface();
795 if (ObjCImplementationDecl *IMD =
Chris Lattner56196882008-04-06 05:25:03 +0000796 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000797 return IMD->getClassInterface();
Chris Lattner56196882008-04-06 05:25:03 +0000798 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner1e03a562008-03-16 00:19:01 +0000799 return CID->getClassInterface();
800 assert(false && "unknown method context");
801 return 0;
802}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000803
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000804ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
805 SourceLocation atLoc,
806 SourceLocation L,
807 ObjCPropertyDecl *property,
Daniel Dunbar9f0afd42008-08-26 04:47:31 +0000808 Kind PK,
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000809 ObjCIvarDecl *ivar) {
810 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
Daniel Dunbar9f0afd42008-08-26 04:47:31 +0000811 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, PK, ivar);
Fariborz Jahanian628b96f2008-04-23 00:06:01 +0000812}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000813
Chris Lattner0ed844b2008-04-04 06:12:32 +0000814