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