blob: dcb53e8c426e973483970f7fe8a3042d17b17395 [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"
16using namespace clang;
17
Chris Lattner114add62008-03-16 00:49:28 +000018//===----------------------------------------------------------------------===//
19// ObjC Decl Allocation/Deallocation Method Implementations
20//===----------------------------------------------------------------------===//
21
22ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc,
23 SourceLocation endLoc,
24 Selector SelInfo, QualType T,
25 Decl *contextDecl,
Chris Lattner114add62008-03-16 00:49:28 +000026 AttributeList *M, bool isInstance,
27 bool isVariadic,
Chris Lattnerf7355832008-03-16 00:58:16 +000028 ImplementationControl impControl) {
Chris Lattner114add62008-03-16 00:49:28 +000029 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
30 return new (Mem) ObjCMethodDecl(beginLoc, endLoc, SelInfo, T, contextDecl,
Chris Lattnerf7355832008-03-16 00:58:16 +000031 M, isInstance,
32 isVariadic, impControl);
Chris Lattner0db541b2008-03-16 01:15:50 +000033}
Chris Lattner114add62008-03-16 00:49:28 +000034
Chris Lattner0db541b2008-03-16 01:15:50 +000035ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,SourceLocation atLoc,
36 unsigned numRefProtos,
37 IdentifierInfo *Id,
38 bool ForwardDecl, bool isInternal){
39 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
40 return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos, Id, ForwardDecl,
41 isInternal);
42}
43
44ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
45 IdentifierInfo *Id, QualType T) {
46 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
47 return new (Mem) ObjCIvarDecl(L, Id, T);
Chris Lattner114add62008-03-16 00:49:28 +000048}
49
Chris Lattner180f7e22008-03-16 01:23:04 +000050ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, SourceLocation L,
51 unsigned numRefProtos,
Chris Lattner7afba9c2008-03-16 20:19:15 +000052 IdentifierInfo *Id) {
Chris Lattner180f7e22008-03-16 01:23:04 +000053 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
Chris Lattner7afba9c2008-03-16 20:19:15 +000054 return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
Chris Lattner180f7e22008-03-16 01:23:04 +000055}
56
Chris Lattnere29dc832008-03-16 20:34:23 +000057ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, SourceLocation L,
58 ObjCInterfaceDecl **Elts, unsigned nElts) {
59 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
60 return new (Mem) ObjCClassDecl(L, Elts, nElts);
61}
62
63ObjCForwardProtocolDecl *
64ObjCForwardProtocolDecl::Create(ASTContext &C, SourceLocation L,
65 ObjCProtocolDecl **Elts, unsigned NumElts) {
66 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
67 return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
68}
69
70ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, SourceLocation L,
Chris Lattnere29dc832008-03-16 20:34:23 +000071 IdentifierInfo *Id) {
72 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
Chris Lattner321b5d12008-03-16 20:47:45 +000073 return new (Mem) ObjCCategoryDecl(L, Id);
Chris Lattnere29dc832008-03-16 20:34:23 +000074}
75
Chris Lattner1b6de332008-03-16 20:53:07 +000076ObjCCategoryImplDecl *
77ObjCCategoryImplDecl::Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id,
78 ObjCInterfaceDecl *ClassInterface) {
79 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
80 return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
81}
82
83ObjCImplementationDecl *
84ObjCImplementationDecl::Create(ASTContext &C, SourceLocation L,
85 IdentifierInfo *Id,
86 ObjCInterfaceDecl *ClassInterface,
87 ObjCInterfaceDecl *SuperDecl) {
88 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
89 return new (Mem) ObjCImplementationDecl(L, Id, ClassInterface, SuperDecl);
90}
Chris Lattner10318b82008-03-16 00:19:01 +000091
Chris Lattner2d1c4312008-03-16 21:17:37 +000092ObjCCompatibleAliasDecl *
93ObjCCompatibleAliasDecl::Create(ASTContext &C, SourceLocation L,
94 IdentifierInfo *Id,
95 ObjCInterfaceDecl* AliasedClass) {
96 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
97 return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
98}
99
100ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, SourceLocation L) {
101 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
102 return new (Mem) ObjCPropertyDecl(L);
103}
104
Chris Lattner10318b82008-03-16 00:19:01 +0000105//===----------------------------------------------------------------------===//
106// Objective-C Decl Implementation
107//===----------------------------------------------------------------------===//
108
109void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
110 unsigned NumParams) {
111 assert(ParamInfo == 0 && "Already has param info!");
112
113 // Zero params -> null pointer.
114 if (NumParams) {
115 ParamInfo = new ParmVarDecl*[NumParams];
116 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
117 NumMethodParams = NumParams;
118 }
119}
120
121ObjCMethodDecl::~ObjCMethodDecl() {
122 delete[] ParamInfo;
123}
124
125/// ObjCAddInstanceVariablesToClass - Inserts instance variables
126/// into ObjCInterfaceDecl's fields.
127///
128void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
129 unsigned numIvars,
130 SourceLocation RBrac) {
131 NumIvars = numIvars;
132 if (numIvars) {
133 Ivars = new ObjCIvarDecl*[numIvars];
134 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
135 }
136 setLocEnd(RBrac);
137}
138
139/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
140/// Variables (Ivars) relative to what declared in @implementation;s class.
141/// Ivars into ObjCImplementationDecl's fields.
142///
143void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
144 ObjCIvarDecl **ivars, unsigned numIvars) {
145 NumIvars = numIvars;
146 if (numIvars) {
147 Ivars = new ObjCIvarDecl*[numIvars];
148 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
149 }
150}
151
152/// addMethods - Insert instance and methods declarations into
153/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
154///
155void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
156 unsigned numInsMembers,
157 ObjCMethodDecl **clsMethods,
158 unsigned numClsMembers,
159 SourceLocation endLoc) {
160 NumInstanceMethods = numInsMembers;
161 if (numInsMembers) {
162 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
163 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
164 }
165 NumClassMethods = numClsMembers;
166 if (numClsMembers) {
167 ClassMethods = new ObjCMethodDecl*[numClsMembers];
168 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
169 }
170 AtEndLoc = endLoc;
171}
172
173/// addMethods - Insert instance and methods declarations into
174/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
175///
176void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
177 unsigned numInsMembers,
178 ObjCMethodDecl **clsMethods,
179 unsigned numClsMembers,
180 SourceLocation endLoc) {
181 NumInstanceMethods = numInsMembers;
182 if (numInsMembers) {
183 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
184 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
185 }
186 NumClassMethods = numClsMembers;
187 if (numClsMembers) {
188 ClassMethods = new ObjCMethodDecl*[numClsMembers];
189 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
190 }
191 AtEndLoc = endLoc;
192}
193
Chris Lattner321b5d12008-03-16 20:47:45 +0000194void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
195 unsigned NumRPs) {
196 assert(NumReferencedProtocols == 0 && "Protocol list already set");
197 if (NumRPs == 0) return;
198
199 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
200 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
201 NumReferencedProtocols = NumRPs;
202}
203
204
Chris Lattner10318b82008-03-16 00:19:01 +0000205/// addMethods - Insert instance and methods declarations into
206/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
207///
208void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
209 unsigned numInsMembers,
210 ObjCMethodDecl **clsMethods,
211 unsigned numClsMembers,
212 SourceLocation endLoc) {
213 NumInstanceMethods = numInsMembers;
214 if (numInsMembers) {
215 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
216 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
217 }
218 NumClassMethods = numClsMembers;
219 if (numClsMembers) {
220 ClassMethods = new ObjCMethodDecl*[numClsMembers];
221 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
222 }
223 AtEndLoc = endLoc;
224}
225
226ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
227 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
228 ObjCInterfaceDecl* ClassDecl = this;
229 while (ClassDecl != NULL) {
230 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
231 I != E; ++I) {
232 if ((*I)->getIdentifier() == ID) {
233 clsDeclared = ClassDecl;
234 return *I;
235 }
236 }
237 ClassDecl = ClassDecl->getSuperClass();
238 }
239 return NULL;
240}
241
242/// lookupInstanceMethod - This method returns an instance method by looking in
243/// the class, its categories, and its super classes (using a linear search).
244ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
245 ObjCInterfaceDecl* ClassDecl = this;
246 ObjCMethodDecl *MethodDecl = 0;
247
248 while (ClassDecl != NULL) {
249 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
250 return MethodDecl;
251
252 // Didn't find one yet - look through protocols.
253 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
254 int numProtocols = ClassDecl->getNumIntfRefProtocols();
255 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
256 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
257 return MethodDecl;
258 }
259 // Didn't find one yet - now look through categories.
260 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
261 while (CatDecl) {
262 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
263 return MethodDecl;
264 CatDecl = CatDecl->getNextClassCategory();
265 }
266 ClassDecl = ClassDecl->getSuperClass();
267 }
268 return NULL;
269}
270
271// lookupClassMethod - This method returns a class method by looking in the
272// class, its categories, and its super classes (using a linear search).
273ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
274 ObjCInterfaceDecl* ClassDecl = this;
275 ObjCMethodDecl *MethodDecl = 0;
276
277 while (ClassDecl != NULL) {
278 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
279 return MethodDecl;
280
281 // Didn't find one yet - look through protocols.
282 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
283 int numProtocols = ClassDecl->getNumIntfRefProtocols();
284 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
285 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
286 return MethodDecl;
287 }
288 // Didn't find one yet - now look through categories.
289 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
290 while (CatDecl) {
291 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
292 return MethodDecl;
293 CatDecl = CatDecl->getNextClassCategory();
294 }
295 ClassDecl = ClassDecl->getSuperClass();
296 }
297 return NULL;
298}
299
300/// lookupInstanceMethod - This method returns an instance method by looking in
301/// the class implementation. Unlike interfaces, we don't look outside the
302/// implementation.
303ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
304 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
305 if ((*I)->getSelector() == Sel)
306 return *I;
307 return NULL;
308}
309
310/// lookupClassMethod - This method returns a class method by looking in
311/// the class implementation. Unlike interfaces, we don't look outside the
312/// implementation.
313ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
314 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
315 I != E; ++I)
316 if ((*I)->getSelector() == Sel)
317 return *I;
318 return NULL;
319}
320
321// lookupInstanceMethod - This method returns an instance method by looking in
322// the class implementation. Unlike interfaces, we don't look outside the
323// implementation.
324ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
325 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
326 if ((*I)->getSelector() == Sel)
327 return *I;
328 return NULL;
329}
330
331// lookupClassMethod - This method returns an instance method by looking in
332// the class implementation. Unlike interfaces, we don't look outside the
333// implementation.
334ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
335 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
336 I != E; ++I)
337 if ((*I)->getSelector() == Sel)
338 return *I;
339 return NULL;
340}
341
342// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
343// it inherited.
344ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
345 ObjCMethodDecl *MethodDecl = NULL;
346
347 if ((MethodDecl = getInstanceMethod(Sel)))
348 return MethodDecl;
349
350 if (getNumReferencedProtocols() > 0) {
351 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
352
353 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
354 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
355 return MethodDecl;
356 }
357 }
358 return NULL;
359}
360
361// lookupInstanceMethod - Lookup a class method in the protocol and protocols
362// it inherited.
363ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
364 ObjCMethodDecl *MethodDecl = NULL;
365
366 if ((MethodDecl = getClassMethod(Sel)))
367 return MethodDecl;
368
369 if (getNumReferencedProtocols() > 0) {
370 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
371
372 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
373 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
374 return MethodDecl;
375 }
376 }
377 return NULL;
378}
379
380/// getSynthesizedMethodSize - Compute size of synthesized method name
381/// as done be the rewrite.
382///
383unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
384 // syntesized method name is a concatenation of -/+[class-name selector]
385 // Get length of this name.
386 unsigned length = 3; // _I_ or _C_
387 length += strlen(getClassInterface()->getName()) +1; // extra for _
388 NamedDecl *MethodContext = getMethodContext();
389 if (ObjCCategoryImplDecl *CID =
390 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
391 length += strlen(CID->getName()) +1;
392 length += getSelector().getName().size(); // selector name
393 return length;
394}
395
396ObjCInterfaceDecl *const ObjCMethodDecl::getClassInterface() const {
397 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
398 return ID;
399 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
400 return CD->getClassInterface();
401 if (ObjCImplementationDecl *IMD =
402 dyn_cast<ObjCImplementationDecl>(MethodContext))
403 return IMD->getClassInterface();
404 if (ObjCCategoryImplDecl *CID =
405 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
406 return CID->getClassInterface();
407 assert(false && "unknown method context");
408 return 0;
409}