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 "llvm/ADT/STLExtras.h"
18 using namespace clang;
19 
20 //===----------------------------------------------------------------------===//
21 // ObjCListBase
22 //===----------------------------------------------------------------------===//
23 
24 void ObjCListBase::Destroy(ASTContext &Ctx) {
25   Ctx.Deallocate(List);
26   NumElts = 0;
27   List = 0;
28 }
29 
30 void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
31   assert(List == 0 && "Elements already set!");
32   if (Elts == 0) return;  // Setting to an empty list is a noop.
33 
34 
35   List = new (Ctx) void*[Elts];
36   NumElts = Elts;
37   memcpy(List, InList, sizeof(void*)*Elts);
38 }
39 
40 
41 //===----------------------------------------------------------------------===//
42 // ObjCInterfaceDecl
43 //===----------------------------------------------------------------------===//
44 
45 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
46 ///
47 ObjCIvarDecl *
48 ObjCContainerDecl::getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const {
49   lookup_const_iterator Ivar, IvarEnd;
50   for (llvm::tie(Ivar, IvarEnd) = lookup(Context, Id);
51        Ivar != IvarEnd; ++Ivar) {
52     if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
53       return ivar;
54   }
55   return 0;
56 }
57 
58 // Get the local instance method declared in this interface.
59 ObjCMethodDecl *
60 ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
61   // Since instance & class methods can have the same name, the loop below
62   // ensures we get the correct method.
63   //
64   // @interface Whatever
65   // - (int) class_method;
66   // + (float) class_method;
67   // @end
68   //
69   lookup_const_iterator Meth, MethEnd;
70   for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
71        Meth != MethEnd; ++Meth) {
72     ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
73     if (MD && MD->isInstanceMethod())
74       return MD;
75   }
76   return 0;
77 }
78 
79 // Get the local class method declared in this interface.
80 ObjCMethodDecl *
81 ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
82   // Since instance & class methods can have the same name, the loop below
83   // ensures we get the correct method.
84   //
85   // @interface Whatever
86   // - (int) class_method;
87   // + (float) class_method;
88   // @end
89   //
90   lookup_const_iterator Meth, MethEnd;
91   for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
92        Meth != MethEnd; ++Meth) {
93     ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
94     if (MD && MD->isClassMethod())
95       return MD;
96   }
97   return 0;
98 }
99 
100 /// FindPropertyDeclaration - Finds declaration of the property given its name
101 /// in 'PropertyId' and returns it. It returns 0, if not found.
102 /// FIXME: Convert to DeclContext lookup...
103 ///
104 ObjCPropertyDecl *
105 ObjCContainerDecl::FindPropertyDeclaration(ASTContext &Context,
106                                            IdentifierInfo *PropertyId) const {
107   for (prop_iterator I = prop_begin(Context), E = prop_end(Context);
108        I != E; ++I)
109     if ((*I)->getIdentifier() == PropertyId)
110       return *I;
111 
112   const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
113   if (PID) {
114     for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
115          E = PID->protocol_end(); I != E; ++I)
116       if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
117                                                               PropertyId))
118         return P;
119   }
120 
121   if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
122     // Look through categories.
123     for (ObjCCategoryDecl *Category = OID->getCategoryList();
124          Category; Category = Category->getNextClassCategory()) {
125       if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(Context,
126                                                                   PropertyId))
127         return P;
128     }
129     // Look through protocols.
130     for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
131          E = OID->protocol_end(); I != E; ++I) {
132       if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
133                                                               PropertyId))
134         return P;
135     }
136     if (OID->getSuperClass())
137       return OID->getSuperClass()->FindPropertyDeclaration(Context,
138                                                            PropertyId);
139   } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
140     // Look through protocols.
141     for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
142          E = OCD->protocol_end(); I != E; ++I) {
143       if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
144                                                               PropertyId))
145         return P;
146     }
147   }
148   return 0;
149 }
150 
151 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
152   ASTContext &Context, IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
153   ObjCInterfaceDecl* ClassDecl = this;
154   while (ClassDecl != NULL) {
155     if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(Context, ID)) {
156       clsDeclared = ClassDecl;
157       return I;
158     }
159     ClassDecl = ClassDecl->getSuperClass();
160   }
161   return NULL;
162 }
163 
164 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
165 /// class whose name is passed as argument. If it is not one of the super classes
166 /// the it returns NULL.
167 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
168                                         const IdentifierInfo*ICName) {
169   ObjCInterfaceDecl* ClassDecl = this;
170   while (ClassDecl != NULL) {
171     if (ClassDecl->getIdentifier() == ICName)
172       return ClassDecl;
173     ClassDecl = ClassDecl->getSuperClass();
174   }
175   return NULL;
176 }
177 
178 /// lookupInstanceMethod - This method returns an instance method by looking in
179 /// the class, its categories, and its super classes (using a linear search).
180 ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
181                                                         Selector Sel) {
182   ObjCInterfaceDecl* ClassDecl = this;
183   ObjCMethodDecl *MethodDecl = 0;
184 
185   while (ClassDecl != NULL) {
186     if ((MethodDecl = ClassDecl->getInstanceMethod(Context, Sel)))
187       return MethodDecl;
188 
189     // Didn't find one yet - look through protocols.
190     const ObjCList<ObjCProtocolDecl> &Protocols =
191       ClassDecl->getReferencedProtocols();
192     for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
193          E = Protocols.end(); I != E; ++I)
194       if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
195         return MethodDecl;
196 
197     // Didn't find one yet - now look through categories.
198     ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
199     while (CatDecl) {
200       if ((MethodDecl = CatDecl->getInstanceMethod(Context, Sel)))
201         return MethodDecl;
202 
203       // Didn't find one yet - look through protocols.
204       const ObjCList<ObjCProtocolDecl> &Protocols =
205         CatDecl->getReferencedProtocols();
206       for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
207            E = Protocols.end(); I != E; ++I)
208         if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
209           return MethodDecl;
210       CatDecl = CatDecl->getNextClassCategory();
211     }
212     ClassDecl = ClassDecl->getSuperClass();
213   }
214   return NULL;
215 }
216 
217 // lookupClassMethod - This method returns a class method by looking in the
218 // class, its categories, and its super classes (using a linear search).
219 ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(ASTContext &Context,
220                                                      Selector Sel) {
221   ObjCInterfaceDecl* ClassDecl = this;
222   ObjCMethodDecl *MethodDecl = 0;
223 
224   while (ClassDecl != NULL) {
225     if ((MethodDecl = ClassDecl->getClassMethod(Context, Sel)))
226       return MethodDecl;
227 
228     // Didn't find one yet - look through protocols.
229     for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
230          E = ClassDecl->protocol_end(); I != E; ++I)
231       if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
232         return MethodDecl;
233 
234     // Didn't find one yet - now look through categories.
235     ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
236     while (CatDecl) {
237       if ((MethodDecl = CatDecl->getClassMethod(Context, Sel)))
238         return MethodDecl;
239 
240       // Didn't find one yet - look through protocols.
241       const ObjCList<ObjCProtocolDecl> &Protocols =
242         CatDecl->getReferencedProtocols();
243       for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
244            E = Protocols.end(); I != E; ++I)
245         if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
246           return MethodDecl;
247       CatDecl = CatDecl->getNextClassCategory();
248     }
249     ClassDecl = ClassDecl->getSuperClass();
250   }
251   return NULL;
252 }
253 
254 
255 
256 //===----------------------------------------------------------------------===//
257 // ObjCMethodDecl
258 //===----------------------------------------------------------------------===//
259 
260 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
261                                        SourceLocation beginLoc,
262                                        SourceLocation endLoc,
263                                        Selector SelInfo, QualType T,
264                                        DeclContext *contextDecl,
265                                        bool isInstance,
266                                        bool isVariadic,
267                                        bool isSynthesized,
268                                        ImplementationControl impControl) {
269   return new (C) ObjCMethodDecl(beginLoc, endLoc,
270                                   SelInfo, T, contextDecl,
271                                   isInstance,
272                                   isVariadic, isSynthesized, impControl);
273 }
274 
275 void ObjCMethodDecl::Destroy(ASTContext &C) {
276   if (Body) Body->Destroy(C);
277   if (SelfDecl) SelfDecl->Destroy(C);
278 
279   for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
280     if (*I) (*I)->Destroy(C);
281 
282   ParamInfo.Destroy(C);
283 
284   Decl::Destroy(C);
285 }
286 
287 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
288                                           const ObjCInterfaceDecl *OID) {
289   QualType selfTy;
290   if (isInstanceMethod()) {
291     // There may be no interface context due to error in declaration
292     // of the interface (which has been reported). Recover gracefully.
293     if (OID) {
294       selfTy = Context.getObjCInterfaceType(OID);
295       selfTy = Context.getPointerType(selfTy);
296     } else {
297       selfTy = Context.getObjCIdType();
298     }
299   } else // we have a factory method.
300     selfTy = Context.getObjCClassType();
301 
302   setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
303                                         &Context.Idents.get("self"), selfTy));
304 
305   setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
306                                        &Context.Idents.get("_cmd"),
307                                        Context.getObjCSelType()));
308 }
309 
310 
311 
312 /// getSynthesizedMethodSize - Compute size of synthesized method name
313 /// as done be the rewrite.
314 ///
315 unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
316   // syntesized method name is a concatenation of -/+[class-name selector]
317   // Get length of this name.
318   unsigned length = 3;  // _I_ or _C_
319   length += getClassInterface()->getNameAsString().size()+1; // extra for _
320   if (const ObjCCategoryImplDecl *CID =
321       dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
322     length += CID->getNameAsString().size()+1;
323   length += getSelector().getAsString().size(); // selector name
324   return length;
325 }
326 
327 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
328   if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
329     return ID;
330   if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
331     return CD->getClassInterface();
332   if (ObjCImplementationDecl *IMD =
333       dyn_cast<ObjCImplementationDecl>(getDeclContext()))
334     return IMD->getClassInterface();
335   if (ObjCCategoryImplDecl *CID =
336       dyn_cast<ObjCCategoryImplDecl>(getDeclContext()))
337     return CID->getClassInterface();
338   assert(false && "unknown method context");
339   return 0;
340 }
341 
342 //===----------------------------------------------------------------------===//
343 // ObjCInterfaceDecl
344 //===----------------------------------------------------------------------===//
345 
346 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
347                                              DeclContext *DC,
348                                              SourceLocation atLoc,
349                                              IdentifierInfo *Id,
350                                              SourceLocation ClassLoc,
351                                              bool ForwardDecl, bool isInternal){
352   return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
353                                      isInternal);
354 }
355 
356 ObjCInterfaceDecl::
357 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
358                   SourceLocation CLoc, bool FD, bool isInternal)
359   : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
360     TypeForDecl(0), SuperClass(0),
361     CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
362     ClassLoc(CLoc) {
363 }
364 
365 void ObjCInterfaceDecl::Destroy(ASTContext &C) {
366   for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
367     if (*I) (*I)->Destroy(C);
368 
369   IVars.Destroy(C);
370   // FIXME: CategoryList?
371 
372   // FIXME: Because there is no clear ownership
373   //  role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
374   //  reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
375   Decl::Destroy(C);
376 }
377 
378 
379 /// FindCategoryDeclaration - Finds category declaration in the list of
380 /// categories for this class and returns it. Name of the category is passed
381 /// in 'CategoryId'. If category not found, return 0;
382 ///
383 ObjCCategoryDecl *
384 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
385   for (ObjCCategoryDecl *Category = getCategoryList();
386        Category; Category = Category->getNextClassCategory())
387     if (Category->getIdentifier() == CategoryId)
388       return Category;
389   return 0;
390 }
391 
392 //===----------------------------------------------------------------------===//
393 // ObjCIvarDecl
394 //===----------------------------------------------------------------------===//
395 
396 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
397                                    SourceLocation L, IdentifierInfo *Id,
398                                    QualType T, AccessControl ac, Expr *BW) {
399   return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW);
400 }
401 
402 
403 
404 //===----------------------------------------------------------------------===//
405 // ObjCAtDefsFieldDecl
406 //===----------------------------------------------------------------------===//
407 
408 ObjCAtDefsFieldDecl
409 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
410                              IdentifierInfo *Id, QualType T, Expr *BW) {
411   return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
412 }
413 
414 void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
415   this->~ObjCAtDefsFieldDecl();
416   C.Deallocate((void *)this);
417 }
418 
419 //===----------------------------------------------------------------------===//
420 // ObjCProtocolDecl
421 //===----------------------------------------------------------------------===//
422 
423 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
424                                            SourceLocation L,
425                                            IdentifierInfo *Id) {
426   return new (C) ObjCProtocolDecl(DC, L, Id);
427 }
428 
429 void ObjCProtocolDecl::Destroy(ASTContext &C) {
430   ReferencedProtocols.Destroy(C);
431   ObjCContainerDecl::Destroy(C);
432 }
433 
434 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
435   ObjCProtocolDecl *PDecl = this;
436 
437   if (Name == getIdentifier())
438     return PDecl;
439 
440   for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
441     if ((PDecl = (*I)->lookupProtocolNamed(Name)))
442       return PDecl;
443 
444   return NULL;
445 }
446 
447 // lookupInstanceMethod - Lookup a instance method in the protocol and protocols
448 // it inherited.
449 ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(ASTContext &Context,
450                                                        Selector Sel) {
451   ObjCMethodDecl *MethodDecl = NULL;
452 
453   if ((MethodDecl = getInstanceMethod(Context, Sel)))
454     return MethodDecl;
455 
456   for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
457     if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
458       return MethodDecl;
459   return NULL;
460 }
461 
462 // lookupInstanceMethod - Lookup a class method in the protocol and protocols
463 // it inherited.
464 ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(ASTContext &Context,
465                                                     Selector Sel) {
466   ObjCMethodDecl *MethodDecl = NULL;
467 
468   if ((MethodDecl = getClassMethod(Context, Sel)))
469     return MethodDecl;
470 
471   for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
472     if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
473       return MethodDecl;
474   return NULL;
475 }
476 
477 //===----------------------------------------------------------------------===//
478 // ObjCClassDecl
479 //===----------------------------------------------------------------------===//
480 
481 ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
482                              ObjCInterfaceDecl *const *Elts, unsigned nElts,
483                              ASTContext &C)
484   : Decl(ObjCClass, DC, L) {
485   ForwardDecls.set(Elts, nElts, C);
486 }
487 
488 
489 ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
490                                      SourceLocation L,
491                                      ObjCInterfaceDecl *const *Elts,
492                                      unsigned nElts) {
493   return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
494 }
495 
496 void ObjCClassDecl::Destroy(ASTContext &C) {
497 
498   // FIXME: There is no clear ownership policy now for referenced
499   //  ObjCInterfaceDecls.  Some of them can be forward declarations that
500   //  are never later defined (in which case the ObjCClassDecl owns them)
501   //  or the ObjCInterfaceDecl later becomes a real definition later.  Ideally
502   //  we should have separate objects for forward declarations and definitions,
503   //  obviating this problem.  Because of this situation, referenced
504   //  ObjCInterfaceDecls are destroyed in ~TranslationUnit.
505 
506   ForwardDecls.Destroy(C);
507   Decl::Destroy(C);
508 }
509 
510 //===----------------------------------------------------------------------===//
511 // ObjCForwardProtocolDecl
512 //===----------------------------------------------------------------------===//
513 
514 ObjCForwardProtocolDecl::
515 ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
516                         ObjCProtocolDecl *const *Elts, unsigned nElts,
517                         ASTContext &C)
518 : Decl(ObjCForwardProtocol, DC, L) {
519   ReferencedProtocols.set(Elts, nElts, C);
520 }
521 
522 
523 ObjCForwardProtocolDecl *
524 ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
525                                 SourceLocation L,
526                                 ObjCProtocolDecl *const *Elts,
527                                 unsigned NumElts) {
528   return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
529 }
530 
531 void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
532   ReferencedProtocols.Destroy(C);
533   Decl::Destroy(C);
534 }
535 
536 //===----------------------------------------------------------------------===//
537 // ObjCCategoryDecl
538 //===----------------------------------------------------------------------===//
539 
540 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
541                                            SourceLocation L,
542                                            IdentifierInfo *Id) {
543   return new (C) ObjCCategoryDecl(DC, L, Id);
544 }
545 
546 //===----------------------------------------------------------------------===//
547 // ObjCCategoryImplDecl
548 //===----------------------------------------------------------------------===//
549 
550 ObjCCategoryImplDecl *
551 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
552                              SourceLocation L,IdentifierInfo *Id,
553                              ObjCInterfaceDecl *ClassInterface) {
554   return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
555 }
556 
557 
558 void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
559                                              ObjCPropertyImplDecl *property) {
560   // FIXME: The context should be correct before we get here.
561   property->setLexicalDeclContext(this);
562   addDecl(Context, property);
563 }
564 
565 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
566 /// properties implemented in this category @implementation block and returns
567 /// the implemented property that uses it.
568 ///
569 ObjCPropertyImplDecl *ObjCImplDecl::
570 FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
571   for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
572        i != e; ++i){
573     ObjCPropertyImplDecl *PID = *i;
574     if (PID->getPropertyIvarDecl() &&
575         PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
576       return PID;
577   }
578   return 0;
579 }
580 
581 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
582 /// added to the list of those properties @synthesized/@dynamic in this
583 /// category @implementation block.
584 ///
585 ObjCPropertyImplDecl *ObjCImplDecl::
586 FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
587   for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
588        i != e; ++i){
589     ObjCPropertyImplDecl *PID = *i;
590     if (PID->getPropertyDecl()->getIdentifier() == Id)
591       return PID;
592   }
593   return 0;
594 }
595 
596 // getInstanceMethod - This method returns an instance method by looking in
597 // the class implementation. Unlike interfaces, we don't look outside the
598 // implementation.
599 ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
600                                                 Selector Sel) const {
601   // Since instance & class methods can have the same name, the loop below
602   // ensures we get the correct method.
603   //
604   // @interface Whatever
605   // - (int) class_method;
606   // + (float) class_method;
607   // @end
608   //
609   lookup_const_iterator Meth, MethEnd;
610   for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
611        Meth != MethEnd; ++Meth) {
612     ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
613     if (MD && MD->isInstanceMethod())
614       return MD;
615   }
616   return 0;
617 }
618 
619 // getClassMethod - This method returns an instance method by looking in
620 // the class implementation. Unlike interfaces, we don't look outside the
621 // implementation.
622 ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
623                                              Selector Sel) const {
624   // Since instance & class methods can have the same name, the loop below
625   // ensures we get the correct method.
626   //
627   // @interface Whatever
628   // - (int) class_method;
629   // + (float) class_method;
630   // @end
631   //
632   lookup_const_iterator Meth, MethEnd;
633   for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
634        Meth != MethEnd; ++Meth) {
635     ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
636     if (MD && MD->isClassMethod())
637       return MD;
638   }
639   return 0;
640 }
641 
642 //===----------------------------------------------------------------------===//
643 // ObjCImplementationDecl
644 //===----------------------------------------------------------------------===//
645 
646 ObjCImplementationDecl *
647 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
648                                SourceLocation L,
649                                ObjCInterfaceDecl *ClassInterface,
650                                ObjCInterfaceDecl *SuperDecl) {
651   return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
652 }
653 
654 //===----------------------------------------------------------------------===//
655 // ObjCCompatibleAliasDecl
656 //===----------------------------------------------------------------------===//
657 
658 ObjCCompatibleAliasDecl *
659 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
660                                 SourceLocation L,
661                                 IdentifierInfo *Id,
662                                 ObjCInterfaceDecl* AliasedClass) {
663   return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
664 }
665 
666 //===----------------------------------------------------------------------===//
667 // ObjCPropertyDecl
668 //===----------------------------------------------------------------------===//
669 
670 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
671                                            SourceLocation L,
672                                            IdentifierInfo *Id,
673                                            QualType T,
674                                            PropertyControl propControl) {
675   return new (C) ObjCPropertyDecl(DC, L, Id, T);
676 }
677 
678 
679 //===----------------------------------------------------------------------===//
680 // ObjCPropertyImplDecl
681 //===----------------------------------------------------------------------===//
682 
683 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
684                                                    DeclContext *DC,
685                                                    SourceLocation atLoc,
686                                                    SourceLocation L,
687                                                    ObjCPropertyDecl *property,
688                                                    Kind PK,
689                                                    ObjCIvarDecl *ivar) {
690   return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
691 }
692 
693 
694