]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/AST/DeclObjC.cpp
Update clang to r94309.
[FreeBSD/FreeBSD.git] / lib / AST / DeclObjC.cpp
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 void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts, 
41                            const SourceLocation *Locs, ASTContext &Ctx) {
42   if (Elts == 0)
43     return;
44
45   Locations = new (Ctx) SourceLocation[Elts];
46   memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
47   set(InList, Elts, Ctx);
48 }
49
50 void ObjCProtocolList::Destroy(ASTContext &Ctx) {
51   Ctx.Deallocate(Locations);
52   Locations = 0;
53   ObjCList<ObjCProtocolDecl>::Destroy(Ctx);
54 }
55
56 //===----------------------------------------------------------------------===//
57 // ObjCInterfaceDecl
58 //===----------------------------------------------------------------------===//
59
60 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
61 ///
62 ObjCIvarDecl *
63 ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
64   lookup_const_iterator Ivar, IvarEnd;
65   for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
66     if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
67       return ivar;
68   }
69   return 0;
70 }
71
72 // Get the local instance/class method declared in this interface.
73 ObjCMethodDecl *
74 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
75   // Since instance & class methods can have the same name, the loop below
76   // ensures we get the correct method.
77   //
78   // @interface Whatever
79   // - (int) class_method;
80   // + (float) class_method;
81   // @end
82   //
83   lookup_const_iterator Meth, MethEnd;
84   for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
85     ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
86     if (MD && MD->isInstanceMethod() == isInstance)
87       return MD;
88   }
89   return 0;
90 }
91
92 /// FindPropertyDeclaration - Finds declaration of the property given its name
93 /// in 'PropertyId' and returns it. It returns 0, if not found.
94 /// FIXME: Convert to DeclContext lookup...
95 ///
96 ObjCPropertyDecl *
97 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
98   for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
99     if ((*I)->getIdentifier() == PropertyId)
100       return *I;
101
102   const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
103   if (PID) {
104     for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
105          E = PID->protocol_end(); I != E; ++I)
106       if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
107         return P;
108   }
109
110   if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) {
111     // Look through categories.
112     for (ObjCCategoryDecl *Category = OID->getCategoryList();
113          Category; Category = Category->getNextClassCategory()) {
114       if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId))
115         return P;
116     }
117     // Look through protocols.
118     for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
119          E = OID->protocol_end(); I != E; ++I) {
120       if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
121         return P;
122     }
123     if (OID->getSuperClass())
124       return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
125   } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
126     // Look through protocols.
127     for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
128          E = OCD->protocol_end(); I != E; ++I) {
129       if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
130         return P;
131     }
132   }
133   return 0;
134 }
135
136 /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
137 /// with name 'PropertyId' in the primary class; including those in protocols
138 /// (direct or indirect) used by the promary class.
139 /// FIXME: Convert to DeclContext lookup...
140 ///
141 ObjCPropertyDecl *
142 ObjCContainerDecl::FindPropertyVisibleInPrimaryClass(
143                                             IdentifierInfo *PropertyId) const {
144   assert(isa<ObjCInterfaceDecl>(this) && "FindPropertyVisibleInPrimaryClass");
145   for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
146     if ((*I)->getIdentifier() == PropertyId)
147       return *I;
148   const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this);
149   // Look through protocols.
150   for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
151        E = OID->protocol_end(); I != E; ++I)
152     if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
153       return P;
154   return 0;
155 }
156
157 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
158                               ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
159                               const SourceLocation *Locs,
160                               ASTContext &C)
161 {
162   if (ReferencedProtocols.empty()) {
163     ReferencedProtocols.set(ExtList, ExtNum, Locs, C);
164     return;
165   }
166   // Check for duplicate protocol in class's protocol list.
167   // This is (O)2. But it is extremely rare and number of protocols in
168   // class or its extension are very few.
169   llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
170   llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
171   for (unsigned i = 0; i < ExtNum; i++) {
172     bool protocolExists = false;
173     ObjCProtocolDecl *ProtoInExtension = ExtList[i];
174     for (protocol_iterator p = protocol_begin(), e = protocol_end();
175          p != e; p++) {
176       ObjCProtocolDecl *Proto = (*p);
177       if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
178         protocolExists = true;
179         break;
180       }      
181     }
182     // Do we want to warn on a protocol in extension class which
183     // already exist in the class? Probably not.
184     if (!protocolExists) {
185       ProtocolRefs.push_back(ProtoInExtension);
186       ProtocolLocs.push_back(Locs[i]);
187     }
188   }
189   if (ProtocolRefs.empty())
190     return;
191   // Merge ProtocolRefs into class's protocol list;
192   protocol_loc_iterator pl = protocol_loc_begin();
193   for (protocol_iterator p = protocol_begin(), e = protocol_end();
194        p != e; ++p, ++pl) {
195     ProtocolRefs.push_back(*p);
196     ProtocolLocs.push_back(*pl);
197   }
198   ReferencedProtocols.Destroy(C);
199   unsigned NumProtoRefs = ProtocolRefs.size();
200   setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
201 }
202
203 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
204                                               ObjCInterfaceDecl *&clsDeclared) {
205   ObjCInterfaceDecl* ClassDecl = this;
206   while (ClassDecl != NULL) {
207     if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
208       clsDeclared = ClassDecl;
209       return I;
210     }
211     ClassDecl = ClassDecl->getSuperClass();
212   }
213   return NULL;
214 }
215
216 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
217 /// class whose name is passed as argument. If it is not one of the super classes
218 /// the it returns NULL.
219 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
220                                         const IdentifierInfo*ICName) {
221   ObjCInterfaceDecl* ClassDecl = this;
222   while (ClassDecl != NULL) {
223     if (ClassDecl->getIdentifier() == ICName)
224       return ClassDecl;
225     ClassDecl = ClassDecl->getSuperClass();
226   }
227   return NULL;
228 }
229
230 /// lookupMethod - This method returns an instance/class method by looking in
231 /// the class, its categories, and its super classes (using a linear search).
232 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
233                                                 bool isInstance) const {
234   const ObjCInterfaceDecl* ClassDecl = this;
235   ObjCMethodDecl *MethodDecl = 0;
236
237   while (ClassDecl != NULL) {
238     if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
239       return MethodDecl;
240
241     // Didn't find one yet - look through protocols.
242     const ObjCList<ObjCProtocolDecl> &Protocols =
243       ClassDecl->getReferencedProtocols();
244     for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
245          E = Protocols.end(); I != E; ++I)
246       if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
247         return MethodDecl;
248
249     // Didn't find one yet - now look through categories.
250     ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
251     while (CatDecl) {
252       if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
253         return MethodDecl;
254
255       // Didn't find one yet - look through protocols.
256       const ObjCList<ObjCProtocolDecl> &Protocols =
257         CatDecl->getReferencedProtocols();
258       for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
259            E = Protocols.end(); I != E; ++I)
260         if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
261           return MethodDecl;
262       CatDecl = CatDecl->getNextClassCategory();
263     }
264     ClassDecl = ClassDecl->getSuperClass();
265   }
266   return NULL;
267 }
268
269 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateInstanceMethod(
270                                    const Selector &Sel) {
271   ObjCMethodDecl *Method = 0;
272   if (ObjCImplementationDecl *ImpDecl = getImplementation())
273     Method = ImpDecl->getInstanceMethod(Sel);
274   
275   if (!Method && getSuperClass())
276     return getSuperClass()->lookupPrivateInstanceMethod(Sel);
277   return Method;
278 }
279
280 //===----------------------------------------------------------------------===//
281 // ObjCMethodDecl
282 //===----------------------------------------------------------------------===//
283
284 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
285                                        SourceLocation beginLoc,
286                                        SourceLocation endLoc,
287                                        Selector SelInfo, QualType T,
288                                        DeclContext *contextDecl,
289                                        bool isInstance,
290                                        bool isVariadic,
291                                        bool isSynthesized,
292                                        ImplementationControl impControl) {
293   return new (C) ObjCMethodDecl(beginLoc, endLoc,
294                                   SelInfo, T, contextDecl,
295                                   isInstance,
296                                   isVariadic, isSynthesized, impControl);
297 }
298
299 void ObjCMethodDecl::Destroy(ASTContext &C) {
300   if (Body) Body->Destroy(C);
301   if (SelfDecl) SelfDecl->Destroy(C);
302
303   for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
304     if (*I) (*I)->Destroy(C);
305
306   ParamInfo.Destroy(C);
307
308   Decl::Destroy(C);
309 }
310
311 /// \brief A definition will return its interface declaration.
312 /// An interface declaration will return its definition.
313 /// Otherwise it will return itself.
314 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
315   ASTContext &Ctx = getASTContext();
316   ObjCMethodDecl *Redecl = 0;
317   Decl *CtxD = cast<Decl>(getDeclContext());
318
319   if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
320     if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
321       Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
322
323   } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
324     if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
325       Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
326
327   } else if (ObjCImplementationDecl *ImplD =
328                dyn_cast<ObjCImplementationDecl>(CtxD)) {
329     if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
330       Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
331
332   } else if (ObjCCategoryImplDecl *CImplD =
333                dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
334     if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
335       Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
336   }
337
338   return Redecl ? Redecl : this;
339 }
340
341 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
342   Decl *CtxD = cast<Decl>(getDeclContext());
343
344   if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
345     if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
346       if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
347                                               isInstanceMethod()))
348         return MD;
349
350   } else if (ObjCCategoryImplDecl *CImplD =
351                dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
352     if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
353       if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
354                                                isInstanceMethod()))
355         return MD;
356   }
357
358   return this;
359 }
360
361 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
362                                           const ObjCInterfaceDecl *OID) {
363   QualType selfTy;
364   if (isInstanceMethod()) {
365     // There may be no interface context due to error in declaration
366     // of the interface (which has been reported). Recover gracefully.
367     if (OID) {
368       selfTy = Context.getObjCInterfaceType(OID);
369       selfTy = Context.getObjCObjectPointerType(selfTy);
370     } else {
371       selfTy = Context.getObjCIdType();
372     }
373   } else // we have a factory method.
374     selfTy = Context.getObjCClassType();
375
376   setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
377                                         &Context.Idents.get("self"), selfTy));
378
379   setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
380                                        &Context.Idents.get("_cmd"),
381                                        Context.getObjCSelType()));
382 }
383
384 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
385   if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
386     return ID;
387   if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
388     return CD->getClassInterface();
389   if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
390     return IMD->getClassInterface();
391
392   assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
393   assert(false && "unknown method context");
394   return 0;
395 }
396
397 //===----------------------------------------------------------------------===//
398 // ObjCInterfaceDecl
399 //===----------------------------------------------------------------------===//
400
401 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
402                                              DeclContext *DC,
403                                              SourceLocation atLoc,
404                                              IdentifierInfo *Id,
405                                              SourceLocation ClassLoc,
406                                              bool ForwardDecl, bool isInternal){
407   return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
408                                      isInternal);
409 }
410
411 ObjCInterfaceDecl::
412 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
413                   SourceLocation CLoc, bool FD, bool isInternal)
414   : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
415     TypeForDecl(0), SuperClass(0),
416     CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
417     ClassLoc(CLoc) {
418 }
419
420 void ObjCInterfaceDecl::Destroy(ASTContext &C) {
421   for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
422     if (*I) (*I)->Destroy(C);
423
424   IVars.Destroy(C);
425   // FIXME: CategoryList?
426
427   // FIXME: Because there is no clear ownership
428   //  role between ObjCInterfaceDecls and the ObjCPropertyDecls that they
429   //  reference, we destroy ObjCPropertyDecls in ~TranslationUnit.
430   Decl::Destroy(C);
431 }
432
433 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
434   return getASTContext().getObjCImplementation(
435                                           const_cast<ObjCInterfaceDecl*>(this));
436 }
437
438 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
439   getASTContext().setObjCImplementation(this, ImplD);
440 }
441
442
443 /// FindCategoryDeclaration - Finds category declaration in the list of
444 /// categories for this class and returns it. Name of the category is passed
445 /// in 'CategoryId'. If category not found, return 0;
446 ///
447 ObjCCategoryDecl *
448 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
449   for (ObjCCategoryDecl *Category = getCategoryList();
450        Category; Category = Category->getNextClassCategory())
451     if (Category->getIdentifier() == CategoryId)
452       return Category;
453   return 0;
454 }
455
456 ObjCMethodDecl *
457 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
458   for (ObjCCategoryDecl *Category = getCategoryList();
459        Category; Category = Category->getNextClassCategory())
460     if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
461       if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
462         return MD;
463   return 0;
464 }
465
466 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
467   for (ObjCCategoryDecl *Category = getCategoryList();
468        Category; Category = Category->getNextClassCategory())
469     if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
470       if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
471         return MD;
472   return 0;
473 }
474
475 /// ClassImplementsProtocol - Checks that 'lProto' protocol
476 /// has been implemented in IDecl class, its super class or categories (if
477 /// lookupCategory is true).
478 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
479                                     bool lookupCategory,
480                                     bool RHSIsQualifiedID) {
481   ObjCInterfaceDecl *IDecl = this;
482   // 1st, look up the class.
483   const ObjCList<ObjCProtocolDecl> &Protocols =
484   IDecl->getReferencedProtocols();
485
486   for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
487        E = Protocols.end(); PI != E; ++PI) {
488     if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
489       return true;
490     // This is dubious and is added to be compatible with gcc.  In gcc, it is
491     // also allowed assigning a protocol-qualified 'id' type to a LHS object
492     // when protocol in qualified LHS is in list of protocols in the rhs 'id'
493     // object. This IMO, should be a bug.
494     // FIXME: Treat this as an extension, and flag this as an error when GCC
495     // extensions are not enabled.
496     if (RHSIsQualifiedID &&
497         getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
498       return true;
499   }
500
501   // 2nd, look up the category.
502   if (lookupCategory)
503     for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
504          CDecl = CDecl->getNextClassCategory()) {
505       for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
506            E = CDecl->protocol_end(); PI != E; ++PI)
507         if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
508           return true;
509     }
510
511   // 3rd, look up the super class(s)
512   if (IDecl->getSuperClass())
513     return
514   IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
515                                                   RHSIsQualifiedID);
516
517   return false;
518 }
519
520 //===----------------------------------------------------------------------===//
521 // ObjCIvarDecl
522 //===----------------------------------------------------------------------===//
523
524 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC,
525                                    SourceLocation L, IdentifierInfo *Id,
526                                    QualType T, TypeSourceInfo *TInfo,
527                                    AccessControl ac, Expr *BW) {
528   return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
529 }
530
531
532
533 //===----------------------------------------------------------------------===//
534 // ObjCAtDefsFieldDecl
535 //===----------------------------------------------------------------------===//
536
537 ObjCAtDefsFieldDecl
538 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
539                              IdentifierInfo *Id, QualType T, Expr *BW) {
540   return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW);
541 }
542
543 void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) {
544   this->~ObjCAtDefsFieldDecl();
545   C.Deallocate((void *)this);
546 }
547
548 //===----------------------------------------------------------------------===//
549 // ObjCProtocolDecl
550 //===----------------------------------------------------------------------===//
551
552 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
553                                            SourceLocation L,
554                                            IdentifierInfo *Id) {
555   return new (C) ObjCProtocolDecl(DC, L, Id);
556 }
557
558 void ObjCProtocolDecl::Destroy(ASTContext &C) {
559   ReferencedProtocols.Destroy(C);
560   ObjCContainerDecl::Destroy(C);
561 }
562
563 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
564   ObjCProtocolDecl *PDecl = this;
565
566   if (Name == getIdentifier())
567     return PDecl;
568
569   for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
570     if ((PDecl = (*I)->lookupProtocolNamed(Name)))
571       return PDecl;
572
573   return NULL;
574 }
575
576 // lookupMethod - Lookup a instance/class method in the protocol and protocols
577 // it inherited.
578 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
579                                                bool isInstance) const {
580   ObjCMethodDecl *MethodDecl = NULL;
581
582   if ((MethodDecl = getMethod(Sel, isInstance)))
583     return MethodDecl;
584
585   for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
586     if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
587       return MethodDecl;
588   return NULL;
589 }
590
591 //===----------------------------------------------------------------------===//
592 // ObjCClassDecl
593 //===----------------------------------------------------------------------===//
594
595 ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
596                              ObjCInterfaceDecl *const *Elts,
597                              const SourceLocation *Locs,
598                              unsigned nElts,
599                              ASTContext &C)
600   : Decl(ObjCClass, DC, L) {
601   setClassList(C, Elts, Locs, nElts);
602 }
603
604 void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
605                                  const SourceLocation *Locs, unsigned Num) {
606   ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num,
607                                             llvm::alignof<ObjCClassRef>());
608   for (unsigned i = 0; i < Num; ++i)
609     new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]);
610   
611   NumDecls = Num;
612 }
613
614 ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
615                                      SourceLocation L,
616                                      ObjCInterfaceDecl *const *Elts,
617                                      const SourceLocation *Locs,
618                                      unsigned nElts) {
619   return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C);
620 }
621
622 void ObjCClassDecl::Destroy(ASTContext &C) {
623   // ObjCInterfaceDecls registered with a DeclContext will get destroyed
624   // when the DeclContext is destroyed.  For those created only by a forward
625   // declaration, the first @class that created the ObjCInterfaceDecl gets
626   // to destroy it.
627   // FIXME: Note that this ownership role is very brittle; a better
628   // polict is surely need in the future.
629   for (iterator I = begin(), E = end(); I !=E ; ++I) {
630     ObjCInterfaceDecl *ID = I->getInterface();
631     if (ID->isForwardDecl() && ID->getLocStart() == getLocStart())
632       ID->Destroy(C);
633   }
634   
635   C.Deallocate(ForwardDecls);
636   Decl::Destroy(C);
637 }
638
639 SourceRange ObjCClassDecl::getSourceRange() const {
640   // FIXME: We should include the semicolon
641   assert(NumDecls);
642   return SourceRange(getLocation(), ForwardDecls[NumDecls-1].getLocation());
643 }
644
645 //===----------------------------------------------------------------------===//
646 // ObjCForwardProtocolDecl
647 //===----------------------------------------------------------------------===//
648
649 ObjCForwardProtocolDecl::
650 ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
651                         ObjCProtocolDecl *const *Elts, unsigned nElts,
652                         const SourceLocation *Locs, ASTContext &C)
653 : Decl(ObjCForwardProtocol, DC, L) {
654   ReferencedProtocols.set(Elts, nElts, Locs, C);
655 }
656
657
658 ObjCForwardProtocolDecl *
659 ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
660                                 SourceLocation L,
661                                 ObjCProtocolDecl *const *Elts,
662                                 unsigned NumElts,
663                                 const SourceLocation *Locs) {
664   return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C);
665 }
666
667 void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
668   ReferencedProtocols.Destroy(C);
669   Decl::Destroy(C);
670 }
671
672 //===----------------------------------------------------------------------===//
673 // ObjCCategoryDecl
674 //===----------------------------------------------------------------------===//
675
676 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
677                                            SourceLocation AtLoc, 
678                                            SourceLocation ClassNameLoc,
679                                            SourceLocation CategoryNameLoc,
680                                            IdentifierInfo *Id) {
681   return new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id);
682 }
683
684 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
685   return getASTContext().getObjCImplementation(
686                                            const_cast<ObjCCategoryDecl*>(this));
687 }
688
689 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
690   getASTContext().setObjCImplementation(this, ImplD);
691 }
692
693
694 //===----------------------------------------------------------------------===//
695 // ObjCCategoryImplDecl
696 //===----------------------------------------------------------------------===//
697
698 ObjCCategoryImplDecl *
699 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
700                              SourceLocation L,IdentifierInfo *Id,
701                              ObjCInterfaceDecl *ClassInterface) {
702   return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface);
703 }
704
705 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
706   return getClassInterface()->FindCategoryDeclaration(getIdentifier());
707 }
708
709
710 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
711   // FIXME: The context should be correct before we get here.
712   property->setLexicalDeclContext(this);
713   addDecl(property);
714 }
715
716 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
717   ASTContext &Ctx = getASTContext();
718
719   if (ObjCImplementationDecl *ImplD
720         = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
721     if (IFace)
722       Ctx.setObjCImplementation(IFace, ImplD);
723
724   } else if (ObjCCategoryImplDecl *ImplD =
725              dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
726     if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
727       Ctx.setObjCImplementation(CD, ImplD);
728   }
729
730   ClassInterface = IFace;
731 }
732
733 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
734 /// properties implemented in this category @implementation block and returns
735 /// the implemented property that uses it.
736 ///
737 ObjCPropertyImplDecl *ObjCImplDecl::
738 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
739   for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
740     ObjCPropertyImplDecl *PID = *i;
741     if (PID->getPropertyIvarDecl() &&
742         PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
743       return PID;
744   }
745   return 0;
746 }
747
748 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
749 /// added to the list of those properties @synthesized/@dynamic in this
750 /// category @implementation block.
751 ///
752 ObjCPropertyImplDecl *ObjCImplDecl::
753 FindPropertyImplDecl(IdentifierInfo *Id) const {
754   for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
755     ObjCPropertyImplDecl *PID = *i;
756     if (PID->getPropertyDecl()->getIdentifier() == Id)
757       return PID;
758   }
759   return 0;
760 }
761
762 //===----------------------------------------------------------------------===//
763 // ObjCImplementationDecl
764 //===----------------------------------------------------------------------===//
765
766 ObjCImplementationDecl *
767 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
768                                SourceLocation L,
769                                ObjCInterfaceDecl *ClassInterface,
770                                ObjCInterfaceDecl *SuperDecl) {
771   return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
772 }
773
774 //===----------------------------------------------------------------------===//
775 // ObjCCompatibleAliasDecl
776 //===----------------------------------------------------------------------===//
777
778 ObjCCompatibleAliasDecl *
779 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
780                                 SourceLocation L,
781                                 IdentifierInfo *Id,
782                                 ObjCInterfaceDecl* AliasedClass) {
783   return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
784 }
785
786 //===----------------------------------------------------------------------===//
787 // ObjCPropertyDecl
788 //===----------------------------------------------------------------------===//
789
790 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
791                                            SourceLocation L,
792                                            IdentifierInfo *Id,
793                                            SourceLocation AtLoc,
794                                            QualType T,
795                                            PropertyControl propControl) {
796   return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T);
797 }
798
799
800 //===----------------------------------------------------------------------===//
801 // ObjCPropertyImplDecl
802 //===----------------------------------------------------------------------===//
803
804 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
805                                                    DeclContext *DC,
806                                                    SourceLocation atLoc,
807                                                    SourceLocation L,
808                                                    ObjCPropertyDecl *property,
809                                                    Kind PK,
810                                                    ObjCIvarDecl *ivar) {
811   return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar);
812 }
813
814