blob: 857224f2b89fcfbd367d9b0f7b1710fd554c2f3f [file] [log] [blame]
Chris Lattner10318b82008-03-16 00:19:01 +00001//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Objective-C related Decl classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/DeclObjC.h"
15#include "clang/AST/ASTContext.h"
Daniel Dunbarde300732008-08-11 04:54:23 +000016#include "clang/AST/Stmt.h"
Chris Lattner10318b82008-03-16 00:19:01 +000017using namespace clang;
18
Chris Lattner114add62008-03-16 00:49:28 +000019//===----------------------------------------------------------------------===//
20// ObjC Decl Allocation/Deallocation Method Implementations
21//===----------------------------------------------------------------------===//
22
Chris Lattnereee57c02008-04-04 06:12:32 +000023ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
24 SourceLocation beginLoc,
Chris Lattner114add62008-03-16 00:49:28 +000025 SourceLocation endLoc,
26 Selector SelInfo, QualType T,
27 Decl *contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000028 bool isInstance,
Chris Lattner114add62008-03-16 00:49:28 +000029 bool isVariadic,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000030 bool isSynthesized,
Chris Lattnerf7355832008-03-16 00:58:16 +000031 ImplementationControl impControl) {
Chris Lattner114add62008-03-16 00:49:28 +000032 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattnereee57c02008-04-04 06:12:32 +000033 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
34 SelInfo, T, contextDecl,
Daniel Dunbard8bd6822008-08-20 18:02:42 +000035 isInstance,
Fariborz Jahanian5f2e2242008-05-07 20:53:44 +000036 isVariadic, isSynthesized, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000037}
Chris Lattner114add62008-03-16 00:49:28 +000038
Ted Kremenek8c945b12008-06-06 16:45:15 +000039ObjCMethodDecl::~ObjCMethodDecl() {
40 delete [] ParamInfo;
Ted Kremenek8c945b12008-06-06 16:45:15 +000041}
42
43void ObjCMethodDecl::Destroy(ASTContext& C) {
44 if (Body) Body->Destroy(C);
45 if (SelfDecl) SelfDecl->Destroy(C);
46
47 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
48 if (*I) (*I)->Destroy(C);
49
50 Decl::Destroy(C);
51}
52
Chris Lattnereee57c02008-04-04 06:12:32 +000053ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
54 SourceLocation atLoc,
Steve Naroff7c371742008-04-11 19:35:35 +000055 IdentifierInfo *Id,
56 SourceLocation ClassLoc,
Chris Lattner0db541b2008-03-16 01:15:50 +000057 bool ForwardDecl, bool isInternal){
58 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattner5cece462008-07-21 07:06:49 +000059 return new (Mem) ObjCInterfaceDecl(atLoc, Id, ClassLoc, ForwardDecl,
Chris Lattner0db541b2008-03-16 01:15:50 +000060 isInternal);
61}
62
Ted Kremenek8c945b12008-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 Kremenek22db1602008-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 Kremenek8c945b12008-06-06 16:45:15 +000085 Decl::Destroy(C);
86}
87
88
Chris Lattnerf3874bc2008-04-06 04:47:34 +000089ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
Ted Kremenek173dd312008-07-23 18:04:17 +000090 IdentifierInfo *Id, QualType T,
91 AccessControl ac, Expr *BW) {
Chris Lattner0db541b2008-03-16 01:15:50 +000092 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Ted Kremenek173dd312008-07-23 18:04:17 +000093 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW);
Chris Lattner114add62008-03-16 00:49:28 +000094}
95
Ted Kremeneke5bedfe2008-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 Lattnereee57c02008-04-04 06:12:32 +0000109ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
110 SourceLocation L,
Chris Lattner7afba9c2008-03-16 20:19:15 +0000111 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +0000112 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner0be08822008-07-21 21:32:27 +0000113 return new (Mem) ObjCProtocolDecl(L, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +0000114}
115
Ted Kremenekc906e5e2008-06-06 19:48:57 +0000116ObjCProtocolDecl::~ObjCProtocolDecl() {
Ted Kremenekc906e5e2008-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 Lattnereee57c02008-04-04 06:12:32 +0000140ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
141 SourceLocation L,
Chris Lattnere29dc832008-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 Kremenekff291622008-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 Lattnere29dc832008-03-16 20:34:23 +0000164ObjCForwardProtocolDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000165ObjCForwardProtocolDecl::Create(ASTContext &C,
166 SourceLocation L,
Chris Lattnere29dc832008-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 Kremenek1e5e0bf2008-06-06 21:05:33 +0000172ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() {
173 delete [] ReferencedProtocols;
174}
175
Chris Lattnereee57c02008-04-04 06:12:32 +0000176ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
177 SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +0000178 IdentifierInfo *Id) {
179 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +0000180 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +0000181}
182
Chris Lattner1b6de332008-03-16 20:53:07 +0000183ObjCCategoryImplDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000184ObjCCategoryImplDecl::Create(ASTContext &C,
185 SourceLocation L,IdentifierInfo *Id,
Chris Lattner1b6de332008-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 Lattnereee57c02008-04-04 06:12:32 +0000192ObjCImplementationDecl::Create(ASTContext &C,
193 SourceLocation L,
Chris Lattner1b6de332008-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 Lattner10318b82008-03-16 00:19:01 +0000200
Chris Lattner2d1c4312008-03-16 21:17:37 +0000201ObjCCompatibleAliasDecl *
Chris Lattnereee57c02008-04-04 06:12:32 +0000202ObjCCompatibleAliasDecl::Create(ASTContext &C,
203 SourceLocation L,
Chris Lattner2d1c4312008-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 Lattnereee57c02008-04-04 06:12:32 +0000210ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
Fariborz Jahaniane7071722008-04-11 23:40:25 +0000211 SourceLocation L,
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000212 IdentifierInfo *Id,
Fariborz Jahanian4aa72a72008-05-05 18:51:55 +0000213 QualType T,
214 PropertyControl propControl) {
Chris Lattner2d1c4312008-03-16 21:17:37 +0000215 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
Fariborz Jahanian0ceb4be2008-04-14 23:36:35 +0000216 return new (Mem) ObjCPropertyDecl(L, Id, T);
Chris Lattner2d1c4312008-03-16 21:17:37 +0000217}
218
Chris Lattner10318b82008-03-16 00:19:01 +0000219//===----------------------------------------------------------------------===//
220// Objective-C Decl Implementation
221//===----------------------------------------------------------------------===//
222
223void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
224 unsigned NumParams) {
225 assert(ParamInfo == 0 && "Already has param info!");
226
227 // Zero params -> null pointer.
228 if (NumParams) {
229 ParamInfo = new ParmVarDecl*[NumParams];
230 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
231 NumMethodParams = NumParams;
232 }
233}
234
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000235/// FindPropertyDeclaration - Finds declaration of the property given its name
236/// in 'PropertyId' and returns it. It returns 0, if not found.
237///
238ObjCPropertyDecl *
239 ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
240 for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
241 E = classprop_end(); I != E; ++I) {
242 ObjCPropertyDecl *property = *I;
243 if (property->getIdentifier() == PropertyId)
244 return property;
245 }
Steve Naroff30faf472008-06-04 04:46:04 +0000246 // Look through categories.
247 for (ObjCCategoryDecl *Category = getCategoryList();
248 Category; Category = Category->getNextClassCategory()) {
249 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
250 if (property)
251 return property;
252 }
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000253 // Look through protocols.
254 for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
255 E = protocol_end(); I != E; ++I) {
256 ObjCProtocolDecl *Protocol = *I;
257 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
258 if (property)
259 return property;
260 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000261 if (getSuperClass())
262 return getSuperClass()->FindPropertyDeclaration(PropertyId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000263 return 0;
264}
265
266/// FindCategoryDeclaration - Finds category declaration in the list of
267/// categories for this class and returns it. Name of the category is passed
268/// in 'CategoryId'. If category not found, return 0;
269///
270ObjCCategoryDecl *
271 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
272 for (ObjCCategoryDecl *Category = getCategoryList();
273 Category; Category = Category->getNextClassCategory())
274 if (Category->getIdentifier() == CategoryId)
275 return Category;
276 return 0;
277}
278
279/// FindIvarDeclaration - Find an Ivar declaration in this class given its
280/// name in 'IvarId'. On failure to find, return 0;
281///
282ObjCIvarDecl *
283 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const {
284 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(),
285 IVE = ivar_end(); IVI != IVE; ++IVI) {
286 ObjCIvarDecl* Ivar = (*IVI);
287 if (Ivar->getIdentifier() == IvarId)
288 return Ivar;
289 }
Fariborz Jahanian8acf3352008-04-21 23:57:08 +0000290 if (getSuperClass())
291 return getSuperClass()->FindIvarDeclaration(IvarId);
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000292 return 0;
293}
294
Chris Lattner10318b82008-03-16 00:19:01 +0000295/// ObjCAddInstanceVariablesToClass - Inserts instance variables
296/// into ObjCInterfaceDecl's fields.
297///
298void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
299 unsigned numIvars,
300 SourceLocation RBrac) {
301 NumIvars = numIvars;
302 if (numIvars) {
303 Ivars = new ObjCIvarDecl*[numIvars];
304 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
305 }
306 setLocEnd(RBrac);
307}
308
309/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
310/// Variables (Ivars) relative to what declared in @implementation;s class.
311/// Ivars into ObjCImplementationDecl's fields.
312///
313void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
314 ObjCIvarDecl **ivars, unsigned numIvars) {
315 NumIvars = numIvars;
316 if (numIvars) {
317 Ivars = new ObjCIvarDecl*[numIvars];
318 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
319 }
320}
321
322/// addMethods - Insert instance and methods declarations into
323/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
324///
325void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
326 unsigned numInsMembers,
327 ObjCMethodDecl **clsMethods,
328 unsigned numClsMembers,
329 SourceLocation endLoc) {
330 NumInstanceMethods = numInsMembers;
331 if (numInsMembers) {
332 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
333 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
334 }
335 NumClassMethods = numClsMembers;
336 if (numClsMembers) {
337 ClassMethods = new ObjCMethodDecl*[numClsMembers];
338 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
339 }
340 AtEndLoc = endLoc;
341}
342
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000343/// addProperties - Insert property declaration AST nodes into
344/// ObjCInterfaceDecl's PropertyDecl field.
Chris Lattnercffe3662008-03-16 21:23:50 +0000345///
346void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
347 unsigned NumProperties) {
348 if (NumProperties == 0) return;
349
350 NumPropertyDecl = NumProperties;
351 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
352 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
353}
354
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000355/// mergeProperties - Adds properties to the end of list of current properties
356/// for this class.
357
358void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties,
359 unsigned NumNewProperties) {
360 if (NumNewProperties == 0) return;
361
362 if (PropertyDecl) {
363 ObjCPropertyDecl **newPropertyDecl =
364 new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
365 ObjCPropertyDecl **buf = newPropertyDecl;
366 // put back original properties in buffer.
367 memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
368 // Add new properties to this buffer.
369 memcpy(buf+NumPropertyDecl, Properties,
370 NumNewProperties*sizeof(ObjCPropertyDecl*));
Nuno Lopes1ee78042008-05-10 10:31:54 +0000371 delete[] PropertyDecl;
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000372 PropertyDecl = newPropertyDecl;
373 NumPropertyDecl += NumNewProperties;
374 }
375 else {
Nuno Lopes1ee78042008-05-10 10:31:54 +0000376 addProperties(Properties, NumNewProperties);
Fariborz Jahanian33973a22008-05-02 19:17:30 +0000377 }
378}
379
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000380/// addPropertyMethods - Goes through list of properties declared in this class
381/// and builds setter/getter method declartions depending on the setter/getter
382/// attributes of the property.
383///
384void ObjCInterfaceDecl::addPropertyMethods(
385 ASTContext &Context,
386 ObjCPropertyDecl *property,
387 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods) {
388 // Find the default getter and if one not found, add one.
389 ObjCMethodDecl *GetterDecl = getInstanceMethod(property->getGetterName());
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000390 if (!GetterDecl) {
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000391 // No instance method of same name as property getter name was found.
392 // Declare a getter method and add it to the list of methods
393 // for this class.
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000394 GetterDecl =
395 ObjCMethodDecl::Create(Context, property->getLocation(),
396 property->getLocation(),
397 property->getGetterName(),
398 property->getType(),
399 this,
400 true, false, true, ObjCMethodDecl::Required);
401 insMethods.push_back(GetterDecl);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000402 }
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000403 property->setGetterMethodDecl(GetterDecl);
404
405 // Find the default setter and if one not found, add one.
406 ObjCMethodDecl *SetterDecl = getInstanceMethod(property->getSetterName());
407 if (!SetterDecl) {
408 // No instance method of same name as property setter name was found.
409 // Declare a setter method and add it to the list of methods
410 // for this class.
411 SetterDecl =
412 ObjCMethodDecl::Create(Context, property->getLocation(),
413 property->getLocation(),
414 property->getSetterName(),
Daniel Dunbar4b8babe2008-08-26 02:53:23 +0000415 Context.VoidTy,
Daniel Dunbar70cdeaa2008-08-26 02:32:45 +0000416 this,
417 true, false, true, ObjCMethodDecl::Required);
418 insMethods.push_back(SetterDecl);
419
420 // Invent the arguments for the setter. We don't bother making a
421 // nice name for the argument.
422 ParmVarDecl *Argument = ParmVarDecl::Create(Context,
423 SetterDecl,
424 SourceLocation(),
425 property->getIdentifier(),
426 property->getType(),
427 VarDecl::None,
428 0, 0);
429 SetterDecl->setMethodParams(&Argument, 1);
430 }
431 property->setSetterMethodDecl(SetterDecl);
Fariborz Jahaniane4534e72008-05-07 17:43:59 +0000432}
433
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000434/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian8516e9a2008-04-17 18:25:18 +0000435/// ObjCProtocolDecl's PropertyDecl field.
436///
437void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties,
438 unsigned NumProperties) {
439 if (NumProperties == 0) return;
440
441 NumPropertyDecl = NumProperties;
442 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
443 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
444}
445
446/// addProperties - Insert property declaration AST nodes into
Fariborz Jahanian5742a0f2008-04-16 21:11:25 +0000447/// ObjCCategoryDecl's PropertyDecl field.
Fariborz Jahanian52ff8442008-04-16 21:08:45 +0000448///
449void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties,
450 unsigned NumProperties) {
451 if (NumProperties == 0) return;
452
453 NumPropertyDecl = NumProperties;
454 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
455 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
456}
457
Chris Lattnercffe3662008-03-16 21:23:50 +0000458/// addMethods - Insert instance and methods declarations into
Chris Lattner10318b82008-03-16 00:19:01 +0000459/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
460///
461void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
462 unsigned numInsMembers,
463 ObjCMethodDecl **clsMethods,
464 unsigned numClsMembers,
465 SourceLocation endLoc) {
466 NumInstanceMethods = numInsMembers;
467 if (numInsMembers) {
468 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
469 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
470 }
471 NumClassMethods = numClsMembers;
472 if (numClsMembers) {
473 ClassMethods = new ObjCMethodDecl*[numClsMembers];
474 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
475 }
476 AtEndLoc = endLoc;
477}
478
Chris Lattner321b5d12008-03-16 20:47:45 +0000479
480
Chris Lattner10318b82008-03-16 00:19:01 +0000481/// addMethods - Insert instance and methods declarations into
482/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
483///
484void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
485 unsigned numInsMembers,
486 ObjCMethodDecl **clsMethods,
487 unsigned numClsMembers,
488 SourceLocation endLoc) {
489 NumInstanceMethods = numInsMembers;
490 if (numInsMembers) {
491 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
492 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
493 }
494 NumClassMethods = numClsMembers;
495 if (numClsMembers) {
496 ClassMethods = new ObjCMethodDecl*[numClsMembers];
497 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
498 }
499 AtEndLoc = endLoc;
500}
501
Fariborz Jahanianef8a3df2008-04-21 19:04:53 +0000502/// FindPropertyDeclaration - Finds declaration of the property given its name
503/// in 'PropertyId' and returns it. It returns 0, if not found.
504///
505ObjCPropertyDecl *
506ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
507 for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
508 E = classprop_end(); I != E; ++I) {
509 ObjCPropertyDecl *property = *I;
510 if (property->getIdentifier() == PropertyId)
511 return property;
512 }
513 return 0;
514}
515
Steve Naroffd1f0eb42008-06-05 13:55:23 +0000516/// FindPropertyDeclaration - Finds declaration of the property given its name
517/// in 'PropertyId' and returns it. It returns 0, if not found.
518///
519ObjCPropertyDecl *
520ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
521 for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
522 E = classprop_end(); I != E; ++I) {
523 ObjCPropertyDecl *property = *I;
524 if (property->getIdentifier() == PropertyId)
525 return property;
526 }
527 return 0;
528}
529
Chris Lattner10318b82008-03-16 00:19:01 +0000530ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
531 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
532 ObjCInterfaceDecl* ClassDecl = this;
533 while (ClassDecl != NULL) {
534 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
535 I != E; ++I) {
536 if ((*I)->getIdentifier() == ID) {
537 clsDeclared = ClassDecl;
538 return *I;
539 }
540 }
541 ClassDecl = ClassDecl->getSuperClass();
542 }
543 return NULL;
544}
545
546/// lookupInstanceMethod - This method returns an instance method by looking in
547/// the class, its categories, and its super classes (using a linear search).
548ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
549 ObjCInterfaceDecl* ClassDecl = this;
550 ObjCMethodDecl *MethodDecl = 0;
551
552 while (ClassDecl != NULL) {
553 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
554 return MethodDecl;
555
556 // Didn't find one yet - look through protocols.
Chris Lattner8bcb5252008-07-21 18:19:38 +0000557 const ObjCList<ObjCProtocolDecl> &Protocols =
558 ClassDecl->getReferencedProtocols();
559 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
560 E = Protocols.end(); I != E; ++I)
561 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000562 return MethodDecl;
Chris Lattner8bcb5252008-07-21 18:19:38 +0000563
Chris Lattner10318b82008-03-16 00:19:01 +0000564 // Didn't find one yet - now look through categories.
565 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
566 while (CatDecl) {
567 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
568 return MethodDecl;
569 CatDecl = CatDecl->getNextClassCategory();
570 }
571 ClassDecl = ClassDecl->getSuperClass();
572 }
573 return NULL;
574}
575
576// lookupClassMethod - This method returns a class method by looking in the
577// class, its categories, and its super classes (using a linear search).
578ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
579 ObjCInterfaceDecl* ClassDecl = this;
580 ObjCMethodDecl *MethodDecl = 0;
581
582 while (ClassDecl != NULL) {
583 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
584 return MethodDecl;
585
586 // Didn't find one yet - look through protocols.
Chris Lattner0be08822008-07-21 21:32:27 +0000587 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
588 E = ClassDecl->protocol_end(); I != E; ++I)
Chris Lattner8bcb5252008-07-21 18:19:38 +0000589 if ((MethodDecl = (*I)->getClassMethod(Sel)))
Chris Lattner10318b82008-03-16 00:19:01 +0000590 return MethodDecl;
Chris Lattner0be08822008-07-21 21:32:27 +0000591
Chris Lattner10318b82008-03-16 00:19:01 +0000592 // Didn't find one yet - now look through categories.
593 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
594 while (CatDecl) {
595 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
596 return MethodDecl;
597 CatDecl = CatDecl->getNextClassCategory();
598 }
599 ClassDecl = ClassDecl->getSuperClass();
600 }
601 return NULL;
602}
603
604/// lookupInstanceMethod - This method returns an instance method by looking in
605/// the class implementation. Unlike interfaces, we don't look outside the
606/// implementation.
607ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
608 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
609 if ((*I)->getSelector() == Sel)
610 return *I;
611 return NULL;
612}
613
614/// lookupClassMethod - This method returns a class method by looking in
615/// the class implementation. Unlike interfaces, we don't look outside the
616/// implementation.
617ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
618 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
619 I != E; ++I)
620 if ((*I)->getSelector() == Sel)
621 return *I;
622 return NULL;
623}
624
625// lookupInstanceMethod - This method returns an instance method by looking in
626// the class implementation. Unlike interfaces, we don't look outside the
627// implementation.
628ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
629 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
630 if ((*I)->getSelector() == Sel)
631 return *I;
632 return NULL;
633}
634
635// lookupClassMethod - This method returns an instance method by looking in
636// the class implementation. Unlike interfaces, we don't look outside the
637// implementation.
638ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
639 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
640 I != E; ++I)
641 if ((*I)->getSelector() == Sel)
642 return *I;
643 return NULL;
644}
645
646// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
647// it inherited.
648ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
649 ObjCMethodDecl *MethodDecl = NULL;
650
651 if ((MethodDecl = getInstanceMethod(Sel)))
652 return MethodDecl;
653
Chris Lattner0be08822008-07-21 21:32:27 +0000654 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
655 if ((MethodDecl = (*I)->getInstanceMethod(Sel)))
656 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000657 return NULL;
658}
659
660// lookupInstanceMethod - Lookup a class method in the protocol and protocols
661// it inherited.
662ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
663 ObjCMethodDecl *MethodDecl = NULL;
664
665 if ((MethodDecl = getClassMethod(Sel)))
666 return MethodDecl;
667
Chris Lattner0be08822008-07-21 21:32:27 +0000668 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
669 if ((MethodDecl = (*I)->getClassMethod(Sel)))
670 return MethodDecl;
Chris Lattner10318b82008-03-16 00:19:01 +0000671 return NULL;
672}
673
674/// getSynthesizedMethodSize - Compute size of synthesized method name
675/// as done be the rewrite.
676///
677unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
678 // syntesized method name is a concatenation of -/+[class-name selector]
679 // Get length of this name.
680 unsigned length = 3; // _I_ or _C_
681 length += strlen(getClassInterface()->getName()) +1; // extra for _
682 NamedDecl *MethodContext = getMethodContext();
683 if (ObjCCategoryImplDecl *CID =
684 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
685 length += strlen(CID->getName()) +1;
686 length += getSelector().getName().size(); // selector name
687 return length;
688}
689
Chris Lattner052fbcd2008-04-06 05:25:03 +0000690ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
Chris Lattner10318b82008-03-16 00:19:01 +0000691 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
692 return ID;
693 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
694 return CD->getClassInterface();
695 if (ObjCImplementationDecl *IMD =
Chris Lattner052fbcd2008-04-06 05:25:03 +0000696 dyn_cast<ObjCImplementationDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000697 return IMD->getClassInterface();
Chris Lattner052fbcd2008-04-06 05:25:03 +0000698 if (ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(MethodContext))
Chris Lattner10318b82008-03-16 00:19:01 +0000699 return CID->getClassInterface();
700 assert(false && "unknown method context");
701 return 0;
702}
Chris Lattner44859612008-03-17 01:19:02 +0000703
Fariborz Jahaniandc0569e2008-04-23 00:06:01 +0000704ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
705 SourceLocation atLoc,
706 SourceLocation L,
707 ObjCPropertyDecl *property,
708 PropertyImplKind kind,
709 ObjCIvarDecl *ivar) {
710 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>();
711 return new (Mem) ObjCPropertyImplDecl(atLoc, L, property, kind, ivar);
712}
Chris Lattner44859612008-03-17 01:19:02 +0000713
Chris Lattnereee57c02008-04-04 06:12:32 +0000714