• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/ASTMutationListener.h"
17 #include "clang/AST/Attr.h"
18 #include "clang/AST/Stmt.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/SmallString.h"
21 using namespace clang;
22 
23 //===----------------------------------------------------------------------===//
24 // ObjCListBase
25 //===----------------------------------------------------------------------===//
26 
set(void * const * InList,unsigned Elts,ASTContext & Ctx)27 void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
28   List = 0;
29   if (Elts == 0) return;  // Setting to an empty list is a noop.
30 
31 
32   List = new (Ctx) void*[Elts];
33   NumElts = Elts;
34   memcpy(List, InList, sizeof(void*)*Elts);
35 }
36 
set(ObjCProtocolDecl * const * InList,unsigned Elts,const SourceLocation * Locs,ASTContext & Ctx)37 void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
38                            const SourceLocation *Locs, ASTContext &Ctx) {
39   if (Elts == 0)
40     return;
41 
42   Locations = new (Ctx) SourceLocation[Elts];
43   memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
44   set(InList, Elts, Ctx);
45 }
46 
47 //===----------------------------------------------------------------------===//
48 // ObjCInterfaceDecl
49 //===----------------------------------------------------------------------===//
50 
anchor()51 void ObjCContainerDecl::anchor() { }
52 
53 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
54 ///
55 ObjCIvarDecl *
getIvarDecl(IdentifierInfo * Id) const56 ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
57   lookup_const_result R = lookup(Id);
58   for (lookup_const_iterator Ivar = R.begin(), IvarEnd = R.end();
59        Ivar != IvarEnd; ++Ivar) {
60     if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
61       return ivar;
62   }
63   return 0;
64 }
65 
66 // Get the local instance/class method declared in this interface.
67 ObjCMethodDecl *
getMethod(Selector Sel,bool isInstance) const68 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
69   // If this context is a hidden protocol definition, don't find any
70   // methods there.
71   if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
72     if (const ObjCProtocolDecl *Def = Proto->getDefinition())
73       if (Def->isHidden())
74         return 0;
75   }
76 
77   // Since instance & class methods can have the same name, the loop below
78   // ensures we get the correct method.
79   //
80   // @interface Whatever
81   // - (int) class_method;
82   // + (float) class_method;
83   // @end
84   //
85   lookup_const_result R = lookup(Sel);
86   for (lookup_const_iterator Meth = R.begin(), MethEnd = R.end();
87        Meth != MethEnd; ++Meth) {
88     ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
89     if (MD && MD->isInstanceMethod() == isInstance)
90       return MD;
91   }
92   return 0;
93 }
94 
95 ObjCPropertyDecl *
findPropertyDecl(const DeclContext * DC,IdentifierInfo * propertyID)96 ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
97                                    IdentifierInfo *propertyID) {
98   // If this context is a hidden protocol definition, don't find any
99   // property.
100   if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
101     if (const ObjCProtocolDecl *Def = Proto->getDefinition())
102       if (Def->isHidden())
103         return 0;
104   }
105 
106   DeclContext::lookup_const_result R = DC->lookup(propertyID);
107   for (DeclContext::lookup_const_iterator I = R.begin(), E = R.end(); I != E;
108        ++I)
109     if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
110       return PD;
111 
112   return 0;
113 }
114 
115 IdentifierInfo *
getDefaultSynthIvarName(ASTContext & Ctx) const116 ObjCPropertyDecl::getDefaultSynthIvarName(ASTContext &Ctx) const {
117   SmallString<128> ivarName;
118   {
119     llvm::raw_svector_ostream os(ivarName);
120     os << '_' << getIdentifier()->getName();
121   }
122   return &Ctx.Idents.get(ivarName.str());
123 }
124 
125 /// FindPropertyDeclaration - Finds declaration of the property given its name
126 /// in 'PropertyId' and returns it. It returns 0, if not found.
127 ObjCPropertyDecl *
FindPropertyDeclaration(IdentifierInfo * PropertyId) const128 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
129   // Don't find properties within hidden protocol definitions.
130   if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
131     if (const ObjCProtocolDecl *Def = Proto->getDefinition())
132       if (Def->isHidden())
133         return 0;
134   }
135 
136   if (ObjCPropertyDecl *PD =
137         ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
138     return PD;
139 
140   switch (getKind()) {
141     default:
142       break;
143     case Decl::ObjCProtocol: {
144       const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
145       for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
146            E = PID->protocol_end(); I != E; ++I)
147         if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
148           return P;
149       break;
150     }
151     case Decl::ObjCInterface: {
152       const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
153       // Look through categories (but not extensions).
154       for (ObjCInterfaceDecl::visible_categories_iterator
155              Cat = OID->visible_categories_begin(),
156              CatEnd = OID->visible_categories_end();
157            Cat != CatEnd; ++Cat) {
158         if (!Cat->IsClassExtension())
159           if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
160             return P;
161       }
162 
163       // Look through protocols.
164       for (ObjCInterfaceDecl::all_protocol_iterator
165             I = OID->all_referenced_protocol_begin(),
166             E = OID->all_referenced_protocol_end(); I != E; ++I)
167         if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
168           return P;
169 
170       // Finally, check the super class.
171       if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
172         return superClass->FindPropertyDeclaration(PropertyId);
173       break;
174     }
175     case Decl::ObjCCategory: {
176       const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
177       // Look through protocols.
178       if (!OCD->IsClassExtension())
179         for (ObjCCategoryDecl::protocol_iterator
180               I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
181         if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
182           return P;
183 
184       break;
185     }
186   }
187   return 0;
188 }
189 
anchor()190 void ObjCInterfaceDecl::anchor() { }
191 
192 /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
193 /// with name 'PropertyId' in the primary class; including those in protocols
194 /// (direct or indirect) used by the primary class.
195 ///
196 ObjCPropertyDecl *
FindPropertyVisibleInPrimaryClass(IdentifierInfo * PropertyId) const197 ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
198                                             IdentifierInfo *PropertyId) const {
199   // FIXME: Should make sure no callers ever do this.
200   if (!hasDefinition())
201     return 0;
202 
203   if (data().ExternallyCompleted)
204     LoadExternalDefinition();
205 
206   if (ObjCPropertyDecl *PD =
207       ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
208     return PD;
209 
210   // Look through protocols.
211   for (ObjCInterfaceDecl::all_protocol_iterator
212         I = all_referenced_protocol_begin(),
213         E = all_referenced_protocol_end(); I != E; ++I)
214     if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
215       return P;
216 
217   return 0;
218 }
219 
collectPropertiesToImplement(PropertyMap & PM,PropertyDeclOrder & PO) const220 void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
221                                                      PropertyDeclOrder &PO) const {
222   for (ObjCContainerDecl::prop_iterator P = prop_begin(),
223       E = prop_end(); P != E; ++P) {
224     ObjCPropertyDecl *Prop = *P;
225     PM[Prop->getIdentifier()] = Prop;
226     PO.push_back(Prop);
227   }
228   for (ObjCInterfaceDecl::all_protocol_iterator
229       PI = all_referenced_protocol_begin(),
230       E = all_referenced_protocol_end(); PI != E; ++PI)
231     (*PI)->collectPropertiesToImplement(PM, PO);
232   // Note, the properties declared only in class extensions are still copied
233   // into the main @interface's property list, and therefore we don't
234   // explicitly, have to search class extension properties.
235 }
236 
isArcWeakrefUnavailable() const237 bool ObjCInterfaceDecl::isArcWeakrefUnavailable() const {
238   const ObjCInterfaceDecl *Class = this;
239   while (Class) {
240     if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
241       return true;
242     Class = Class->getSuperClass();
243   }
244   return false;
245 }
246 
isObjCRequiresPropertyDefs() const247 const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
248   const ObjCInterfaceDecl *Class = this;
249   while (Class) {
250     if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
251       return Class;
252     Class = Class->getSuperClass();
253   }
254   return 0;
255 }
256 
mergeClassExtensionProtocolList(ObjCProtocolDecl * const * ExtList,unsigned ExtNum,ASTContext & C)257 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
258                               ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
259                               ASTContext &C)
260 {
261   if (data().ExternallyCompleted)
262     LoadExternalDefinition();
263 
264   if (data().AllReferencedProtocols.empty() &&
265       data().ReferencedProtocols.empty()) {
266     data().AllReferencedProtocols.set(ExtList, ExtNum, C);
267     return;
268   }
269 
270   // Check for duplicate protocol in class's protocol list.
271   // This is O(n*m). But it is extremely rare and number of protocols in
272   // class or its extension are very few.
273   SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
274   for (unsigned i = 0; i < ExtNum; i++) {
275     bool protocolExists = false;
276     ObjCProtocolDecl *ProtoInExtension = ExtList[i];
277     for (all_protocol_iterator
278           p = all_referenced_protocol_begin(),
279           e = all_referenced_protocol_end(); p != e; ++p) {
280       ObjCProtocolDecl *Proto = (*p);
281       if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
282         protocolExists = true;
283         break;
284       }
285     }
286     // Do we want to warn on a protocol in extension class which
287     // already exist in the class? Probably not.
288     if (!protocolExists)
289       ProtocolRefs.push_back(ProtoInExtension);
290   }
291 
292   if (ProtocolRefs.empty())
293     return;
294 
295   // Merge ProtocolRefs into class's protocol list;
296   for (all_protocol_iterator p = all_referenced_protocol_begin(),
297         e = all_referenced_protocol_end(); p != e; ++p) {
298     ProtocolRefs.push_back(*p);
299   }
300 
301   data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
302 }
303 
allocateDefinitionData()304 void ObjCInterfaceDecl::allocateDefinitionData() {
305   assert(!hasDefinition() && "ObjC class already has a definition");
306   Data.setPointer(new (getASTContext()) DefinitionData());
307   Data.getPointer()->Definition = this;
308 
309   // Make the type point at the definition, now that we have one.
310   if (TypeForDecl)
311     cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
312 }
313 
startDefinition()314 void ObjCInterfaceDecl::startDefinition() {
315   allocateDefinitionData();
316 
317   // Update all of the declarations with a pointer to the definition.
318   for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
319        RD != RDEnd; ++RD) {
320     if (*RD != this)
321       RD->Data = Data;
322   }
323 }
324 
lookupInstanceVariable(IdentifierInfo * ID,ObjCInterfaceDecl * & clsDeclared)325 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
326                                               ObjCInterfaceDecl *&clsDeclared) {
327   // FIXME: Should make sure no callers ever do this.
328   if (!hasDefinition())
329     return 0;
330 
331   if (data().ExternallyCompleted)
332     LoadExternalDefinition();
333 
334   ObjCInterfaceDecl* ClassDecl = this;
335   while (ClassDecl != NULL) {
336     if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
337       clsDeclared = ClassDecl;
338       return I;
339     }
340 
341     for (ObjCInterfaceDecl::visible_extensions_iterator
342            Ext = ClassDecl->visible_extensions_begin(),
343            ExtEnd = ClassDecl->visible_extensions_end();
344          Ext != ExtEnd; ++Ext) {
345       if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
346         clsDeclared = ClassDecl;
347         return I;
348       }
349     }
350 
351     ClassDecl = ClassDecl->getSuperClass();
352   }
353   return NULL;
354 }
355 
356 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
357 /// class whose name is passed as argument. If it is not one of the super classes
358 /// the it returns NULL.
lookupInheritedClass(const IdentifierInfo * ICName)359 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
360                                         const IdentifierInfo*ICName) {
361   // FIXME: Should make sure no callers ever do this.
362   if (!hasDefinition())
363     return 0;
364 
365   if (data().ExternallyCompleted)
366     LoadExternalDefinition();
367 
368   ObjCInterfaceDecl* ClassDecl = this;
369   while (ClassDecl != NULL) {
370     if (ClassDecl->getIdentifier() == ICName)
371       return ClassDecl;
372     ClassDecl = ClassDecl->getSuperClass();
373   }
374   return NULL;
375 }
376 
377 /// lookupMethod - This method returns an instance/class method by looking in
378 /// the class, its categories, and its super classes (using a linear search).
lookupMethod(Selector Sel,bool isInstance,bool shallowCategoryLookup) const379 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
380                                      bool isInstance,
381                                      bool shallowCategoryLookup) const {
382   // FIXME: Should make sure no callers ever do this.
383   if (!hasDefinition())
384     return 0;
385 
386   const ObjCInterfaceDecl* ClassDecl = this;
387   ObjCMethodDecl *MethodDecl = 0;
388 
389   if (data().ExternallyCompleted)
390     LoadExternalDefinition();
391 
392   while (ClassDecl != NULL) {
393     if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
394       return MethodDecl;
395 
396     // Didn't find one yet - look through protocols.
397     for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
398                                               E = ClassDecl->protocol_end();
399            I != E; ++I)
400       if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
401         return MethodDecl;
402 
403     // Didn't find one yet - now look through categories.
404     for (ObjCInterfaceDecl::visible_categories_iterator
405            Cat = ClassDecl->visible_categories_begin(),
406            CatEnd = ClassDecl->visible_categories_end();
407          Cat != CatEnd; ++Cat) {
408       if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
409         return MethodDecl;
410 
411       if (!shallowCategoryLookup) {
412         // Didn't find one yet - look through protocols.
413         const ObjCList<ObjCProtocolDecl> &Protocols =
414           Cat->getReferencedProtocols();
415         for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
416              E = Protocols.end(); I != E; ++I)
417           if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
418             return MethodDecl;
419       }
420     }
421 
422     ClassDecl = ClassDecl->getSuperClass();
423   }
424   return NULL;
425 }
426 
427 // Will search "local" class/category implementations for a method decl.
428 // If failed, then we search in class's root for an instance method.
429 // Returns 0 if no method is found.
lookupPrivateMethod(const Selector & Sel,bool Instance) const430 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
431                                    const Selector &Sel,
432                                    bool Instance) const {
433   // FIXME: Should make sure no callers ever do this.
434   if (!hasDefinition())
435     return 0;
436 
437   if (data().ExternallyCompleted)
438     LoadExternalDefinition();
439 
440   ObjCMethodDecl *Method = 0;
441   if (ObjCImplementationDecl *ImpDecl = getImplementation())
442     Method = Instance ? ImpDecl->getInstanceMethod(Sel)
443                       : ImpDecl->getClassMethod(Sel);
444 
445   // Look through local category implementations associated with the class.
446   if (!Method)
447     Method = Instance ? getCategoryInstanceMethod(Sel)
448                       : getCategoryClassMethod(Sel);
449 
450   // Before we give up, check if the selector is an instance method.
451   // But only in the root. This matches gcc's behavior and what the
452   // runtime expects.
453   if (!Instance && !Method && !getSuperClass()) {
454     Method = lookupInstanceMethod(Sel);
455     // Look through local category implementations associated
456     // with the root class.
457     if (!Method)
458       Method = lookupPrivateMethod(Sel, true);
459   }
460 
461   if (!Method && getSuperClass())
462     return getSuperClass()->lookupPrivateMethod(Sel, Instance);
463   return Method;
464 }
465 
466 //===----------------------------------------------------------------------===//
467 // ObjCMethodDecl
468 //===----------------------------------------------------------------------===//
469 
Create(ASTContext & C,SourceLocation beginLoc,SourceLocation endLoc,Selector SelInfo,QualType T,TypeSourceInfo * ResultTInfo,DeclContext * contextDecl,bool isInstance,bool isVariadic,bool isPropertyAccessor,bool isImplicitlyDeclared,bool isDefined,ImplementationControl impControl,bool HasRelatedResultType)470 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
471                                        SourceLocation beginLoc,
472                                        SourceLocation endLoc,
473                                        Selector SelInfo, QualType T,
474                                        TypeSourceInfo *ResultTInfo,
475                                        DeclContext *contextDecl,
476                                        bool isInstance,
477                                        bool isVariadic,
478                                        bool isPropertyAccessor,
479                                        bool isImplicitlyDeclared,
480                                        bool isDefined,
481                                        ImplementationControl impControl,
482                                        bool HasRelatedResultType) {
483   return new (C) ObjCMethodDecl(beginLoc, endLoc,
484                                 SelInfo, T, ResultTInfo, contextDecl,
485                                 isInstance, isVariadic, isPropertyAccessor,
486                                 isImplicitlyDeclared, isDefined,
487                                 impControl,
488                                 HasRelatedResultType);
489 }
490 
CreateDeserialized(ASTContext & C,unsigned ID)491 ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
492   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCMethodDecl));
493   return new (Mem) ObjCMethodDecl(SourceLocation(), SourceLocation(),
494                                   Selector(), QualType(), 0, 0);
495 }
496 
getBody() const497 Stmt *ObjCMethodDecl::getBody() const {
498   return Body.get(getASTContext().getExternalSource());
499 }
500 
setAsRedeclaration(const ObjCMethodDecl * PrevMethod)501 void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
502   assert(PrevMethod);
503   getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
504   IsRedeclaration = true;
505   PrevMethod->HasRedeclaration = true;
506 }
507 
setParamsAndSelLocs(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)508 void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
509                                          ArrayRef<ParmVarDecl*> Params,
510                                          ArrayRef<SourceLocation> SelLocs) {
511   ParamsAndSelLocs = 0;
512   NumParams = Params.size();
513   if (Params.empty() && SelLocs.empty())
514     return;
515 
516   unsigned Size = sizeof(ParmVarDecl *) * NumParams +
517                   sizeof(SourceLocation) * SelLocs.size();
518   ParamsAndSelLocs = C.Allocate(Size);
519   std::copy(Params.begin(), Params.end(), getParams());
520   std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
521 }
522 
getSelectorLocs(SmallVectorImpl<SourceLocation> & SelLocs) const523 void ObjCMethodDecl::getSelectorLocs(
524                                SmallVectorImpl<SourceLocation> &SelLocs) const {
525   for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
526     SelLocs.push_back(getSelectorLoc(i));
527 }
528 
setMethodParams(ASTContext & C,ArrayRef<ParmVarDecl * > Params,ArrayRef<SourceLocation> SelLocs)529 void ObjCMethodDecl::setMethodParams(ASTContext &C,
530                                      ArrayRef<ParmVarDecl*> Params,
531                                      ArrayRef<SourceLocation> SelLocs) {
532   assert((!SelLocs.empty() || isImplicit()) &&
533          "No selector locs for non-implicit method");
534   if (isImplicit())
535     return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
536 
537   SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params,
538                                         DeclEndLoc);
539   if (SelLocsKind != SelLoc_NonStandard)
540     return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
541 
542   setParamsAndSelLocs(C, Params, SelLocs);
543 }
544 
545 /// \brief A definition will return its interface declaration.
546 /// An interface declaration will return its definition.
547 /// Otherwise it will return itself.
getNextRedeclaration()548 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
549   ASTContext &Ctx = getASTContext();
550   ObjCMethodDecl *Redecl = 0;
551   if (HasRedeclaration)
552     Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
553   if (Redecl)
554     return Redecl;
555 
556   Decl *CtxD = cast<Decl>(getDeclContext());
557 
558   if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
559     if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
560       Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
561 
562   } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
563     if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
564       Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
565 
566   } else if (ObjCImplementationDecl *ImplD =
567                dyn_cast<ObjCImplementationDecl>(CtxD)) {
568     if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
569       Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
570 
571   } else if (ObjCCategoryImplDecl *CImplD =
572                dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
573     if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
574       Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
575   }
576 
577   if (!Redecl && isRedeclaration()) {
578     // This is the last redeclaration, go back to the first method.
579     return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
580                                                     isInstanceMethod());
581   }
582 
583   return Redecl ? Redecl : this;
584 }
585 
getCanonicalDecl()586 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
587   Decl *CtxD = cast<Decl>(getDeclContext());
588 
589   if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
590     if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
591       if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
592                                               isInstanceMethod()))
593         return MD;
594 
595   } else if (ObjCCategoryImplDecl *CImplD =
596                dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
597     if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
598       if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
599                                                isInstanceMethod()))
600         return MD;
601   }
602 
603   if (isRedeclaration())
604     return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
605                                                     isInstanceMethod());
606 
607   return this;
608 }
609 
getLocEnd() const610 SourceLocation ObjCMethodDecl::getLocEnd() const {
611   if (Stmt *Body = getBody())
612     return Body->getLocEnd();
613   return DeclEndLoc;
614 }
615 
getMethodFamily() const616 ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
617   ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
618   if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
619     return family;
620 
621   // Check for an explicit attribute.
622   if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
623     // The unfortunate necessity of mapping between enums here is due
624     // to the attributes framework.
625     switch (attr->getFamily()) {
626     case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
627     case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
628     case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
629     case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
630     case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
631     case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
632     }
633     Family = static_cast<unsigned>(family);
634     return family;
635   }
636 
637   family = getSelector().getMethodFamily();
638   switch (family) {
639   case OMF_None: break;
640 
641   // init only has a conventional meaning for an instance method, and
642   // it has to return an object.
643   case OMF_init:
644     if (!isInstanceMethod() || !getResultType()->isObjCObjectPointerType())
645       family = OMF_None;
646     break;
647 
648   // alloc/copy/new have a conventional meaning for both class and
649   // instance methods, but they require an object return.
650   case OMF_alloc:
651   case OMF_copy:
652   case OMF_mutableCopy:
653   case OMF_new:
654     if (!getResultType()->isObjCObjectPointerType())
655       family = OMF_None;
656     break;
657 
658   // These selectors have a conventional meaning only for instance methods.
659   case OMF_dealloc:
660   case OMF_finalize:
661   case OMF_retain:
662   case OMF_release:
663   case OMF_autorelease:
664   case OMF_retainCount:
665   case OMF_self:
666     if (!isInstanceMethod())
667       family = OMF_None;
668     break;
669 
670   case OMF_performSelector:
671     if (!isInstanceMethod() ||
672         !getResultType()->isObjCIdType())
673       family = OMF_None;
674     else {
675       unsigned noParams = param_size();
676       if (noParams < 1 || noParams > 3)
677         family = OMF_None;
678       else {
679         ObjCMethodDecl::arg_type_iterator it = arg_type_begin();
680         QualType ArgT = (*it);
681         if (!ArgT->isObjCSelType()) {
682           family = OMF_None;
683           break;
684         }
685         while (--noParams) {
686           it++;
687           ArgT = (*it);
688           if (!ArgT->isObjCIdType()) {
689             family = OMF_None;
690             break;
691           }
692         }
693       }
694     }
695     break;
696 
697   }
698 
699   // Cache the result.
700   Family = static_cast<unsigned>(family);
701   return family;
702 }
703 
createImplicitParams(ASTContext & Context,const ObjCInterfaceDecl * OID)704 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
705                                           const ObjCInterfaceDecl *OID) {
706   QualType selfTy;
707   if (isInstanceMethod()) {
708     // There may be no interface context due to error in declaration
709     // of the interface (which has been reported). Recover gracefully.
710     if (OID) {
711       selfTy = Context.getObjCInterfaceType(OID);
712       selfTy = Context.getObjCObjectPointerType(selfTy);
713     } else {
714       selfTy = Context.getObjCIdType();
715     }
716   } else // we have a factory method.
717     selfTy = Context.getObjCClassType();
718 
719   bool selfIsPseudoStrong = false;
720   bool selfIsConsumed = false;
721 
722   if (Context.getLangOpts().ObjCAutoRefCount) {
723     if (isInstanceMethod()) {
724       selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
725 
726       // 'self' is always __strong.  It's actually pseudo-strong except
727       // in init methods (or methods labeled ns_consumes_self), though.
728       Qualifiers qs;
729       qs.setObjCLifetime(Qualifiers::OCL_Strong);
730       selfTy = Context.getQualifiedType(selfTy, qs);
731 
732       // In addition, 'self' is const unless this is an init method.
733       if (getMethodFamily() != OMF_init && !selfIsConsumed) {
734         selfTy = selfTy.withConst();
735         selfIsPseudoStrong = true;
736       }
737     }
738     else {
739       assert(isClassMethod());
740       // 'self' is always const in class methods.
741       selfTy = selfTy.withConst();
742       selfIsPseudoStrong = true;
743     }
744   }
745 
746   ImplicitParamDecl *self
747     = ImplicitParamDecl::Create(Context, this, SourceLocation(),
748                                 &Context.Idents.get("self"), selfTy);
749   setSelfDecl(self);
750 
751   if (selfIsConsumed)
752     self->addAttr(new (Context) NSConsumedAttr(SourceLocation(), Context));
753 
754   if (selfIsPseudoStrong)
755     self->setARCPseudoStrong(true);
756 
757   setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
758                                        &Context.Idents.get("_cmd"),
759                                        Context.getObjCSelType()));
760 }
761 
getClassInterface()762 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
763   if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
764     return ID;
765   if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
766     return CD->getClassInterface();
767   if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
768     return IMD->getClassInterface();
769 
770   assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
771   llvm_unreachable("unknown method context");
772 }
773 
CollectOverriddenMethodsRecurse(const ObjCContainerDecl * Container,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods,bool MovedToSuper)774 static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
775                                             const ObjCMethodDecl *Method,
776                                SmallVectorImpl<const ObjCMethodDecl *> &Methods,
777                                             bool MovedToSuper) {
778   if (!Container)
779     return;
780 
781   // In categories look for overriden methods from protocols. A method from
782   // category is not "overriden" since it is considered as the "same" method
783   // (same USR) as the one from the interface.
784   if (const ObjCCategoryDecl *
785         Category = dyn_cast<ObjCCategoryDecl>(Container)) {
786     // Check whether we have a matching method at this category but only if we
787     // are at the super class level.
788     if (MovedToSuper)
789       if (ObjCMethodDecl *
790             Overridden = Container->getMethod(Method->getSelector(),
791                                               Method->isInstanceMethod()))
792         if (Method != Overridden) {
793           // We found an override at this category; there is no need to look
794           // into its protocols.
795           Methods.push_back(Overridden);
796           return;
797         }
798 
799     for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
800                                           PEnd = Category->protocol_end();
801          P != PEnd; ++P)
802       CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
803     return;
804   }
805 
806   // Check whether we have a matching method at this level.
807   if (const ObjCMethodDecl *
808         Overridden = Container->getMethod(Method->getSelector(),
809                                                     Method->isInstanceMethod()))
810     if (Method != Overridden) {
811       // We found an override at this level; there is no need to look
812       // into other protocols or categories.
813       Methods.push_back(Overridden);
814       return;
815     }
816 
817   if (const ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
818     for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
819                                           PEnd = Protocol->protocol_end();
820          P != PEnd; ++P)
821       CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
822   }
823 
824   if (const ObjCInterfaceDecl *
825         Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
826     for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
827                                            PEnd = Interface->protocol_end();
828          P != PEnd; ++P)
829       CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
830 
831     for (ObjCInterfaceDecl::visible_categories_iterator
832            Cat = Interface->visible_categories_begin(),
833            CatEnd = Interface->visible_categories_end();
834          Cat != CatEnd; ++Cat) {
835       CollectOverriddenMethodsRecurse(*Cat, Method, Methods,
836                                       MovedToSuper);
837     }
838 
839     if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
840       return CollectOverriddenMethodsRecurse(Super, Method, Methods,
841                                              /*MovedToSuper=*/true);
842   }
843 }
844 
CollectOverriddenMethods(const ObjCContainerDecl * Container,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods)845 static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
846                                             const ObjCMethodDecl *Method,
847                              SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
848   CollectOverriddenMethodsRecurse(Container, Method, Methods,
849                                   /*MovedToSuper=*/false);
850 }
851 
collectOverriddenMethodsSlow(const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & overridden)852 static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
853                           SmallVectorImpl<const ObjCMethodDecl *> &overridden) {
854   assert(Method->isOverriding());
855 
856   if (const ObjCProtocolDecl *
857         ProtD = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
858     CollectOverriddenMethods(ProtD, Method, overridden);
859 
860   } else if (const ObjCImplDecl *
861                IMD = dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
862     const ObjCInterfaceDecl *ID = IMD->getClassInterface();
863     if (!ID)
864       return;
865     // Start searching for overridden methods using the method from the
866     // interface as starting point.
867     if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
868                                                   Method->isInstanceMethod()))
869       Method = IFaceMeth;
870     CollectOverriddenMethods(ID, Method, overridden);
871 
872   } else if (const ObjCCategoryDecl *
873                CatD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
874     const ObjCInterfaceDecl *ID = CatD->getClassInterface();
875     if (!ID)
876       return;
877     // Start searching for overridden methods using the method from the
878     // interface as starting point.
879     if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
880                                                   Method->isInstanceMethod()))
881       Method = IFaceMeth;
882     CollectOverriddenMethods(ID, Method, overridden);
883 
884   } else {
885     CollectOverriddenMethods(
886                   dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
887                   Method, overridden);
888   }
889 }
890 
collectOnCategoriesAfterLocation(SourceLocation Loc,const ObjCInterfaceDecl * Class,SourceManager & SM,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods)891 static void collectOnCategoriesAfterLocation(SourceLocation Loc,
892                                              const ObjCInterfaceDecl *Class,
893                                              SourceManager &SM,
894                                              const ObjCMethodDecl *Method,
895                              SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
896   if (!Class)
897     return;
898 
899   for (ObjCInterfaceDecl::visible_categories_iterator
900          Cat = Class->visible_categories_begin(),
901          CatEnd = Class->visible_categories_end();
902        Cat != CatEnd; ++Cat) {
903     if (SM.isBeforeInTranslationUnit(Loc, Cat->getLocation()))
904       CollectOverriddenMethodsRecurse(*Cat, Method, Methods, true);
905   }
906 
907   collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), SM,
908                                    Method, Methods);
909 }
910 
911 /// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding()
912 /// returns false.
913 /// You'd think that in that case there are no overrides but categories can
914 /// "introduce" new overridden methods that are missed by Sema because the
915 /// overrides lookup that it does for methods, inside implementations, will
916 /// stop at the interface level (if there is a method there) and not look
917 /// further in super classes.
918 /// Methods in an implementation can overide methods in super class's category
919 /// but not in current class's category. But, such methods
collectOverriddenMethodsFast(SourceManager & SM,const ObjCMethodDecl * Method,SmallVectorImpl<const ObjCMethodDecl * > & Methods)920 static void collectOverriddenMethodsFast(SourceManager &SM,
921                                          const ObjCMethodDecl *Method,
922                              SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
923   assert(!Method->isOverriding());
924 
925   const ObjCContainerDecl *
926     ContD = cast<ObjCContainerDecl>(Method->getDeclContext());
927   if (isa<ObjCInterfaceDecl>(ContD) || isa<ObjCProtocolDecl>(ContD))
928     return;
929   const ObjCInterfaceDecl *Class = Method->getClassInterface();
930   if (!Class)
931     return;
932 
933   collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(),
934                                    SM, Method, Methods);
935 }
936 
getOverriddenMethods(SmallVectorImpl<const ObjCMethodDecl * > & Overridden) const937 void ObjCMethodDecl::getOverriddenMethods(
938                     SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
939   const ObjCMethodDecl *Method = this;
940 
941   if (Method->isRedeclaration()) {
942     Method = cast<ObjCContainerDecl>(Method->getDeclContext())->
943                    getMethod(Method->getSelector(), Method->isInstanceMethod());
944   }
945 
946   if (!Method->isOverriding()) {
947     collectOverriddenMethodsFast(getASTContext().getSourceManager(),
948                                  Method, Overridden);
949   } else {
950     collectOverriddenMethodsSlow(Method, Overridden);
951     assert(!Overridden.empty() &&
952            "ObjCMethodDecl's overriding bit is not as expected");
953   }
954 }
955 
956 const ObjCPropertyDecl *
findPropertyDecl(bool CheckOverrides) const957 ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
958   Selector Sel = getSelector();
959   unsigned NumArgs = Sel.getNumArgs();
960   if (NumArgs > 1)
961     return 0;
962 
963   if (!isInstanceMethod() || getMethodFamily() != OMF_None)
964     return 0;
965 
966   if (isPropertyAccessor()) {
967     const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent());
968     // If container is class extension, find its primary class.
969     if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(Container))
970       if (CatDecl->IsClassExtension())
971         Container = CatDecl->getClassInterface();
972 
973     bool IsGetter = (NumArgs == 0);
974 
975     for (ObjCContainerDecl::prop_iterator I = Container->prop_begin(),
976                                           E = Container->prop_end();
977          I != E; ++I) {
978       Selector NextSel = IsGetter ? (*I)->getGetterName()
979                                   : (*I)->getSetterName();
980       if (NextSel == Sel)
981         return *I;
982     }
983 
984     llvm_unreachable("Marked as a property accessor but no property found!");
985   }
986 
987   if (!CheckOverrides)
988     return 0;
989 
990   typedef SmallVector<const ObjCMethodDecl *, 8> OverridesTy;
991   OverridesTy Overrides;
992   getOverriddenMethods(Overrides);
993   for (OverridesTy::const_iterator I = Overrides.begin(), E = Overrides.end();
994        I != E; ++I) {
995     if (const ObjCPropertyDecl *Prop = (*I)->findPropertyDecl(false))
996       return Prop;
997   }
998 
999   return 0;
1000 
1001 }
1002 
1003 //===----------------------------------------------------------------------===//
1004 // ObjCInterfaceDecl
1005 //===----------------------------------------------------------------------===//
1006 
Create(const ASTContext & C,DeclContext * DC,SourceLocation atLoc,IdentifierInfo * Id,ObjCInterfaceDecl * PrevDecl,SourceLocation ClassLoc,bool isInternal)1007 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
1008                                              DeclContext *DC,
1009                                              SourceLocation atLoc,
1010                                              IdentifierInfo *Id,
1011                                              ObjCInterfaceDecl *PrevDecl,
1012                                              SourceLocation ClassLoc,
1013                                              bool isInternal){
1014   ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc,
1015                                                         PrevDecl, isInternal);
1016   Result->Data.setInt(!C.getLangOpts().Modules);
1017   C.getObjCInterfaceType(Result, PrevDecl);
1018   return Result;
1019 }
1020 
CreateDeserialized(ASTContext & C,unsigned ID)1021 ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C,
1022                                                          unsigned ID) {
1023   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCInterfaceDecl));
1024   ObjCInterfaceDecl *Result = new (Mem) ObjCInterfaceDecl(0, SourceLocation(),
1025                                                           0, SourceLocation(),
1026                                                           0, false);
1027   Result->Data.setInt(!C.getLangOpts().Modules);
1028   return Result;
1029 }
1030 
1031 ObjCInterfaceDecl::
ObjCInterfaceDecl(DeclContext * DC,SourceLocation atLoc,IdentifierInfo * Id,SourceLocation CLoc,ObjCInterfaceDecl * PrevDecl,bool isInternal)1032 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
1033                   SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
1034                   bool isInternal)
1035   : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
1036     TypeForDecl(0), Data()
1037 {
1038   setPreviousDeclaration(PrevDecl);
1039 
1040   // Copy the 'data' pointer over.
1041   if (PrevDecl)
1042     Data = PrevDecl->Data;
1043 
1044   setImplicit(isInternal);
1045 }
1046 
LoadExternalDefinition() const1047 void ObjCInterfaceDecl::LoadExternalDefinition() const {
1048   assert(data().ExternallyCompleted && "Class is not externally completed");
1049   data().ExternallyCompleted = false;
1050   getASTContext().getExternalSource()->CompleteType(
1051                                         const_cast<ObjCInterfaceDecl *>(this));
1052 }
1053 
setExternallyCompleted()1054 void ObjCInterfaceDecl::setExternallyCompleted() {
1055   assert(getASTContext().getExternalSource() &&
1056          "Class can't be externally completed without an external source");
1057   assert(hasDefinition() &&
1058          "Forward declarations can't be externally completed");
1059   data().ExternallyCompleted = true;
1060 }
1061 
getImplementation() const1062 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
1063   if (const ObjCInterfaceDecl *Def = getDefinition()) {
1064     if (data().ExternallyCompleted)
1065       LoadExternalDefinition();
1066 
1067     return getASTContext().getObjCImplementation(
1068              const_cast<ObjCInterfaceDecl*>(Def));
1069   }
1070 
1071   // FIXME: Should make sure no callers ever do this.
1072   return 0;
1073 }
1074 
setImplementation(ObjCImplementationDecl * ImplD)1075 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
1076   getASTContext().setObjCImplementation(getDefinition(), ImplD);
1077 }
1078 
1079 namespace {
1080   struct SynthesizeIvarChunk {
1081     uint64_t Size;
1082     ObjCIvarDecl *Ivar;
SynthesizeIvarChunk__anoneed1ec6f0111::SynthesizeIvarChunk1083     SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
1084       : Size(size), Ivar(ivar) {}
1085   };
1086 
operator <(const SynthesizeIvarChunk & LHS,const SynthesizeIvarChunk & RHS)1087   bool operator<(const SynthesizeIvarChunk & LHS,
1088                  const SynthesizeIvarChunk &RHS) {
1089       return LHS.Size < RHS.Size;
1090   }
1091 }
1092 
1093 /// all_declared_ivar_begin - return first ivar declared in this class,
1094 /// its extensions and its implementation. Lazily build the list on first
1095 /// access.
1096 ///
1097 /// Caveat: The list returned by this method reflects the current
1098 /// state of the parser. The cache will be updated for every ivar
1099 /// added by an extension or the implementation when they are
1100 /// encountered.
1101 /// See also ObjCIvarDecl::Create().
all_declared_ivar_begin()1102 ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
1103   // FIXME: Should make sure no callers ever do this.
1104   if (!hasDefinition())
1105     return 0;
1106 
1107   ObjCIvarDecl *curIvar = 0;
1108   if (!data().IvarList) {
1109     if (!ivar_empty()) {
1110       ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
1111       data().IvarList = *I; ++I;
1112       for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
1113         curIvar->setNextIvar(*I);
1114     }
1115 
1116     for (ObjCInterfaceDecl::known_extensions_iterator
1117            Ext = known_extensions_begin(),
1118            ExtEnd = known_extensions_end();
1119          Ext != ExtEnd; ++Ext) {
1120       if (!Ext->ivar_empty()) {
1121         ObjCCategoryDecl::ivar_iterator
1122           I = Ext->ivar_begin(),
1123           E = Ext->ivar_end();
1124         if (!data().IvarList) {
1125           data().IvarList = *I; ++I;
1126           curIvar = data().IvarList;
1127         }
1128         for ( ;I != E; curIvar = *I, ++I)
1129           curIvar->setNextIvar(*I);
1130       }
1131     }
1132     data().IvarListMissingImplementation = true;
1133   }
1134 
1135   // cached and complete!
1136   if (!data().IvarListMissingImplementation)
1137       return data().IvarList;
1138 
1139   if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
1140     data().IvarListMissingImplementation = false;
1141     if (!ImplDecl->ivar_empty()) {
1142       SmallVector<SynthesizeIvarChunk, 16> layout;
1143       for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
1144            E = ImplDecl->ivar_end(); I != E; ++I) {
1145         ObjCIvarDecl *IV = *I;
1146         if (IV->getSynthesize() && !IV->isInvalidDecl()) {
1147           layout.push_back(SynthesizeIvarChunk(
1148                              IV->getASTContext().getTypeSize(IV->getType()), IV));
1149           continue;
1150         }
1151         if (!data().IvarList)
1152           data().IvarList = *I;
1153         else
1154           curIvar->setNextIvar(*I);
1155         curIvar = *I;
1156       }
1157 
1158       if (!layout.empty()) {
1159         // Order synthesized ivars by their size.
1160         std::stable_sort(layout.begin(), layout.end());
1161         unsigned Ix = 0, EIx = layout.size();
1162         if (!data().IvarList) {
1163           data().IvarList = layout[0].Ivar; Ix++;
1164           curIvar = data().IvarList;
1165         }
1166         for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++)
1167           curIvar->setNextIvar(layout[Ix].Ivar);
1168       }
1169     }
1170   }
1171   return data().IvarList;
1172 }
1173 
1174 /// FindCategoryDeclaration - Finds category declaration in the list of
1175 /// categories for this class and returns it. Name of the category is passed
1176 /// in 'CategoryId'. If category not found, return 0;
1177 ///
1178 ObjCCategoryDecl *
FindCategoryDeclaration(IdentifierInfo * CategoryId) const1179 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
1180   // FIXME: Should make sure no callers ever do this.
1181   if (!hasDefinition())
1182     return 0;
1183 
1184   if (data().ExternallyCompleted)
1185     LoadExternalDefinition();
1186 
1187   for (visible_categories_iterator Cat = visible_categories_begin(),
1188                                    CatEnd = visible_categories_end();
1189        Cat != CatEnd;
1190        ++Cat) {
1191     if (Cat->getIdentifier() == CategoryId)
1192       return *Cat;
1193   }
1194 
1195   return 0;
1196 }
1197 
1198 ObjCMethodDecl *
getCategoryInstanceMethod(Selector Sel) const1199 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
1200   for (visible_categories_iterator Cat = visible_categories_begin(),
1201                                    CatEnd = visible_categories_end();
1202        Cat != CatEnd;
1203        ++Cat) {
1204     if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1205       if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
1206         return MD;
1207   }
1208 
1209   return 0;
1210 }
1211 
getCategoryClassMethod(Selector Sel) const1212 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
1213   for (visible_categories_iterator Cat = visible_categories_begin(),
1214                                    CatEnd = visible_categories_end();
1215        Cat != CatEnd;
1216        ++Cat) {
1217     if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
1218       if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
1219         return MD;
1220   }
1221 
1222   return 0;
1223 }
1224 
1225 /// ClassImplementsProtocol - Checks that 'lProto' protocol
1226 /// has been implemented in IDecl class, its super class or categories (if
1227 /// lookupCategory is true).
ClassImplementsProtocol(ObjCProtocolDecl * lProto,bool lookupCategory,bool RHSIsQualifiedID)1228 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
1229                                     bool lookupCategory,
1230                                     bool RHSIsQualifiedID) {
1231   if (!hasDefinition())
1232     return false;
1233 
1234   ObjCInterfaceDecl *IDecl = this;
1235   // 1st, look up the class.
1236   for (ObjCInterfaceDecl::protocol_iterator
1237         PI = IDecl->protocol_begin(), E = IDecl->protocol_end(); PI != E; ++PI){
1238     if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
1239       return true;
1240     // This is dubious and is added to be compatible with gcc.  In gcc, it is
1241     // also allowed assigning a protocol-qualified 'id' type to a LHS object
1242     // when protocol in qualified LHS is in list of protocols in the rhs 'id'
1243     // object. This IMO, should be a bug.
1244     // FIXME: Treat this as an extension, and flag this as an error when GCC
1245     // extensions are not enabled.
1246     if (RHSIsQualifiedID &&
1247         getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
1248       return true;
1249   }
1250 
1251   // 2nd, look up the category.
1252   if (lookupCategory)
1253     for (visible_categories_iterator Cat = visible_categories_begin(),
1254                                      CatEnd = visible_categories_end();
1255          Cat != CatEnd;
1256          ++Cat) {
1257       for (ObjCCategoryDecl::protocol_iterator PI = Cat->protocol_begin(),
1258                                                E = Cat->protocol_end();
1259            PI != E; ++PI)
1260         if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
1261           return true;
1262     }
1263 
1264   // 3rd, look up the super class(s)
1265   if (IDecl->getSuperClass())
1266     return
1267   IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
1268                                                   RHSIsQualifiedID);
1269 
1270   return false;
1271 }
1272 
1273 //===----------------------------------------------------------------------===//
1274 // ObjCIvarDecl
1275 //===----------------------------------------------------------------------===//
1276 
anchor()1277 void ObjCIvarDecl::anchor() { }
1278 
Create(ASTContext & C,ObjCContainerDecl * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,AccessControl ac,Expr * BW,bool synthesized)1279 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
1280                                    SourceLocation StartLoc,
1281                                    SourceLocation IdLoc, IdentifierInfo *Id,
1282                                    QualType T, TypeSourceInfo *TInfo,
1283                                    AccessControl ac, Expr *BW,
1284                                    bool synthesized) {
1285   if (DC) {
1286     // Ivar's can only appear in interfaces, implementations (via synthesized
1287     // properties), and class extensions (via direct declaration, or synthesized
1288     // properties).
1289     //
1290     // FIXME: This should really be asserting this:
1291     //   (isa<ObjCCategoryDecl>(DC) &&
1292     //    cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
1293     // but unfortunately we sometimes place ivars into non-class extension
1294     // categories on error. This breaks an AST invariant, and should not be
1295     // fixed.
1296     assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
1297             isa<ObjCCategoryDecl>(DC)) &&
1298            "Invalid ivar decl context!");
1299     // Once a new ivar is created in any of class/class-extension/implementation
1300     // decl contexts, the previously built IvarList must be rebuilt.
1301     ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
1302     if (!ID) {
1303       if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
1304         ID = IM->getClassInterface();
1305       else
1306         ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
1307     }
1308     ID->setIvarList(0);
1309   }
1310 
1311   return new (C) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo,
1312                               ac, BW, synthesized);
1313 }
1314 
CreateDeserialized(ASTContext & C,unsigned ID)1315 ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1316   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCIvarDecl));
1317   return new (Mem) ObjCIvarDecl(0, SourceLocation(), SourceLocation(), 0,
1318                                 QualType(), 0, ObjCIvarDecl::None, 0, false);
1319 }
1320 
getContainingInterface() const1321 const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
1322   const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
1323 
1324   switch (DC->getKind()) {
1325   default:
1326   case ObjCCategoryImpl:
1327   case ObjCProtocol:
1328     llvm_unreachable("invalid ivar container!");
1329 
1330     // Ivars can only appear in class extension categories.
1331   case ObjCCategory: {
1332     const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
1333     assert(CD->IsClassExtension() && "invalid container for ivar!");
1334     return CD->getClassInterface();
1335   }
1336 
1337   case ObjCImplementation:
1338     return cast<ObjCImplementationDecl>(DC)->getClassInterface();
1339 
1340   case ObjCInterface:
1341     return cast<ObjCInterfaceDecl>(DC);
1342   }
1343 }
1344 
1345 //===----------------------------------------------------------------------===//
1346 // ObjCAtDefsFieldDecl
1347 //===----------------------------------------------------------------------===//
1348 
anchor()1349 void ObjCAtDefsFieldDecl::anchor() { }
1350 
1351 ObjCAtDefsFieldDecl
Create(ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,IdentifierInfo * Id,QualType T,Expr * BW)1352 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
1353                              SourceLocation StartLoc,  SourceLocation IdLoc,
1354                              IdentifierInfo *Id, QualType T, Expr *BW) {
1355   return new (C) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
1356 }
1357 
CreateDeserialized(ASTContext & C,unsigned ID)1358 ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
1359                                                              unsigned ID) {
1360   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCAtDefsFieldDecl));
1361   return new (Mem) ObjCAtDefsFieldDecl(0, SourceLocation(), SourceLocation(),
1362                                        0, QualType(), 0);
1363 }
1364 
1365 //===----------------------------------------------------------------------===//
1366 // ObjCProtocolDecl
1367 //===----------------------------------------------------------------------===//
1368 
anchor()1369 void ObjCProtocolDecl::anchor() { }
1370 
ObjCProtocolDecl(DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1371 ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
1372                                    SourceLocation nameLoc,
1373                                    SourceLocation atStartLoc,
1374                                    ObjCProtocolDecl *PrevDecl)
1375   : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data()
1376 {
1377   setPreviousDeclaration(PrevDecl);
1378   if (PrevDecl)
1379     Data = PrevDecl->Data;
1380 }
1381 
Create(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,SourceLocation nameLoc,SourceLocation atStartLoc,ObjCProtocolDecl * PrevDecl)1382 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
1383                                            IdentifierInfo *Id,
1384                                            SourceLocation nameLoc,
1385                                            SourceLocation atStartLoc,
1386                                            ObjCProtocolDecl *PrevDecl) {
1387   ObjCProtocolDecl *Result
1388     = new (C) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl);
1389   Result->Data.setInt(!C.getLangOpts().Modules);
1390   return Result;
1391 }
1392 
CreateDeserialized(ASTContext & C,unsigned ID)1393 ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
1394                                                        unsigned ID) {
1395   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCProtocolDecl));
1396   ObjCProtocolDecl *Result = new (Mem) ObjCProtocolDecl(0, 0, SourceLocation(),
1397                                                         SourceLocation(), 0);
1398   Result->Data.setInt(!C.getLangOpts().Modules);
1399   return Result;
1400 }
1401 
lookupProtocolNamed(IdentifierInfo * Name)1402 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
1403   ObjCProtocolDecl *PDecl = this;
1404 
1405   if (Name == getIdentifier())
1406     return PDecl;
1407 
1408   for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1409     if ((PDecl = (*I)->lookupProtocolNamed(Name)))
1410       return PDecl;
1411 
1412   return NULL;
1413 }
1414 
1415 // lookupMethod - Lookup a instance/class method in the protocol and protocols
1416 // it inherited.
lookupMethod(Selector Sel,bool isInstance) const1417 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
1418                                                bool isInstance) const {
1419   ObjCMethodDecl *MethodDecl = NULL;
1420 
1421   // If there is no definition or the definition is hidden, we don't find
1422   // anything.
1423   const ObjCProtocolDecl *Def = getDefinition();
1424   if (!Def || Def->isHidden())
1425     return NULL;
1426 
1427   if ((MethodDecl = getMethod(Sel, isInstance)))
1428     return MethodDecl;
1429 
1430   for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1431     if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
1432       return MethodDecl;
1433   return NULL;
1434 }
1435 
allocateDefinitionData()1436 void ObjCProtocolDecl::allocateDefinitionData() {
1437   assert(!Data.getPointer() && "Protocol already has a definition!");
1438   Data.setPointer(new (getASTContext()) DefinitionData);
1439   Data.getPointer()->Definition = this;
1440 }
1441 
startDefinition()1442 void ObjCProtocolDecl::startDefinition() {
1443   allocateDefinitionData();
1444 
1445   // Update all of the declarations with a pointer to the definition.
1446   for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
1447        RD != RDEnd; ++RD)
1448     RD->Data = this->Data;
1449 }
1450 
collectPropertiesToImplement(PropertyMap & PM,PropertyDeclOrder & PO) const1451 void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
1452                                                     PropertyDeclOrder &PO) const {
1453 
1454   if (const ObjCProtocolDecl *PDecl = getDefinition()) {
1455     for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
1456          E = PDecl->prop_end(); P != E; ++P) {
1457       ObjCPropertyDecl *Prop = *P;
1458       // Insert into PM if not there already.
1459       PM.insert(std::make_pair(Prop->getIdentifier(), Prop));
1460       PO.push_back(Prop);
1461     }
1462     // Scan through protocol's protocols.
1463     for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
1464          E = PDecl->protocol_end(); PI != E; ++PI)
1465       (*PI)->collectPropertiesToImplement(PM, PO);
1466   }
1467 }
1468 
1469 
1470 //===----------------------------------------------------------------------===//
1471 // ObjCCategoryDecl
1472 //===----------------------------------------------------------------------===//
1473 
anchor()1474 void ObjCCategoryDecl::anchor() { }
1475 
Create(ASTContext & C,DeclContext * DC,SourceLocation AtLoc,SourceLocation ClassNameLoc,SourceLocation CategoryNameLoc,IdentifierInfo * Id,ObjCInterfaceDecl * IDecl,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)1476 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
1477                                            SourceLocation AtLoc,
1478                                            SourceLocation ClassNameLoc,
1479                                            SourceLocation CategoryNameLoc,
1480                                            IdentifierInfo *Id,
1481                                            ObjCInterfaceDecl *IDecl,
1482                                            SourceLocation IvarLBraceLoc,
1483                                            SourceLocation IvarRBraceLoc) {
1484   ObjCCategoryDecl *CatDecl = new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc,
1485                                                        CategoryNameLoc, Id,
1486                                                        IDecl,
1487                                                        IvarLBraceLoc, IvarRBraceLoc);
1488   if (IDecl) {
1489     // Link this category into its class's category list.
1490     CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
1491     if (IDecl->hasDefinition()) {
1492       IDecl->setCategoryListRaw(CatDecl);
1493       if (ASTMutationListener *L = C.getASTMutationListener())
1494         L->AddedObjCCategoryToInterface(CatDecl, IDecl);
1495     }
1496   }
1497 
1498   return CatDecl;
1499 }
1500 
CreateDeserialized(ASTContext & C,unsigned ID)1501 ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
1502                                                        unsigned ID) {
1503   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryDecl));
1504   return new (Mem) ObjCCategoryDecl(0, SourceLocation(), SourceLocation(),
1505                                     SourceLocation(), 0, 0);
1506 }
1507 
getImplementation() const1508 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
1509   return getASTContext().getObjCImplementation(
1510                                            const_cast<ObjCCategoryDecl*>(this));
1511 }
1512 
setImplementation(ObjCCategoryImplDecl * ImplD)1513 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
1514   getASTContext().setObjCImplementation(this, ImplD);
1515 }
1516 
1517 
1518 //===----------------------------------------------------------------------===//
1519 // ObjCCategoryImplDecl
1520 //===----------------------------------------------------------------------===//
1521 
anchor()1522 void ObjCCategoryImplDecl::anchor() { }
1523 
1524 ObjCCategoryImplDecl *
Create(ASTContext & C,DeclContext * DC,IdentifierInfo * Id,ObjCInterfaceDecl * ClassInterface,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation CategoryNameLoc)1525 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
1526                              IdentifierInfo *Id,
1527                              ObjCInterfaceDecl *ClassInterface,
1528                              SourceLocation nameLoc,
1529                              SourceLocation atStartLoc,
1530                              SourceLocation CategoryNameLoc) {
1531   if (ClassInterface && ClassInterface->hasDefinition())
1532     ClassInterface = ClassInterface->getDefinition();
1533   return new (C) ObjCCategoryImplDecl(DC, Id, ClassInterface,
1534                                       nameLoc, atStartLoc, CategoryNameLoc);
1535 }
1536 
CreateDeserialized(ASTContext & C,unsigned ID)1537 ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
1538                                                                unsigned ID) {
1539   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryImplDecl));
1540   return new (Mem) ObjCCategoryImplDecl(0, 0, 0, SourceLocation(),
1541                                         SourceLocation(), SourceLocation());
1542 }
1543 
getCategoryDecl() const1544 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
1545   // The class interface might be NULL if we are working with invalid code.
1546   if (const ObjCInterfaceDecl *ID = getClassInterface())
1547     return ID->FindCategoryDeclaration(getIdentifier());
1548   return 0;
1549 }
1550 
1551 
anchor()1552 void ObjCImplDecl::anchor() { }
1553 
addPropertyImplementation(ObjCPropertyImplDecl * property)1554 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
1555   // FIXME: The context should be correct before we get here.
1556   property->setLexicalDeclContext(this);
1557   addDecl(property);
1558 }
1559 
setClassInterface(ObjCInterfaceDecl * IFace)1560 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
1561   ASTContext &Ctx = getASTContext();
1562 
1563   if (ObjCImplementationDecl *ImplD
1564         = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
1565     if (IFace)
1566       Ctx.setObjCImplementation(IFace, ImplD);
1567 
1568   } else if (ObjCCategoryImplDecl *ImplD =
1569              dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
1570     if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
1571       Ctx.setObjCImplementation(CD, ImplD);
1572   }
1573 
1574   ClassInterface = IFace;
1575 }
1576 
1577 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
1578 /// properties implemented in this \@implementation block and returns
1579 /// the implemented property that uses it.
1580 ///
1581 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplIvarDecl(IdentifierInfo * ivarId) const1582 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
1583   for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
1584     ObjCPropertyImplDecl *PID = *i;
1585     if (PID->getPropertyIvarDecl() &&
1586         PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
1587       return PID;
1588   }
1589   return 0;
1590 }
1591 
1592 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
1593 /// added to the list of those properties \@synthesized/\@dynamic in this
1594 /// category \@implementation block.
1595 ///
1596 ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplDecl(IdentifierInfo * Id) const1597 FindPropertyImplDecl(IdentifierInfo *Id) const {
1598   for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
1599     ObjCPropertyImplDecl *PID = *i;
1600     if (PID->getPropertyDecl()->getIdentifier() == Id)
1601       return PID;
1602   }
1603   return 0;
1604 }
1605 
operator <<(raw_ostream & OS,const ObjCCategoryImplDecl & CID)1606 raw_ostream &clang::operator<<(raw_ostream &OS,
1607                                const ObjCCategoryImplDecl &CID) {
1608   OS << CID.getName();
1609   return OS;
1610 }
1611 
1612 //===----------------------------------------------------------------------===//
1613 // ObjCImplementationDecl
1614 //===----------------------------------------------------------------------===//
1615 
anchor()1616 void ObjCImplementationDecl::anchor() { }
1617 
1618 ObjCImplementationDecl *
Create(ASTContext & C,DeclContext * DC,ObjCInterfaceDecl * ClassInterface,ObjCInterfaceDecl * SuperDecl,SourceLocation nameLoc,SourceLocation atStartLoc,SourceLocation IvarLBraceLoc,SourceLocation IvarRBraceLoc)1619 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
1620                                ObjCInterfaceDecl *ClassInterface,
1621                                ObjCInterfaceDecl *SuperDecl,
1622                                SourceLocation nameLoc,
1623                                SourceLocation atStartLoc,
1624                                SourceLocation IvarLBraceLoc,
1625                                SourceLocation IvarRBraceLoc) {
1626   if (ClassInterface && ClassInterface->hasDefinition())
1627     ClassInterface = ClassInterface->getDefinition();
1628   return new (C) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
1629                                         nameLoc, atStartLoc,
1630                                         IvarLBraceLoc, IvarRBraceLoc);
1631 }
1632 
1633 ObjCImplementationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1634 ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1635   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCImplementationDecl));
1636   return new (Mem) ObjCImplementationDecl(0, 0, 0, SourceLocation(),
1637                                           SourceLocation());
1638 }
1639 
setIvarInitializers(ASTContext & C,CXXCtorInitializer ** initializers,unsigned numInitializers)1640 void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
1641                                              CXXCtorInitializer ** initializers,
1642                                                  unsigned numInitializers) {
1643   if (numInitializers > 0) {
1644     NumIvarInitializers = numInitializers;
1645     CXXCtorInitializer **ivarInitializers =
1646     new (C) CXXCtorInitializer*[NumIvarInitializers];
1647     memcpy(ivarInitializers, initializers,
1648            numInitializers * sizeof(CXXCtorInitializer*));
1649     IvarInitializers = ivarInitializers;
1650   }
1651 }
1652 
operator <<(raw_ostream & OS,const ObjCImplementationDecl & ID)1653 raw_ostream &clang::operator<<(raw_ostream &OS,
1654                                const ObjCImplementationDecl &ID) {
1655   OS << ID.getName();
1656   return OS;
1657 }
1658 
1659 //===----------------------------------------------------------------------===//
1660 // ObjCCompatibleAliasDecl
1661 //===----------------------------------------------------------------------===//
1662 
anchor()1663 void ObjCCompatibleAliasDecl::anchor() { }
1664 
1665 ObjCCompatibleAliasDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,IdentifierInfo * Id,ObjCInterfaceDecl * AliasedClass)1666 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
1667                                 SourceLocation L,
1668                                 IdentifierInfo *Id,
1669                                 ObjCInterfaceDecl* AliasedClass) {
1670   return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
1671 }
1672 
1673 ObjCCompatibleAliasDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1674 ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1675   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCompatibleAliasDecl));
1676   return new (Mem) ObjCCompatibleAliasDecl(0, SourceLocation(), 0, 0);
1677 }
1678 
1679 //===----------------------------------------------------------------------===//
1680 // ObjCPropertyDecl
1681 //===----------------------------------------------------------------------===//
1682 
anchor()1683 void ObjCPropertyDecl::anchor() { }
1684 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,IdentifierInfo * Id,SourceLocation AtLoc,SourceLocation LParenLoc,TypeSourceInfo * T,PropertyControl propControl)1685 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
1686                                            SourceLocation L,
1687                                            IdentifierInfo *Id,
1688                                            SourceLocation AtLoc,
1689                                            SourceLocation LParenLoc,
1690                                            TypeSourceInfo *T,
1691                                            PropertyControl propControl) {
1692   return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
1693 }
1694 
CreateDeserialized(ASTContext & C,unsigned ID)1695 ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
1696                                                        unsigned ID) {
1697   void * Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyDecl));
1698   return new (Mem) ObjCPropertyDecl(0, SourceLocation(), 0, SourceLocation(),
1699                                     SourceLocation(),
1700                                     0);
1701 }
1702 
1703 //===----------------------------------------------------------------------===//
1704 // ObjCPropertyImplDecl
1705 //===----------------------------------------------------------------------===//
1706 
Create(ASTContext & C,DeclContext * DC,SourceLocation atLoc,SourceLocation L,ObjCPropertyDecl * property,Kind PK,ObjCIvarDecl * ivar,SourceLocation ivarLoc)1707 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
1708                                                    DeclContext *DC,
1709                                                    SourceLocation atLoc,
1710                                                    SourceLocation L,
1711                                                    ObjCPropertyDecl *property,
1712                                                    Kind PK,
1713                                                    ObjCIvarDecl *ivar,
1714                                                    SourceLocation ivarLoc) {
1715   return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
1716                                       ivarLoc);
1717 }
1718 
CreateDeserialized(ASTContext & C,unsigned ID)1719 ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
1720                                                                unsigned ID) {
1721   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyImplDecl));
1722   return new (Mem) ObjCPropertyImplDecl(0, SourceLocation(), SourceLocation(),
1723                                         0, Dynamic, 0, SourceLocation());
1724 }
1725 
getSourceRange() const1726 SourceRange ObjCPropertyImplDecl::getSourceRange() const {
1727   SourceLocation EndLoc = getLocation();
1728   if (IvarLoc.isValid())
1729     EndLoc = IvarLoc;
1730 
1731   return SourceRange(AtLoc, EndLoc);
1732 }
1733