blob: a01c3042d31b5396740f612020e5c1845c3bd095 [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"
16using namespace clang;
17
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000018//===----------------------------------------------------------------------===//
19// ObjC Decl Allocation/Deallocation Method Implementations
20//===----------------------------------------------------------------------===//
21
Chris Lattner0ed844b2008-04-04 06:12:32 +000022ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
23 SourceLocation beginLoc,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000024 SourceLocation endLoc,
25 Selector SelInfo, QualType T,
26 Decl *contextDecl,
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000027 AttributeList *M, bool isInstance,
28 bool isVariadic,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000029 ImplementationControl impControl) {
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000030 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000031 return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
32 SelInfo, T, contextDecl,
Chris Lattnerb06fa3b2008-03-16 00:58:16 +000033 M, isInstance,
34 isVariadic, impControl);
Chris Lattner0e77ba02008-03-16 01:15:50 +000035}
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000036
Chris Lattner0ed844b2008-04-04 06:12:32 +000037ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
38 SourceLocation atLoc,
Chris Lattner0e77ba02008-03-16 01:15:50 +000039 unsigned numRefProtos,
40 IdentifierInfo *Id,
41 bool ForwardDecl, bool isInternal){
42 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000043 return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
44 Id, ForwardDecl,
Chris Lattner0e77ba02008-03-16 01:15:50 +000045 isInternal);
46}
47
Chris Lattner0ed844b2008-04-04 06:12:32 +000048ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCInterfaceDecl *CD,
49 SourceLocation L,
Chris Lattner0e77ba02008-03-16 01:15:50 +000050 IdentifierInfo *Id, QualType T) {
51 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
Chris Lattner0ed844b2008-04-04 06:12:32 +000052 return new (Mem) ObjCIvarDecl(CD, L, Id, T);
Chris Lattner6c4ae5d2008-03-16 00:49:28 +000053}
54
Chris Lattner0ed844b2008-04-04 06:12:32 +000055ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
56 SourceLocation L,
Chris Lattnercca59d72008-03-16 01:23:04 +000057 unsigned numRefProtos,
Chris Lattnerc8581052008-03-16 20:19:15 +000058 IdentifierInfo *Id) {
Chris Lattnercca59d72008-03-16 01:23:04 +000059 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattnerc8581052008-03-16 20:19:15 +000060 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattnercca59d72008-03-16 01:23:04 +000061}
62
Chris Lattner0ed844b2008-04-04 06:12:32 +000063ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
64 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +000065 ObjCInterfaceDecl **Elts, unsigned nElts) {
66 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
67 return new (Mem) ObjCClassDecl(L, Elts, nElts);
68}
69
70ObjCForwardProtocolDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +000071ObjCForwardProtocolDecl::Create(ASTContext &C,
72 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +000073 ObjCProtocolDecl **Elts, unsigned NumElts) {
74 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
75 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
76}
77
Chris Lattner0ed844b2008-04-04 06:12:32 +000078ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
79 SourceLocation L,
Chris Lattner61f9d412008-03-16 20:34:23 +000080 IdentifierInfo *Id) {
81 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner68c82cf2008-03-16 20:47:45 +000082 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattner61f9d412008-03-16 20:34:23 +000083}
84
Chris Lattner75c9cae2008-03-16 20:53:07 +000085ObjCCategoryImplDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +000086ObjCCategoryImplDecl::Create(ASTContext &C,
87 SourceLocation L,IdentifierInfo *Id,
Chris Lattner75c9cae2008-03-16 20:53:07 +000088 ObjCInterfaceDecl *ClassInterface) {
89 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
90 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
91}
92
93ObjCImplementationDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +000094ObjCImplementationDecl::Create(ASTContext &C,
95 SourceLocation L,
Chris Lattner75c9cae2008-03-16 20:53:07 +000096 IdentifierInfo *Id,
97 ObjCInterfaceDecl *ClassInterface,
98 ObjCInterfaceDecl *SuperDecl) {
99 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
100 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
101}
Chris Lattner1e03a562008-03-16 00:19:01 +0000102
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000103ObjCCompatibleAliasDecl *
Chris Lattner0ed844b2008-04-04 06:12:32 +0000104ObjCCompatibleAliasDecl::Create(ASTContext &C,
105 SourceLocation L,
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000106 IdentifierInfo *Id,
107 ObjCInterfaceDecl* AliasedClass) {
108 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
109 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
110}
111
Chris Lattner0ed844b2008-04-04 06:12:32 +0000112ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
113 SourceLocation L) {
Chris Lattnerf8d17a52008-03-16 21:17:37 +0000114 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
115 return new (Mem) ObjCPropertyDecl(L);
116}
117
Chris Lattner1e03a562008-03-16 00:19:01 +0000118//===----------------------------------------------------------------------===//
119// Objective-C Decl Implementation
120//===----------------------------------------------------------------------===//
121
122void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
123 unsigned NumParams) {
124 assert(ParamInfo == 0 && "Already has param info!");
125
126 // Zero params -> null pointer.
127 if (NumParams) {
128 ParamInfo = new ParmVarDecl*[NumParams];
129 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
130 NumMethodParams = NumParams;
131 }
132}
133
134ObjCMethodDecl::~ObjCMethodDecl() {
135 delete[] ParamInfo;
136}
137
138/// ObjCAddInstanceVariablesToClass - Inserts instance variables
139/// into ObjCInterfaceDecl's fields.
140///
141void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
142 unsigned numIvars,
143 SourceLocation RBrac) {
144 NumIvars = numIvars;
145 if (numIvars) {
146 Ivars = new ObjCIvarDecl*[numIvars];
147 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
148 }
149 setLocEnd(RBrac);
150}
151
152/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
153/// Variables (Ivars) relative to what declared in @implementation;s class.
154/// Ivars into ObjCImplementationDecl's fields.
155///
156void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
157 ObjCIvarDecl **ivars, unsigned numIvars) {
158 NumIvars = numIvars;
159 if (numIvars) {
160 Ivars = new ObjCIvarDecl*[numIvars];
161 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
162 }
163}
164
165/// addMethods - Insert instance and methods declarations into
166/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
167///
168void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
169 unsigned numInsMembers,
170 ObjCMethodDecl **clsMethods,
171 unsigned numClsMembers,
172 SourceLocation endLoc) {
173 NumInstanceMethods = numInsMembers;
174 if (numInsMembers) {
175 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
176 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
177 }
178 NumClassMethods = numClsMembers;
179 if (numClsMembers) {
180 ClassMethods = new ObjCMethodDecl*[numClsMembers];
181 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
182 }
183 AtEndLoc = endLoc;
184}
185
186/// addMethods - Insert instance and methods declarations into
Chris Lattner55d13b42008-03-16 21:23:50 +0000187/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
188///
189void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties,
190 unsigned NumProperties) {
191 if (NumProperties == 0) return;
192
193 NumPropertyDecl = NumProperties;
194 PropertyDecl = new ObjCPropertyDecl*[NumProperties];
195 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
196}
197
198/// addMethods - Insert instance and methods declarations into
Chris Lattner1e03a562008-03-16 00:19:01 +0000199/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
200///
201void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
202 unsigned numInsMembers,
203 ObjCMethodDecl **clsMethods,
204 unsigned numClsMembers,
205 SourceLocation endLoc) {
206 NumInstanceMethods = numInsMembers;
207 if (numInsMembers) {
208 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
209 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
210 }
211 NumClassMethods = numClsMembers;
212 if (numClsMembers) {
213 ClassMethods = new ObjCMethodDecl*[numClsMembers];
214 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
215 }
216 AtEndLoc = endLoc;
217}
218
Chris Lattner68c82cf2008-03-16 20:47:45 +0000219void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
220 unsigned NumRPs) {
221 assert(NumReferencedProtocols == 0 && "Protocol list already set");
222 if (NumRPs == 0) return;
223
224 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
225 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
226 NumReferencedProtocols = NumRPs;
227}
228
229
Chris Lattner1e03a562008-03-16 00:19:01 +0000230/// addMethods - Insert instance and methods declarations into
231/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
232///
233void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
234 unsigned numInsMembers,
235 ObjCMethodDecl **clsMethods,
236 unsigned numClsMembers,
237 SourceLocation endLoc) {
238 NumInstanceMethods = numInsMembers;
239 if (numInsMembers) {
240 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
241 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
242 }
243 NumClassMethods = numClsMembers;
244 if (numClsMembers) {
245 ClassMethods = new ObjCMethodDecl*[numClsMembers];
246 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
247 }
248 AtEndLoc = endLoc;
249}
250
251ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
252 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
253 ObjCInterfaceDecl* ClassDecl = this;
254 while (ClassDecl != NULL) {
255 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
256 I != E; ++I) {
257 if ((*I)->getIdentifier() == ID) {
258 clsDeclared = ClassDecl;
259 return *I;
260 }
261 }
262 ClassDecl = ClassDecl->getSuperClass();
263 }
264 return NULL;
265}
266
267/// lookupInstanceMethod - This method returns an instance method by looking in
268/// the class, its categories, and its super classes (using a linear search).
269ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
270 ObjCInterfaceDecl* ClassDecl = this;
271 ObjCMethodDecl *MethodDecl = 0;
272
273 while (ClassDecl != NULL) {
274 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
275 return MethodDecl;
276
277 // Didn't find one yet - look through protocols.
278 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
279 int numProtocols = ClassDecl->getNumIntfRefProtocols();
280 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
281 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
282 return MethodDecl;
283 }
284 // Didn't find one yet - now look through categories.
285 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
286 while (CatDecl) {
287 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
288 return MethodDecl;
289 CatDecl = CatDecl->getNextClassCategory();
290 }
291 ClassDecl = ClassDecl->getSuperClass();
292 }
293 return NULL;
294}
295
296// lookupClassMethod - This method returns a class method by looking in the
297// class, its categories, and its super classes (using a linear search).
298ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
299 ObjCInterfaceDecl* ClassDecl = this;
300 ObjCMethodDecl *MethodDecl = 0;
301
302 while (ClassDecl != NULL) {
303 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
304 return MethodDecl;
305
306 // Didn't find one yet - look through protocols.
307 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
308 int numProtocols = ClassDecl->getNumIntfRefProtocols();
309 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
310 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
311 return MethodDecl;
312 }
313 // Didn't find one yet - now look through categories.
314 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
315 while (CatDecl) {
316 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
317 return MethodDecl;
318 CatDecl = CatDecl->getNextClassCategory();
319 }
320 ClassDecl = ClassDecl->getSuperClass();
321 }
322 return NULL;
323}
324
325/// lookupInstanceMethod - This method returns an instance method by looking in
326/// the class implementation. Unlike interfaces, we don't look outside the
327/// implementation.
328ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
329 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
330 if ((*I)->getSelector() == Sel)
331 return *I;
332 return NULL;
333}
334
335/// lookupClassMethod - This method returns a class method by looking in
336/// the class implementation. Unlike interfaces, we don't look outside the
337/// implementation.
338ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
339 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
340 I != E; ++I)
341 if ((*I)->getSelector() == Sel)
342 return *I;
343 return NULL;
344}
345
346// lookupInstanceMethod - This method returns an instance method by looking in
347// the class implementation. Unlike interfaces, we don't look outside the
348// implementation.
349ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
350 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
351 if ((*I)->getSelector() == Sel)
352 return *I;
353 return NULL;
354}
355
356// lookupClassMethod - This method returns an instance method by looking in
357// the class implementation. Unlike interfaces, we don't look outside the
358// implementation.
359ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
360 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
361 I != E; ++I)
362 if ((*I)->getSelector() == Sel)
363 return *I;
364 return NULL;
365}
366
367// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
368// it inherited.
369ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
370 ObjCMethodDecl *MethodDecl = NULL;
371
372 if ((MethodDecl = getInstanceMethod(Sel)))
373 return MethodDecl;
374
375 if (getNumReferencedProtocols() > 0) {
376 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
377
378 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
379 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
380 return MethodDecl;
381 }
382 }
383 return NULL;
384}
385
386// lookupInstanceMethod - Lookup a class method in the protocol and protocols
387// it inherited.
388ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
389 ObjCMethodDecl *MethodDecl = NULL;
390
391 if ((MethodDecl = getClassMethod(Sel)))
392 return MethodDecl;
393
394 if (getNumReferencedProtocols() > 0) {
395 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
396
397 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
398 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
399 return MethodDecl;
400 }
401 }
402 return NULL;
403}
404
405/// getSynthesizedMethodSize - Compute size of synthesized method name
406/// as done be the rewrite.
407///
408unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
409 // syntesized method name is a concatenation of -/+[class-name selector]
410 // Get length of this name.
411 unsigned length = 3; // _I_ or _C_
412 length += strlen(getClassInterface()->getName()) +1; // extra for _
413 NamedDecl *MethodContext = getMethodContext();
414 if (ObjCCategoryImplDecl *CID =
415 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
416 length += strlen(CID->getName()) +1;
417 length += getSelector().getName().size(); // selector name
418 return length;
419}
420
421ObjCInterfaceDecl *const ObjCMethodDecl::getClassInterface() const {
422 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
423 return ID;
424 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
425 return CD->getClassInterface();
426 if (ObjCImplementationDecl *IMD =
427 dyn_cast<ObjCImplementationDecl>(MethodContext))
428 return IMD->getClassInterface();
429 if (ObjCCategoryImplDecl *CID =
430 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
431 return CID->getClassInterface();
432 assert(false && "unknown method context");
433 return 0;
434}
Chris Lattnerf4af5152008-03-17 01:19:02 +0000435
436void ObjCPropertyDecl::setPropertyDeclLists(ObjCIvarDecl **Properties,
437 unsigned NumProp) {
438 assert(PropertyDecls == 0 && "Properties already set");
439 if (NumProp == 0) return;
440 NumPropertyDecls = NumProp;
441
442 PropertyDecls = new ObjCIvarDecl*[NumProp];
443 memcpy(PropertyDecls, Properties, NumProp*sizeof(ObjCIvarDecl*));
444}
445
446
Chris Lattner0ed844b2008-04-04 06:12:32 +0000447