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