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