blob: cd4c6fff9fa11860aa001affcc8fa097a4c7aa4e [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 Lattner10318b82008-03-16 00:19:01 +000076
77//===----------------------------------------------------------------------===//
78// Objective-C Decl Implementation
79//===----------------------------------------------------------------------===//
80
81void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
82 unsigned NumParams) {
83 assert(ParamInfo == 0 && "Already has param info!");
84
85 // Zero params -> null pointer.
86 if (NumParams) {
87 ParamInfo = new ParmVarDecl*[NumParams];
88 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
89 NumMethodParams = NumParams;
90 }
91}
92
93ObjCMethodDecl::~ObjCMethodDecl() {
94 delete[] ParamInfo;
95}
96
97/// ObjCAddInstanceVariablesToClass - Inserts instance variables
98/// into ObjCInterfaceDecl's fields.
99///
100void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars,
101 unsigned numIvars,
102 SourceLocation RBrac) {
103 NumIvars = numIvars;
104 if (numIvars) {
105 Ivars = new ObjCIvarDecl*[numIvars];
106 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
107 }
108 setLocEnd(RBrac);
109}
110
111/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance
112/// Variables (Ivars) relative to what declared in @implementation;s class.
113/// Ivars into ObjCImplementationDecl's fields.
114///
115void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl(
116 ObjCIvarDecl **ivars, unsigned numIvars) {
117 NumIvars = numIvars;
118 if (numIvars) {
119 Ivars = new ObjCIvarDecl*[numIvars];
120 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*));
121 }
122}
123
124/// addMethods - Insert instance and methods declarations into
125/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
126///
127void ObjCInterfaceDecl::addMethods(ObjCMethodDecl **insMethods,
128 unsigned numInsMembers,
129 ObjCMethodDecl **clsMethods,
130 unsigned numClsMembers,
131 SourceLocation endLoc) {
132 NumInstanceMethods = numInsMembers;
133 if (numInsMembers) {
134 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
135 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
136 }
137 NumClassMethods = numClsMembers;
138 if (numClsMembers) {
139 ClassMethods = new ObjCMethodDecl*[numClsMembers];
140 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
141 }
142 AtEndLoc = endLoc;
143}
144
145/// addMethods - Insert instance and methods declarations into
146/// ObjCProtocolDecl's ProtoInsMethods and ProtoClsMethods fields.
147///
148void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
149 unsigned numInsMembers,
150 ObjCMethodDecl **clsMethods,
151 unsigned numClsMembers,
152 SourceLocation endLoc) {
153 NumInstanceMethods = numInsMembers;
154 if (numInsMembers) {
155 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
156 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
157 }
158 NumClassMethods = numClsMembers;
159 if (numClsMembers) {
160 ClassMethods = new ObjCMethodDecl*[numClsMembers];
161 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
162 }
163 AtEndLoc = endLoc;
164}
165
Chris Lattner321b5d12008-03-16 20:47:45 +0000166void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
167 unsigned NumRPs) {
168 assert(NumReferencedProtocols == 0 && "Protocol list already set");
169 if (NumRPs == 0) return;
170
171 ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
172 memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
173 NumReferencedProtocols = NumRPs;
174}
175
176
Chris Lattner10318b82008-03-16 00:19:01 +0000177/// addMethods - Insert instance and methods declarations into
178/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
179///
180void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods,
181 unsigned numInsMembers,
182 ObjCMethodDecl **clsMethods,
183 unsigned numClsMembers,
184 SourceLocation endLoc) {
185 NumInstanceMethods = numInsMembers;
186 if (numInsMembers) {
187 InstanceMethods = new ObjCMethodDecl*[numInsMembers];
188 memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
189 }
190 NumClassMethods = numClsMembers;
191 if (numClsMembers) {
192 ClassMethods = new ObjCMethodDecl*[numClsMembers];
193 memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
194 }
195 AtEndLoc = endLoc;
196}
197
198ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
199 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
200 ObjCInterfaceDecl* ClassDecl = this;
201 while (ClassDecl != NULL) {
202 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end();
203 I != E; ++I) {
204 if ((*I)->getIdentifier() == ID) {
205 clsDeclared = ClassDecl;
206 return *I;
207 }
208 }
209 ClassDecl = ClassDecl->getSuperClass();
210 }
211 return NULL;
212}
213
214/// lookupInstanceMethod - This method returns an instance method by looking in
215/// the class, its categories, and its super classes (using a linear search).
216ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
217 ObjCInterfaceDecl* ClassDecl = this;
218 ObjCMethodDecl *MethodDecl = 0;
219
220 while (ClassDecl != NULL) {
221 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
222 return MethodDecl;
223
224 // Didn't find one yet - look through protocols.
225 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
226 int numProtocols = ClassDecl->getNumIntfRefProtocols();
227 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
228 if ((MethodDecl = protocols[pIdx]->getInstanceMethod(Sel)))
229 return MethodDecl;
230 }
231 // Didn't find one yet - now look through categories.
232 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
233 while (CatDecl) {
234 if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
235 return MethodDecl;
236 CatDecl = CatDecl->getNextClassCategory();
237 }
238 ClassDecl = ClassDecl->getSuperClass();
239 }
240 return NULL;
241}
242
243// lookupClassMethod - This method returns a class method by looking in the
244// class, its categories, and its super classes (using a linear search).
245ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
246 ObjCInterfaceDecl* ClassDecl = this;
247 ObjCMethodDecl *MethodDecl = 0;
248
249 while (ClassDecl != NULL) {
250 if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
251 return MethodDecl;
252
253 // Didn't find one yet - look through protocols.
254 ObjCProtocolDecl **protocols = ClassDecl->getReferencedProtocols();
255 int numProtocols = ClassDecl->getNumIntfRefProtocols();
256 for (int pIdx = 0; pIdx < numProtocols; pIdx++) {
257 if ((MethodDecl = protocols[pIdx]->getClassMethod(Sel)))
258 return MethodDecl;
259 }
260 // Didn't find one yet - now look through categories.
261 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
262 while (CatDecl) {
263 if ((MethodDecl = CatDecl->getClassMethod(Sel)))
264 return MethodDecl;
265 CatDecl = CatDecl->getNextClassCategory();
266 }
267 ClassDecl = ClassDecl->getSuperClass();
268 }
269 return NULL;
270}
271
272/// lookupInstanceMethod - This method returns an instance method by looking in
273/// the class implementation. Unlike interfaces, we don't look outside the
274/// implementation.
275ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) {
276 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
277 if ((*I)->getSelector() == Sel)
278 return *I;
279 return NULL;
280}
281
282/// lookupClassMethod - This method returns a class method by looking in
283/// the class implementation. Unlike interfaces, we don't look outside the
284/// implementation.
285ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) {
286 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
287 I != E; ++I)
288 if ((*I)->getSelector() == Sel)
289 return *I;
290 return NULL;
291}
292
293// lookupInstanceMethod - This method returns an instance method by looking in
294// the class implementation. Unlike interfaces, we don't look outside the
295// implementation.
296ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) {
297 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
298 if ((*I)->getSelector() == Sel)
299 return *I;
300 return NULL;
301}
302
303// lookupClassMethod - This method returns an instance method by looking in
304// the class implementation. Unlike interfaces, we don't look outside the
305// implementation.
306ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) {
307 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
308 I != E; ++I)
309 if ((*I)->getSelector() == Sel)
310 return *I;
311 return NULL;
312}
313
314// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
315// it inherited.
316ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
317 ObjCMethodDecl *MethodDecl = NULL;
318
319 if ((MethodDecl = getInstanceMethod(Sel)))
320 return MethodDecl;
321
322 if (getNumReferencedProtocols() > 0) {
323 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
324
325 for (unsigned i = 0; i < getNumReferencedProtocols(); i++) {
326 if ((MethodDecl = RefPDecl[i]->getInstanceMethod(Sel)))
327 return MethodDecl;
328 }
329 }
330 return NULL;
331}
332
333// lookupInstanceMethod - Lookup a class method in the protocol and protocols
334// it inherited.
335ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
336 ObjCMethodDecl *MethodDecl = NULL;
337
338 if ((MethodDecl = getClassMethod(Sel)))
339 return MethodDecl;
340
341 if (getNumReferencedProtocols() > 0) {
342 ObjCProtocolDecl **RefPDecl = getReferencedProtocols();
343
344 for(unsigned i = 0; i < getNumReferencedProtocols(); i++) {
345 if ((MethodDecl = RefPDecl[i]->getClassMethod(Sel)))
346 return MethodDecl;
347 }
348 }
349 return NULL;
350}
351
352/// getSynthesizedMethodSize - Compute size of synthesized method name
353/// as done be the rewrite.
354///
355unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
356 // syntesized method name is a concatenation of -/+[class-name selector]
357 // Get length of this name.
358 unsigned length = 3; // _I_ or _C_
359 length += strlen(getClassInterface()->getName()) +1; // extra for _
360 NamedDecl *MethodContext = getMethodContext();
361 if (ObjCCategoryImplDecl *CID =
362 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
363 length += strlen(CID->getName()) +1;
364 length += getSelector().getName().size(); // selector name
365 return length;
366}
367
368ObjCInterfaceDecl *const ObjCMethodDecl::getClassInterface() const {
369 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(MethodContext))
370 return ID;
371 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(MethodContext))
372 return CD->getClassInterface();
373 if (ObjCImplementationDecl *IMD =
374 dyn_cast<ObjCImplementationDecl>(MethodContext))
375 return IMD->getClassInterface();
376 if (ObjCCategoryImplDecl *CID =
377 dyn_cast<ObjCCategoryImplDecl>(MethodContext))
378 return CID->getClassInterface();
379 assert(false && "unknown method context");
380 return 0;
381}