1 //===--- 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"
16 #include "clang/AST/Stmt.h"
17 #include "clang/AST/ASTMutationListener.h"
18 #include "llvm/ADT/STLExtras.h"
19 using namespace clang;
20
21 //===----------------------------------------------------------------------===//
22 // ObjCListBase
23 //===----------------------------------------------------------------------===//
24
set(void * const * InList,unsigned Elts,ASTContext & Ctx)25 void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
26 List = 0;
27 if (Elts == 0) return; // Setting to an empty list is a noop.
28
29
30 List = new (Ctx) void*[Elts];
31 NumElts = Elts;
32 memcpy(List, InList, sizeof(void*)*Elts);
33 }
34
set(ObjCProtocolDecl * const * InList,unsigned Elts,const SourceLocation * Locs,ASTContext & Ctx)35 void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
36 const SourceLocation *Locs, ASTContext &Ctx) {
37 if (Elts == 0)
38 return;
39
40 Locations = new (Ctx) SourceLocation[Elts];
41 memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
42 set(InList, Elts, Ctx);
43 }
44
45 //===----------------------------------------------------------------------===//
46 // ObjCInterfaceDecl
47 //===----------------------------------------------------------------------===//
48
anchor()49 void ObjCContainerDecl::anchor() { }
50
51 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
52 ///
53 ObjCIvarDecl *
getIvarDecl(IdentifierInfo * Id) const54 ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
55 lookup_const_iterator Ivar, IvarEnd;
56 for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
57 if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
58 return ivar;
59 }
60 return 0;
61 }
62
63 // Get the local instance/class method declared in this interface.
64 ObjCMethodDecl *
getMethod(Selector Sel,bool isInstance) const65 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
66 // Since instance & class methods can have the same name, the loop below
67 // ensures we get the correct method.
68 //
69 // @interface Whatever
70 // - (int) class_method;
71 // + (float) class_method;
72 // @end
73 //
74 lookup_const_iterator Meth, MethEnd;
75 for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
76 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
77 if (MD && MD->isInstanceMethod() == isInstance)
78 return MD;
79 }
80 return 0;
81 }
82
83 ObjCPropertyDecl *
findPropertyDecl(const DeclContext * DC,IdentifierInfo * propertyID)84 ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
85 IdentifierInfo *propertyID) {
86
87 DeclContext::lookup_const_iterator I, E;
88 llvm::tie(I, E) = DC->lookup(propertyID);
89 for ( ; I != E; ++I)
90 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
91 return PD;
92
93 return 0;
94 }
95
96 /// FindPropertyDeclaration - Finds declaration of the property given its name
97 /// in 'PropertyId' and returns it. It returns 0, if not found.
98 ObjCPropertyDecl *
FindPropertyDeclaration(IdentifierInfo * PropertyId) const99 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
100
101 if (ObjCPropertyDecl *PD =
102 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
103 return PD;
104
105 switch (getKind()) {
106 default:
107 break;
108 case Decl::ObjCProtocol: {
109 const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
110 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
111 E = PID->protocol_end(); I != E; ++I)
112 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
113 return P;
114 break;
115 }
116 case Decl::ObjCInterface: {
117 const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
118 // Look through categories.
119 for (ObjCCategoryDecl *Cat = OID->getCategoryList();
120 Cat; Cat = Cat->getNextClassCategory())
121 if (!Cat->IsClassExtension())
122 if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
123 return P;
124
125 // Look through protocols.
126 for (ObjCInterfaceDecl::all_protocol_iterator
127 I = OID->all_referenced_protocol_begin(),
128 E = OID->all_referenced_protocol_end(); I != E; ++I)
129 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
130 return P;
131
132 // Finally, check the super class.
133 if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
134 return superClass->FindPropertyDeclaration(PropertyId);
135 break;
136 }
137 case Decl::ObjCCategory: {
138 const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
139 // Look through protocols.
140 if (!OCD->IsClassExtension())
141 for (ObjCCategoryDecl::protocol_iterator
142 I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
143 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
144 return P;
145
146 break;
147 }
148 }
149 return 0;
150 }
151
anchor()152 void ObjCInterfaceDecl::anchor() { }
153
154 /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
155 /// with name 'PropertyId' in the primary class; including those in protocols
156 /// (direct or indirect) used by the primary class.
157 ///
158 ObjCPropertyDecl *
FindPropertyVisibleInPrimaryClass(IdentifierInfo * PropertyId) const159 ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
160 IdentifierInfo *PropertyId) const {
161 // FIXME: Should make sure no callers ever do this.
162 if (!hasDefinition())
163 return 0;
164
165 if (data().ExternallyCompleted)
166 LoadExternalDefinition();
167
168 if (ObjCPropertyDecl *PD =
169 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
170 return PD;
171
172 // Look through protocols.
173 for (ObjCInterfaceDecl::all_protocol_iterator
174 I = all_referenced_protocol_begin(),
175 E = all_referenced_protocol_end(); I != E; ++I)
176 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
177 return P;
178
179 return 0;
180 }
181
mergeClassExtensionProtocolList(ObjCProtocolDecl * const * ExtList,unsigned ExtNum,ASTContext & C)182 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
183 ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
184 ASTContext &C)
185 {
186 if (data().ExternallyCompleted)
187 LoadExternalDefinition();
188
189 if (data().AllReferencedProtocols.empty() &&
190 data().ReferencedProtocols.empty()) {
191 data().AllReferencedProtocols.set(ExtList, ExtNum, C);
192 return;
193 }
194
195 // Check for duplicate protocol in class's protocol list.
196 // This is O(n*m). But it is extremely rare and number of protocols in
197 // class or its extension are very few.
198 SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
199 for (unsigned i = 0; i < ExtNum; i++) {
200 bool protocolExists = false;
201 ObjCProtocolDecl *ProtoInExtension = ExtList[i];
202 for (all_protocol_iterator
203 p = all_referenced_protocol_begin(),
204 e = all_referenced_protocol_end(); p != e; ++p) {
205 ObjCProtocolDecl *Proto = (*p);
206 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
207 protocolExists = true;
208 break;
209 }
210 }
211 // Do we want to warn on a protocol in extension class which
212 // already exist in the class? Probably not.
213 if (!protocolExists)
214 ProtocolRefs.push_back(ProtoInExtension);
215 }
216
217 if (ProtocolRefs.empty())
218 return;
219
220 // Merge ProtocolRefs into class's protocol list;
221 for (all_protocol_iterator p = all_referenced_protocol_begin(),
222 e = all_referenced_protocol_end(); p != e; ++p) {
223 ProtocolRefs.push_back(*p);
224 }
225
226 data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
227 }
228
allocateDefinitionData()229 void ObjCInterfaceDecl::allocateDefinitionData() {
230 assert(!hasDefinition() && "ObjC class already has a definition");
231 Data = new (getASTContext()) DefinitionData();
232 Data->Definition = this;
233
234 // Make the type point at the definition, now that we have one.
235 if (TypeForDecl)
236 cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
237 }
238
startDefinition()239 void ObjCInterfaceDecl::startDefinition() {
240 allocateDefinitionData();
241
242 // Update all of the declarations with a pointer to the definition.
243 for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
244 RD != RDEnd; ++RD) {
245 if (*RD != this)
246 RD->Data = Data;
247 }
248 }
249
250 /// getFirstClassExtension - Find first class extension of the given class.
getFirstClassExtension() const251 ObjCCategoryDecl* ObjCInterfaceDecl::getFirstClassExtension() const {
252 for (ObjCCategoryDecl *CDecl = getCategoryList(); CDecl;
253 CDecl = CDecl->getNextClassCategory())
254 if (CDecl->IsClassExtension())
255 return CDecl;
256 return 0;
257 }
258
259 /// getNextClassCategory - Find next class extension in list of categories.
getNextClassExtension() const260 const ObjCCategoryDecl* ObjCCategoryDecl::getNextClassExtension() const {
261 for (const ObjCCategoryDecl *CDecl = getNextClassCategory(); CDecl;
262 CDecl = CDecl->getNextClassCategory())
263 if (CDecl->IsClassExtension())
264 return CDecl;
265 return 0;
266 }
267
lookupInstanceVariable(IdentifierInfo * ID,ObjCInterfaceDecl * & clsDeclared)268 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
269 ObjCInterfaceDecl *&clsDeclared) {
270 // FIXME: Should make sure no callers ever do this.
271 if (!hasDefinition())
272 return 0;
273
274 if (data().ExternallyCompleted)
275 LoadExternalDefinition();
276
277 ObjCInterfaceDecl* ClassDecl = this;
278 while (ClassDecl != NULL) {
279 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
280 clsDeclared = ClassDecl;
281 return I;
282 }
283 for (const ObjCCategoryDecl *CDecl = ClassDecl->getFirstClassExtension();
284 CDecl; CDecl = CDecl->getNextClassExtension()) {
285 if (ObjCIvarDecl *I = CDecl->getIvarDecl(ID)) {
286 clsDeclared = ClassDecl;
287 return I;
288 }
289 }
290
291 ClassDecl = ClassDecl->getSuperClass();
292 }
293 return NULL;
294 }
295
296 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
297 /// class whose name is passed as argument. If it is not one of the super classes
298 /// the it returns NULL.
lookupInheritedClass(const IdentifierInfo * ICName)299 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
300 const IdentifierInfo*ICName) {
301 // FIXME: Should make sure no callers ever do this.
302 if (!hasDefinition())
303 return 0;
304
305 if (data().ExternallyCompleted)
306 LoadExternalDefinition();
307
308 ObjCInterfaceDecl* ClassDecl = this;
309 while (ClassDecl != NULL) {
310 if (ClassDecl->getIdentifier() == ICName)
311 return ClassDecl;
312 ClassDecl = ClassDecl->getSuperClass();
313 }
314 return NULL;
315 }
316
317 /// lookupMethod - This method returns an instance/class method by looking in
318 /// the class, its categories, and its super classes (using a linear search).
lookupMethod(Selector Sel,bool isInstance,bool shallowCategoryLookup) const319 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
320 bool isInstance,
321 bool shallowCategoryLookup) const {
322 // FIXME: Should make sure no callers ever do this.
323 if (!hasDefinition())
324 return 0;
325
326 const ObjCInterfaceDecl* ClassDecl = this;
327 ObjCMethodDecl *MethodDecl = 0;
328
329 if (data().ExternallyCompleted)
330 LoadExternalDefinition();
331
332 while (ClassDecl != NULL) {
333 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
334 return MethodDecl;
335
336 // Didn't find one yet - look through protocols.
337 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
338 E = ClassDecl->protocol_end();
339 I != E; ++I)
340 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
341 return MethodDecl;
342
343 // Didn't find one yet - now look through categories.
344 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
345 while (CatDecl) {
346 if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
347 return MethodDecl;
348
349 if (!shallowCategoryLookup) {
350 // Didn't find one yet - look through protocols.
351 const ObjCList<ObjCProtocolDecl> &Protocols =
352 CatDecl->getReferencedProtocols();
353 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
354 E = Protocols.end(); I != E; ++I)
355 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
356 return MethodDecl;
357 }
358 CatDecl = CatDecl->getNextClassCategory();
359 }
360
361 ClassDecl = ClassDecl->getSuperClass();
362 }
363 return NULL;
364 }
365
366 // Will search "local" class/category implementations for a method decl.
367 // If failed, then we search in class's root for an instance method.
368 // Returns 0 if no method is found.
lookupPrivateMethod(const Selector & Sel,bool Instance) const369 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
370 const Selector &Sel,
371 bool Instance) const {
372 // FIXME: Should make sure no callers ever do this.
373 if (!hasDefinition())
374 return 0;
375
376 if (data().ExternallyCompleted)
377 LoadExternalDefinition();
378
379 ObjCMethodDecl *Method = 0;
380 if (ObjCImplementationDecl *ImpDecl = getImplementation())
381 Method = Instance ? ImpDecl->getInstanceMethod(Sel)
382 : ImpDecl->getClassMethod(Sel);
383
384 // Look through local category implementations associated with the class.
385 if (!Method)
386 Method = Instance ? getCategoryInstanceMethod(Sel)
387 : getCategoryClassMethod(Sel);
388
389 // Before we give up, check if the selector is an instance method.
390 // But only in the root. This matches gcc's behavior and what the
391 // runtime expects.
392 if (!Instance && !Method && !getSuperClass()) {
393 Method = lookupInstanceMethod(Sel);
394 // Look through local category implementations associated
395 // with the root class.
396 if (!Method)
397 Method = lookupPrivateMethod(Sel, true);
398 }
399
400 if (!Method && getSuperClass())
401 return getSuperClass()->lookupPrivateMethod(Sel, Instance);
402 return Method;
403 }
404
405 //===----------------------------------------------------------------------===//
406 // ObjCMethodDecl
407 //===----------------------------------------------------------------------===//
408
Create(ASTContext & C,SourceLocation beginLoc,SourceLocation endLoc,Selector SelInfo,QualType T,TypeSourceInfo * ResultTInfo,DeclContext * contextDecl,bool isInstance,bool isVariadic,bool isSynthesized,bool isImplicitlyDeclared,bool isDefined,ImplementationControl impControl,bool HasRelatedResultType)409 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
410 SourceLocation beginLoc,
411 SourceLocation endLoc,
412 Selector SelInfo, QualType T,
413 TypeSourceInfo *ResultTInfo,
414 DeclContext *contextDecl,
415 bool isInstance,
416 bool isVariadic,
417 bool isSynthesized,
418 bool isImplicitlyDeclared,
419 bool isDefined,
420 ImplementationControl impControl,
421 bool HasRelatedResultType) {
422 return new (C) ObjCMethodDecl(beginLoc, endLoc,
423 SelInfo, T, ResultTInfo, contextDecl,
424 isInstance,
425 isVariadic, isSynthesized, isImplicitlyDeclared,
426 isDefined,
427 impControl,
428 HasRelatedResultType);
429 }
430
CreateDeserialized(ASTContext & C,unsigned ID)431 ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
432 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCMethodDecl));
433 return new (Mem) ObjCMethodDecl(SourceLocation(), SourceLocation(),
434 Selector(), QualType(), 0, 0);
435 }
436
setAsRedeclaration(const ObjCMethodDecl * PrevMethod)437 void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
438 assert(PrevMethod);
439 getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
440 IsRedeclaration = true;
441 PrevMethod->HasRedeclaration = true;
442 }
443
setParamsAndSelLocs(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)444 void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
445 ArrayRef<ParmVarDecl*> Params,
446 ArrayRef<SourceLocation> SelLocs) {
447 ParamsAndSelLocs = 0;
448 NumParams = Params.size();
449 if (Params.empty() && SelLocs.empty())
450 return;
451
452 unsigned Size = sizeof(ParmVarDecl *) * NumParams +
453 sizeof(SourceLocation) * SelLocs.size();
454 ParamsAndSelLocs = C.Allocate(Size);
455 std::copy(Params.begin(), Params.end(), getParams());
456 std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
457 }
458
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const459 void ObjCMethodDecl::getSelectorLocs(
460 SmallVectorImpl<SourceLocation> &SelLocs) const {
461 for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
462 SelLocs.push_back(getSelectorLoc(i));
463 }
464
setMethodParams(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)465 void ObjCMethodDecl::setMethodParams(ASTContext &C,
466 ArrayRef<ParmVarDecl*> Params,
467 ArrayRef<SourceLocation> SelLocs) {
468 assert((!SelLocs.empty() || isImplicit()) &&
469 "No selector locs for non-implicit method");
470 if (isImplicit())
471 return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
472
473 SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params,
474 DeclEndLoc);
475 if (SelLocsKind != SelLoc_NonStandard)
476 return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
477
478 setParamsAndSelLocs(C, Params, SelLocs);
479 }
480
481 /// \brief A definition will return its interface declaration.
482 /// An interface declaration will return its definition.
483 /// Otherwise it will return itself.
getNextRedeclaration()484 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
485 ASTContext &Ctx = getASTContext();
486 ObjCMethodDecl *Redecl = 0;
487 if (HasRedeclaration)
488 Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
489 if (Redecl)
490 return Redecl;
491
492 Decl *CtxD = cast<Decl>(getDeclContext());
493
494 if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
495 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
496 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
497
498 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
499 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
500 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
501
502 } else if (ObjCImplementationDecl *ImplD =
503 dyn_cast<ObjCImplementationDecl>(CtxD)) {
504 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
505 Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
506
507 } else if (ObjCCategoryImplDecl *CImplD =
508 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
509 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
510 Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
511 }
512
513 if (!Redecl && isRedeclaration()) {
514 // This is the last redeclaration, go back to the first method.
515 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
516 isInstanceMethod());
517 }
518
519 return Redecl ? Redecl : this;
520 }
521
getCanonicalDecl()522 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
523 Decl *CtxD = cast<Decl>(getDeclContext());
524
525 if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
526 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
527 if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
528 isInstanceMethod()))
529 return MD;
530
531 } else if (ObjCCategoryImplDecl *CImplD =
532 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
533 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
534 if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
535 isInstanceMethod()))
536 return MD;
537 }
538
539 if (isRedeclaration())
540 return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
541 isInstanceMethod());
542
543 return this;
544 }
545
getLocEnd() const546 SourceLocation ObjCMethodDecl::getLocEnd() const {
547 if (Stmt *Body = getBody())
548 return Body->getLocEnd();
549 return DeclEndLoc;
550 }
551
getMethodFamily() const552 ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
553 ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
554 if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
555 return family;
556
557 // Check for an explicit attribute.
558 if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
559 // The unfortunate necessity of mapping between enums here is due
560 // to the attributes framework.
561 switch (attr->getFamily()) {
562 case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
563 case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
564 case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
565 case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
566 case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
567 case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
568 }
569 Family = static_cast<unsigned>(family);
570 return family;
571 }
572
573 family = getSelector().getMethodFamily();
574 switch (family) {
575 case OMF_None: break;
576
577 // init only has a conventional meaning for an instance method, and
578 // it has to return an object.
579 case OMF_init:
580 if (!isInstanceMethod() || !getResultType()->isObjCObjectPointerType())
581 family = OMF_None;
582 break;
583
584 // alloc/copy/new have a conventional meaning for both class and
585 // instance methods, but they require an object return.
586 case OMF_alloc:
587 case OMF_copy:
588 case OMF_mutableCopy:
589 case OMF_new:
590 if (!getResultType()->isObjCObjectPointerType())
591 family = OMF_None;
592 break;
593
594 // These selectors have a conventional meaning only for instance methods.
595 case OMF_dealloc:
596 case OMF_finalize:
597 case OMF_retain:
598 case OMF_release:
599 case OMF_autorelease:
600 case OMF_retainCount:
601 case OMF_self:
602 if (!isInstanceMethod())
603 family = OMF_None;
604 break;
605
606 case OMF_performSelector:
607 if (!isInstanceMethod() ||
608 !getResultType()->isObjCIdType())
609 family = OMF_None;
610 else {
611 unsigned noParams = param_size();
612 if (noParams < 1 || noParams > 3)
613 family = OMF_None;
614 else {
615 ObjCMethodDecl::arg_type_iterator it = arg_type_begin();
616 QualType ArgT = (*it);
617 if (!ArgT->isObjCSelType()) {
618 family = OMF_None;
619 break;
620 }
621 while (--noParams) {
622 it++;
623 ArgT = (*it);
624 if (!ArgT->isObjCIdType()) {
625 family = OMF_None;
626 break;
627 }
628 }
629 }
630 }
631 break;
632
633 }
634
635 // Cache the result.
636 Family = static_cast<unsigned>(family);
637 return family;
638 }
639
createImplicitParams(ASTContext & Context,const ObjCInterfaceDecl * OID)640 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
641 const ObjCInterfaceDecl *OID) {
642 QualType selfTy;
643 if (isInstanceMethod()) {
644 // There may be no interface context due to error in declaration
645 // of the interface (which has been reported). Recover gracefully.
646 if (OID) {
647 selfTy = Context.getObjCInterfaceType(OID);
648 selfTy = Context.getObjCObjectPointerType(selfTy);
649 } else {
650 selfTy = Context.getObjCIdType();
651 }
652 } else // we have a factory method.
653 selfTy = Context.getObjCClassType();
654
655 bool selfIsPseudoStrong = false;
656 bool selfIsConsumed = false;
657
658 if (Context.getLangOpts().ObjCAutoRefCount) {
659 if (isInstanceMethod()) {
660 selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
661
662 // 'self' is always __strong. It's actually pseudo-strong except
663 // in init methods (or methods labeled ns_consumes_self), though.
664 Qualifiers qs;
665 qs.setObjCLifetime(Qualifiers::OCL_Strong);
666 selfTy = Context.getQualifiedType(selfTy, qs);
667
668 // In addition, 'self' is const unless this is an init method.
669 if (getMethodFamily() != OMF_init && !selfIsConsumed) {
670 selfTy = selfTy.withConst();
671 selfIsPseudoStrong = true;
672 }
673 }
674 else {
675 assert(isClassMethod());
676 // 'self' is always const in class methods.
677 selfTy = selfTy.withConst();
678 selfIsPseudoStrong = true;
679 }
680 }
681
682 ImplicitParamDecl *self
683 = ImplicitParamDecl::Create(Context, this, SourceLocation(),
684 &Context.Idents.get("self"), selfTy);
685 setSelfDecl(self);
686
687 if (selfIsConsumed)
688 self->addAttr(new (Context) NSConsumedAttr(SourceLocation(), Context));
689
690 if (selfIsPseudoStrong)
691 self->setARCPseudoStrong(true);
692
693 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
694 &Context.Idents.get("_cmd"),
695 Context.getObjCSelType()));
696 }
697
getClassInterface()698 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
699 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
700 return ID;
701 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
702 return CD->getClassInterface();
703 if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
704 return IMD->getClassInterface();
705
706 assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
707 llvm_unreachable("unknown method context");
708 }
709
710 //===----------------------------------------------------------------------===//
711 // ObjCInterfaceDecl
712 //===----------------------------------------------------------------------===//
713
Create(const ASTContext & C,DeclContext * DC,SourceLocation atLoc,IdentifierInfo * Id,ObjCInterfaceDecl * PrevDecl,SourceLocation ClassLoc,bool isInternal)714 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
715 DeclContext *DC,
716 SourceLocation atLoc,
717 IdentifierInfo *Id,
718 ObjCInterfaceDecl *PrevDecl,
719 SourceLocation ClassLoc,
720 bool isInternal){
721 ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc,
722 PrevDecl, isInternal);
723 C.getObjCInterfaceType(Result, PrevDecl);
724 return Result;
725 }
726
CreateDeserialized(ASTContext & C,unsigned ID)727 ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C,
728 unsigned ID) {
729 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCInterfaceDecl));
730 return new (Mem) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(),
731 0, false);
732 }
733
734 ObjCInterfaceDecl::
ObjCInterfaceDecl(DeclContext * DC,SourceLocation atLoc,IdentifierInfo * Id,SourceLocation CLoc,ObjCInterfaceDecl * PrevDecl,bool isInternal)735 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
736 SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
737 bool isInternal)
738 : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
739 TypeForDecl(0), Data()
740 {
741 setPreviousDeclaration(PrevDecl);
742
743 // Copy the 'data' pointer over.
744 if (PrevDecl)
745 Data = PrevDecl->Data;
746
747 setImplicit(isInternal);
748 }
749
LoadExternalDefinition() const750 void ObjCInterfaceDecl::LoadExternalDefinition() const {
751 assert(data().ExternallyCompleted && "Class is not externally completed");
752 data().ExternallyCompleted = false;
753 getASTContext().getExternalSource()->CompleteType(
754 const_cast<ObjCInterfaceDecl *>(this));
755 }
756
setExternallyCompleted()757 void ObjCInterfaceDecl::setExternallyCompleted() {
758 assert(getASTContext().getExternalSource() &&
759 "Class can't be externally completed without an external source");
760 assert(hasDefinition() &&
761 "Forward declarations can't be externally completed");
762 data().ExternallyCompleted = true;
763 }
764
getImplementation() const765 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
766 if (const ObjCInterfaceDecl *Def = getDefinition()) {
767 if (data().ExternallyCompleted)
768 LoadExternalDefinition();
769
770 return getASTContext().getObjCImplementation(
771 const_cast<ObjCInterfaceDecl*>(Def));
772 }
773
774 // FIXME: Should make sure no callers ever do this.
775 return 0;
776 }
777
setImplementation(ObjCImplementationDecl * ImplD)778 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
779 getASTContext().setObjCImplementation(getDefinition(), ImplD);
780 }
781
782 /// all_declared_ivar_begin - return first ivar declared in this class,
783 /// its extensions and its implementation. Lazily build the list on first
784 /// access.
all_declared_ivar_begin()785 ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
786 // FIXME: Should make sure no callers ever do this.
787 if (!hasDefinition())
788 return 0;
789
790 if (data().IvarList)
791 return data().IvarList;
792
793 ObjCIvarDecl *curIvar = 0;
794 if (!ivar_empty()) {
795 ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
796 data().IvarList = *I; ++I;
797 for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
798 curIvar->setNextIvar(*I);
799 }
800
801 for (const ObjCCategoryDecl *CDecl = getFirstClassExtension(); CDecl;
802 CDecl = CDecl->getNextClassExtension()) {
803 if (!CDecl->ivar_empty()) {
804 ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
805 E = CDecl->ivar_end();
806 if (!data().IvarList) {
807 data().IvarList = *I; ++I;
808 curIvar = data().IvarList;
809 }
810 for ( ;I != E; curIvar = *I, ++I)
811 curIvar->setNextIvar(*I);
812 }
813 }
814
815 if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
816 if (!ImplDecl->ivar_empty()) {
817 ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
818 E = ImplDecl->ivar_end();
819 if (!data().IvarList) {
820 data().IvarList = *I; ++I;
821 curIvar = data().IvarList;
822 }
823 for ( ;I != E; curIvar = *I, ++I)
824 curIvar->setNextIvar(*I);
825 }
826 }
827 return data().IvarList;
828 }
829
830 /// FindCategoryDeclaration - Finds category declaration in the list of
831 /// categories for this class and returns it. Name of the category is passed
832 /// in 'CategoryId'. If category not found, return 0;
833 ///
834 ObjCCategoryDecl *
FindCategoryDeclaration(IdentifierInfo * CategoryId) const835 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
836 // FIXME: Should make sure no callers ever do this.
837 if (!hasDefinition())
838 return 0;
839
840 if (data().ExternallyCompleted)
841 LoadExternalDefinition();
842
843 for (ObjCCategoryDecl *Category = getCategoryList();
844 Category; Category = Category->getNextClassCategory())
845 if (Category->getIdentifier() == CategoryId)
846 return Category;
847 return 0;
848 }
849
850 ObjCMethodDecl *
getCategoryInstanceMethod(Selector Sel) const851 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
852 for (ObjCCategoryDecl *Category = getCategoryList();
853 Category; Category = Category->getNextClassCategory())
854 if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
855 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
856 return MD;
857 return 0;
858 }
859
getCategoryClassMethod(Selector Sel) const860 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
861 for (ObjCCategoryDecl *Category = getCategoryList();
862 Category; Category = Category->getNextClassCategory())
863 if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
864 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
865 return MD;
866 return 0;
867 }
868
869 /// ClassImplementsProtocol - Checks that 'lProto' protocol
870 /// has been implemented in IDecl class, its super class or categories (if
871 /// lookupCategory is true).
ClassImplementsProtocol(ObjCProtocolDecl * lProto,bool lookupCategory,bool RHSIsQualifiedID)872 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
873 bool lookupCategory,
874 bool RHSIsQualifiedID) {
875 if (!hasDefinition())
876 return false;
877
878 ObjCInterfaceDecl *IDecl = this;
879 // 1st, look up the class.
880 for (ObjCInterfaceDecl::protocol_iterator
881 PI = IDecl->protocol_begin(), E = IDecl->protocol_end(); PI != E; ++PI){
882 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
883 return true;
884 // This is dubious and is added to be compatible with gcc. In gcc, it is
885 // also allowed assigning a protocol-qualified 'id' type to a LHS object
886 // when protocol in qualified LHS is in list of protocols in the rhs 'id'
887 // object. This IMO, should be a bug.
888 // FIXME: Treat this as an extension, and flag this as an error when GCC
889 // extensions are not enabled.
890 if (RHSIsQualifiedID &&
891 getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
892 return true;
893 }
894
895 // 2nd, look up the category.
896 if (lookupCategory)
897 for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
898 CDecl = CDecl->getNextClassCategory()) {
899 for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
900 E = CDecl->protocol_end(); PI != E; ++PI)
901 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
902 return true;
903 }
904
905 // 3rd, look up the super class(s)
906 if (IDecl->getSuperClass())
907 return
908 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
909 RHSIsQualifiedID);
910
911 return false;
912 }
913
914 //===----------------------------------------------------------------------===//
915 // ObjCIvarDecl
916 //===----------------------------------------------------------------------===//
917
anchor()918 void ObjCIvarDecl::anchor() { }
919
Create(ASTContext & C,ObjCContainerDecl * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,AccessControl ac,Expr * BW,bool synthesized)920 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
921 SourceLocation StartLoc,
922 SourceLocation IdLoc, IdentifierInfo *Id,
923 QualType T, TypeSourceInfo *TInfo,
924 AccessControl ac, Expr *BW,
925 bool synthesized) {
926 if (DC) {
927 // Ivar's can only appear in interfaces, implementations (via synthesized
928 // properties), and class extensions (via direct declaration, or synthesized
929 // properties).
930 //
931 // FIXME: This should really be asserting this:
932 // (isa<ObjCCategoryDecl>(DC) &&
933 // cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
934 // but unfortunately we sometimes place ivars into non-class extension
935 // categories on error. This breaks an AST invariant, and should not be
936 // fixed.
937 assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
938 isa<ObjCCategoryDecl>(DC)) &&
939 "Invalid ivar decl context!");
940 // Once a new ivar is created in any of class/class-extension/implementation
941 // decl contexts, the previously built IvarList must be rebuilt.
942 ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
943 if (!ID) {
944 if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
945 ID = IM->getClassInterface();
946 else
947 ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
948 }
949 ID->setIvarList(0);
950 }
951
952 return new (C) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo,
953 ac, BW, synthesized);
954 }
955
CreateDeserialized(ASTContext & C,unsigned ID)956 ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
957 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCIvarDecl));
958 return new (Mem) ObjCIvarDecl(0, SourceLocation(), SourceLocation(), 0,
959 QualType(), 0, ObjCIvarDecl::None, 0, false);
960 }
961
getContainingInterface() const962 const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
963 const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
964
965 switch (DC->getKind()) {
966 default:
967 case ObjCCategoryImpl:
968 case ObjCProtocol:
969 llvm_unreachable("invalid ivar container!");
970
971 // Ivars can only appear in class extension categories.
972 case ObjCCategory: {
973 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
974 assert(CD->IsClassExtension() && "invalid container for ivar!");
975 return CD->getClassInterface();
976 }
977
978 case ObjCImplementation:
979 return cast<ObjCImplementationDecl>(DC)->getClassInterface();
980
981 case ObjCInterface:
982 return cast<ObjCInterfaceDecl>(DC);
983 }
984 }
985
986 //===----------------------------------------------------------------------===//
987 // ObjCAtDefsFieldDecl
988 //===----------------------------------------------------------------------===//
989
anchor()990 void ObjCAtDefsFieldDecl::anchor() { }
991
992 ObjCAtDefsFieldDecl
Create(ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,Expr * BW)993 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
994 SourceLocation StartLoc, SourceLocation IdLoc,
995 IdentifierInfo *Id, QualType T, Expr *BW) {
996 return new (C) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
997 }
998
CreateDeserialized(ASTContext & C,unsigned ID)999 ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
1000 unsigned ID) {
1001 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCAtDefsFieldDecl));
1002 return new (Mem) ObjCAtDefsFieldDecl(0, SourceLocation(), SourceLocation(),
1003 0, QualType(), 0);
1004 }
1005
1006 //===----------------------------------------------------------------------===//
1007 // ObjCProtocolDecl
1008 //===----------------------------------------------------------------------===//
1009
anchor()1010 void ObjCProtocolDecl::anchor() { }
1011
ObjCProtocolDecl(DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1012 ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
1013 SourceLocation nameLoc,
1014 SourceLocation atStartLoc,
1015 ObjCProtocolDecl *PrevDecl)
1016 : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data()
1017 {
1018 setPreviousDeclaration(PrevDecl);
1019 if (PrevDecl)
1020 Data = PrevDecl->Data;
1021 }
1022
Create(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1023 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
1024 IdentifierInfo *Id,
1025 SourceLocation nameLoc,
1026 SourceLocation atStartLoc,
1027 ObjCProtocolDecl *PrevDecl) {
1028 ObjCProtocolDecl *Result
1029 = new (C) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl);
1030
1031 return Result;
1032 }
1033
CreateDeserialized(ASTContext & C,unsigned ID)1034 ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
1035 unsigned ID) {
1036 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCProtocolDecl));
1037 return new (Mem) ObjCProtocolDecl(0, 0, SourceLocation(), SourceLocation(),
1038 0);
1039 }
1040
lookupProtocolNamed(IdentifierInfo * Name)1041 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
1042 ObjCProtocolDecl *PDecl = this;
1043
1044 if (Name == getIdentifier())
1045 return PDecl;
1046
1047 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1048 if ((PDecl = (*I)->lookupProtocolNamed(Name)))
1049 return PDecl;
1050
1051 return NULL;
1052 }
1053
1054 // lookupMethod - Lookup a instance/class method in the protocol and protocols
1055 // it inherited.
lookupMethod(Selector Sel,bool isInstance) const1056 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
1057 bool isInstance) const {
1058 ObjCMethodDecl *MethodDecl = NULL;
1059
1060 if ((MethodDecl = getMethod(Sel, isInstance)))
1061 return MethodDecl;
1062
1063 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1064 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
1065 return MethodDecl;
1066 return NULL;
1067 }
1068
allocateDefinitionData()1069 void ObjCProtocolDecl::allocateDefinitionData() {
1070 assert(!Data && "Protocol already has a definition!");
1071 Data = new (getASTContext()) DefinitionData;
1072 Data->Definition = this;
1073 }
1074
startDefinition()1075 void ObjCProtocolDecl::startDefinition() {
1076 allocateDefinitionData();
1077
1078 // Update all of the declarations with a pointer to the definition.
1079 for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
1080 RD != RDEnd; ++RD)
1081 RD->Data = this->Data;
1082 }
1083
1084 //===----------------------------------------------------------------------===//
1085 // ObjCCategoryDecl
1086 //===----------------------------------------------------------------------===//
1087
anchor()1088 void ObjCCategoryDecl::anchor() { }
1089
Create(ASTContext & C,DeclContext * DC,SourceLocation AtLoc,SourceLocation ClassNameLoc,SourceLocation CategoryNameLoc,IdentifierInfo * Id,ObjCInterfaceDecl * IDecl,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)1090 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
1091 SourceLocation AtLoc,
1092 SourceLocation ClassNameLoc,
1093 SourceLocation CategoryNameLoc,
1094 IdentifierInfo *Id,
1095 ObjCInterfaceDecl *IDecl,
1096 SourceLocation IvarLBraceLoc,
1097 SourceLocation IvarRBraceLoc) {
1098 ObjCCategoryDecl *CatDecl = new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc,
1099 CategoryNameLoc, Id,
1100 IDecl,
1101 IvarLBraceLoc, IvarRBraceLoc);
1102 if (IDecl) {
1103 // Link this category into its class's category list.
1104 CatDecl->NextClassCategory = IDecl->getCategoryList();
1105 if (IDecl->hasDefinition()) {
1106 IDecl->setCategoryList(CatDecl);
1107 if (ASTMutationListener *L = C.getASTMutationListener())
1108 L->AddedObjCCategoryToInterface(CatDecl, IDecl);
1109 }
1110 }
1111
1112 return CatDecl;
1113 }
1114
CreateDeserialized(ASTContext & C,unsigned ID)1115 ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
1116 unsigned ID) {
1117 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryDecl));
1118 return new (Mem) ObjCCategoryDecl(0, SourceLocation(), SourceLocation(),
1119 SourceLocation(), 0, 0);
1120 }
1121
getImplementation() const1122 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
1123 return getASTContext().getObjCImplementation(
1124 const_cast<ObjCCategoryDecl*>(this));
1125 }
1126
setImplementation(ObjCCategoryImplDecl * ImplD)1127 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
1128 getASTContext().setObjCImplementation(this, ImplD);
1129 }
1130
1131
1132 //===----------------------------------------------------------------------===//
1133 // ObjCCategoryImplDecl
1134 //===----------------------------------------------------------------------===//
1135
anchor()1136 void ObjCCategoryImplDecl::anchor() { }
1137
1138 ObjCCategoryImplDecl *
Create(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,ObjCInterfaceDecl * ClassInterface,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation CategoryNameLoc)1139 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
1140 IdentifierInfo *Id,
1141 ObjCInterfaceDecl *ClassInterface,
1142 SourceLocation nameLoc,
1143 SourceLocation atStartLoc,
1144 SourceLocation CategoryNameLoc) {
1145 if (ClassInterface && ClassInterface->hasDefinition())
1146 ClassInterface = ClassInterface->getDefinition();
1147 return new (C) ObjCCategoryImplDecl(DC, Id, ClassInterface,
1148 nameLoc, atStartLoc, CategoryNameLoc);
1149 }
1150
CreateDeserialized(ASTContext & C,unsigned ID)1151 ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
1152 unsigned ID) {
1153 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryImplDecl));
1154 return new (Mem) ObjCCategoryImplDecl(0, 0, 0, SourceLocation(),
1155 SourceLocation(), SourceLocation());
1156 }
1157
getCategoryDecl() const1158 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
1159 // The class interface might be NULL if we are working with invalid code.
1160 if (const ObjCInterfaceDecl *ID = getClassInterface())
1161 return ID->FindCategoryDeclaration(getIdentifier());
1162 return 0;
1163 }
1164
1165
anchor()1166 void ObjCImplDecl::anchor() { }
1167
addPropertyImplementation(ObjCPropertyImplDecl * property)1168 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
1169 // FIXME: The context should be correct before we get here.
1170 property->setLexicalDeclContext(this);
1171 addDecl(property);
1172 }
1173
setClassInterface(ObjCInterfaceDecl * IFace)1174 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
1175 ASTContext &Ctx = getASTContext();
1176
1177 if (ObjCImplementationDecl *ImplD
1178 = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
1179 if (IFace)
1180 Ctx.setObjCImplementation(IFace, ImplD);
1181
1182 } else if (ObjCCategoryImplDecl *ImplD =
1183 dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
1184 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
1185 Ctx.setObjCImplementation(CD, ImplD);
1186 }
1187
1188 ClassInterface = IFace;
1189 }
1190
1191 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
1192 /// properties implemented in this category \@implementation block and returns
1193 /// the implemented property that uses it.
1194 ///
1195 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplIvarDecl(IdentifierInfo * ivarId) const1196 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
1197 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
1198 ObjCPropertyImplDecl *PID = *i;
1199 if (PID->getPropertyIvarDecl() &&
1200 PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
1201 return PID;
1202 }
1203 return 0;
1204 }
1205
1206 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
1207 /// added to the list of those properties \@synthesized/\@dynamic in this
1208 /// category \@implementation block.
1209 ///
1210 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplDecl(IdentifierInfo * Id) const1211 FindPropertyImplDecl(IdentifierInfo *Id) const {
1212 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
1213 ObjCPropertyImplDecl *PID = *i;
1214 if (PID->getPropertyDecl()->getIdentifier() == Id)
1215 return PID;
1216 }
1217 return 0;
1218 }
1219
operator <<(raw_ostream & OS,const ObjCCategoryImplDecl & CID)1220 raw_ostream &clang::operator<<(raw_ostream &OS,
1221 const ObjCCategoryImplDecl &CID) {
1222 OS << CID.getName();
1223 return OS;
1224 }
1225
1226 //===----------------------------------------------------------------------===//
1227 // ObjCImplementationDecl
1228 //===----------------------------------------------------------------------===//
1229
anchor()1230 void ObjCImplementationDecl::anchor() { }
1231
1232 ObjCImplementationDecl *
Create(ASTContext & C,DeclContext * DC,ObjCInterfaceDecl * ClassInterface,ObjCInterfaceDecl * SuperDecl,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)1233 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
1234 ObjCInterfaceDecl *ClassInterface,
1235 ObjCInterfaceDecl *SuperDecl,
1236 SourceLocation nameLoc,
1237 SourceLocation atStartLoc,
1238 SourceLocation IvarLBraceLoc,
1239 SourceLocation IvarRBraceLoc) {
1240 if (ClassInterface && ClassInterface->hasDefinition())
1241 ClassInterface = ClassInterface->getDefinition();
1242 return new (C) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
1243 nameLoc, atStartLoc,
1244 IvarLBraceLoc, IvarRBraceLoc);
1245 }
1246
1247 ObjCImplementationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1248 ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1249 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCImplementationDecl));
1250 return new (Mem) ObjCImplementationDecl(0, 0, 0, SourceLocation(),
1251 SourceLocation());
1252 }
1253
setIvarInitializers(ASTContext & C,CXXCtorInitializer ** initializers,unsigned numInitializers)1254 void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
1255 CXXCtorInitializer ** initializers,
1256 unsigned numInitializers) {
1257 if (numInitializers > 0) {
1258 NumIvarInitializers = numInitializers;
1259 CXXCtorInitializer **ivarInitializers =
1260 new (C) CXXCtorInitializer*[NumIvarInitializers];
1261 memcpy(ivarInitializers, initializers,
1262 numInitializers * sizeof(CXXCtorInitializer*));
1263 IvarInitializers = ivarInitializers;
1264 }
1265 }
1266
operator <<(raw_ostream & OS,const ObjCImplementationDecl & ID)1267 raw_ostream &clang::operator<<(raw_ostream &OS,
1268 const ObjCImplementationDecl &ID) {
1269 OS << ID.getName();
1270 return OS;
1271 }
1272
1273 //===----------------------------------------------------------------------===//
1274 // ObjCCompatibleAliasDecl
1275 //===----------------------------------------------------------------------===//
1276
anchor()1277 void ObjCCompatibleAliasDecl::anchor() { }
1278
1279 ObjCCompatibleAliasDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,IdentifierInfo * Id,ObjCInterfaceDecl * AliasedClass)1280 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
1281 SourceLocation L,
1282 IdentifierInfo *Id,
1283 ObjCInterfaceDecl* AliasedClass) {
1284 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
1285 }
1286
1287 ObjCCompatibleAliasDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1288 ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1289 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCompatibleAliasDecl));
1290 return new (Mem) ObjCCompatibleAliasDecl(0, SourceLocation(), 0, 0);
1291 }
1292
1293 //===----------------------------------------------------------------------===//
1294 // ObjCPropertyDecl
1295 //===----------------------------------------------------------------------===//
1296
anchor()1297 void ObjCPropertyDecl::anchor() { }
1298
Create(ASTContext & C,DeclContext * DC,SourceLocation L,IdentifierInfo * Id,SourceLocation AtLoc,SourceLocation LParenLoc,TypeSourceInfo * T,PropertyControl propControl)1299 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
1300 SourceLocation L,
1301 IdentifierInfo *Id,
1302 SourceLocation AtLoc,
1303 SourceLocation LParenLoc,
1304 TypeSourceInfo *T,
1305 PropertyControl propControl) {
1306 return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
1307 }
1308
CreateDeserialized(ASTContext & C,unsigned ID)1309 ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
1310 unsigned ID) {
1311 void * Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyDecl));
1312 return new (Mem) ObjCPropertyDecl(0, SourceLocation(), 0, SourceLocation(),
1313 SourceLocation(),
1314 0);
1315 }
1316
1317 //===----------------------------------------------------------------------===//
1318 // ObjCPropertyImplDecl
1319 //===----------------------------------------------------------------------===//
1320
Create(ASTContext & C,DeclContext * DC,SourceLocation atLoc,SourceLocation L,ObjCPropertyDecl * property,Kind PK,ObjCIvarDecl * ivar,SourceLocation ivarLoc)1321 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
1322 DeclContext *DC,
1323 SourceLocation atLoc,
1324 SourceLocation L,
1325 ObjCPropertyDecl *property,
1326 Kind PK,
1327 ObjCIvarDecl *ivar,
1328 SourceLocation ivarLoc) {
1329 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
1330 ivarLoc);
1331 }
1332
CreateDeserialized(ASTContext & C,unsigned ID)1333 ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
1334 unsigned ID) {
1335 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyImplDecl));
1336 return new (Mem) ObjCPropertyImplDecl(0, SourceLocation(), SourceLocation(),
1337 0, Dynamic, 0, SourceLocation());
1338 }
1339
getSourceRange() const1340 SourceRange ObjCPropertyImplDecl::getSourceRange() const {
1341 SourceLocation EndLoc = getLocation();
1342 if (IvarLoc.isValid())
1343 EndLoc = IvarLoc;
1344
1345 return SourceRange(AtLoc, EndLoc);
1346 }
1347