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