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 "clang/AST/ASTMutationListener.h"
18#include "llvm/ADT/STLExtras.h"
19using namespace clang;
20
21//===----------------------------------------------------------------------===//
22// ObjCListBase
23//===----------------------------------------------------------------------===//
24
25void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
26  List = 0;
27  if (Elts == 0) return;  // Setting to an empty list is a noop.
28
29
30  List = new (Ctx) void*[Elts];
31  NumElts = Elts;
32  memcpy(List, InList, sizeof(void*)*Elts);
33}
34
35void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
36                           const SourceLocation *Locs, ASTContext &Ctx) {
37  if (Elts == 0)
38    return;
39
40  Locations = new (Ctx) SourceLocation[Elts];
41  memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
42  set(InList, Elts, Ctx);
43}
44
45//===----------------------------------------------------------------------===//
46// ObjCInterfaceDecl
47//===----------------------------------------------------------------------===//
48
49void ObjCContainerDecl::anchor() { }
50
51/// getIvarDecl - This method looks up an ivar in this ContextDecl.
52///
53ObjCIvarDecl *
54ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
55  lookup_const_iterator Ivar, IvarEnd;
56  for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
57    if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
58      return ivar;
59  }
60  return 0;
61}
62
63// Get the local instance/class method declared in this interface.
64ObjCMethodDecl *
65ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
66  // Since instance & class methods can have the same name, the loop below
67  // ensures we get the correct method.
68  //
69  // @interface Whatever
70  // - (int) class_method;
71  // + (float) class_method;
72  // @end
73  //
74  lookup_const_iterator Meth, MethEnd;
75  for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
76    ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
77    if (MD && MD->isInstanceMethod() == isInstance)
78      return MD;
79  }
80  return 0;
81}
82
83ObjCPropertyDecl *
84ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
85                                   IdentifierInfo *propertyID) {
86
87  DeclContext::lookup_const_iterator I, E;
88  llvm::tie(I, E) = DC->lookup(propertyID);
89  for ( ; I != E; ++I)
90    if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
91      return PD;
92
93  return 0;
94}
95
96/// FindPropertyDeclaration - Finds declaration of the property given its name
97/// in 'PropertyId' and returns it. It returns 0, if not found.
98ObjCPropertyDecl *
99ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
100
101  if (ObjCPropertyDecl *PD =
102        ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
103    return PD;
104
105  switch (getKind()) {
106    default:
107      break;
108    case Decl::ObjCProtocol: {
109      const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
110      for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
111           E = PID->protocol_end(); I != E; ++I)
112        if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
113          return P;
114      break;
115    }
116    case Decl::ObjCInterface: {
117      const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
118      // Look through categories.
119      for (ObjCCategoryDecl *Cat = OID->getCategoryList();
120           Cat; Cat = Cat->getNextClassCategory())
121        if (!Cat->IsClassExtension())
122          if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
123            return P;
124
125      // Look through protocols.
126      for (ObjCInterfaceDecl::all_protocol_iterator
127            I = OID->all_referenced_protocol_begin(),
128            E = OID->all_referenced_protocol_end(); I != E; ++I)
129        if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
130          return P;
131
132      // Finally, check the super class.
133      if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
134        return superClass->FindPropertyDeclaration(PropertyId);
135      break;
136    }
137    case Decl::ObjCCategory: {
138      const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
139      // Look through protocols.
140      if (!OCD->IsClassExtension())
141        for (ObjCCategoryDecl::protocol_iterator
142              I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
143        if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
144          return P;
145
146      break;
147    }
148  }
149  return 0;
150}
151
152void ObjCInterfaceDecl::anchor() { }
153
154/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
155/// with name 'PropertyId' in the primary class; including those in protocols
156/// (direct or indirect) used by the primary class.
157///
158ObjCPropertyDecl *
159ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
160                                            IdentifierInfo *PropertyId) const {
161  // FIXME: Should make sure no callers ever do this.
162  if (!hasDefinition())
163    return 0;
164
165  if (data().ExternallyCompleted)
166    LoadExternalDefinition();
167
168  if (ObjCPropertyDecl *PD =
169      ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
170    return PD;
171
172  // Look through protocols.
173  for (ObjCInterfaceDecl::all_protocol_iterator
174        I = all_referenced_protocol_begin(),
175        E = all_referenced_protocol_end(); I != E; ++I)
176    if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
177      return P;
178
179  return 0;
180}
181
182void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
183                              ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
184                              ASTContext &C)
185{
186  if (data().ExternallyCompleted)
187    LoadExternalDefinition();
188
189  if (data().AllReferencedProtocols.empty() &&
190      data().ReferencedProtocols.empty()) {
191    data().AllReferencedProtocols.set(ExtList, ExtNum, C);
192    return;
193  }
194
195  // Check for duplicate protocol in class's protocol list.
196  // This is O(n*m). But it is extremely rare and number of protocols in
197  // class or its extension are very few.
198  SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
199  for (unsigned i = 0; i < ExtNum; i++) {
200    bool protocolExists = false;
201    ObjCProtocolDecl *ProtoInExtension = ExtList[i];
202    for (all_protocol_iterator
203          p = all_referenced_protocol_begin(),
204          e = all_referenced_protocol_end(); p != e; ++p) {
205      ObjCProtocolDecl *Proto = (*p);
206      if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
207        protocolExists = true;
208        break;
209      }
210    }
211    // Do we want to warn on a protocol in extension class which
212    // already exist in the class? Probably not.
213    if (!protocolExists)
214      ProtocolRefs.push_back(ProtoInExtension);
215  }
216
217  if (ProtocolRefs.empty())
218    return;
219
220  // Merge ProtocolRefs into class's protocol list;
221  for (all_protocol_iterator p = all_referenced_protocol_begin(),
222        e = all_referenced_protocol_end(); p != e; ++p) {
223    ProtocolRefs.push_back(*p);
224  }
225
226  data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
227}
228
229void ObjCInterfaceDecl::allocateDefinitionData() {
230  assert(!hasDefinition() && "ObjC class already has a definition");
231  Data = new (getASTContext()) DefinitionData();
232  Data->Definition = this;
233
234  // Make the type point at the definition, now that we have one.
235  if (TypeForDecl)
236    cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
237}
238
239void ObjCInterfaceDecl::startDefinition() {
240  allocateDefinitionData();
241
242  // Update all of the declarations with a pointer to the definition.
243  for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
244       RD != RDEnd; ++RD) {
245    if (*RD != this)
246      RD->Data = Data;
247  }
248}
249
250/// getFirstClassExtension - Find first class extension of the given class.
251ObjCCategoryDecl* ObjCInterfaceDecl::getFirstClassExtension() const {
252  for (ObjCCategoryDecl *CDecl = getCategoryList(); CDecl;
253       CDecl = CDecl->getNextClassCategory())
254    if (CDecl->IsClassExtension())
255      return CDecl;
256  return 0;
257}
258
259/// getNextClassCategory - Find next class extension in list of categories.
260const ObjCCategoryDecl* ObjCCategoryDecl::getNextClassExtension() const {
261  for (const ObjCCategoryDecl *CDecl = getNextClassCategory(); CDecl;
262        CDecl = CDecl->getNextClassCategory())
263    if (CDecl->IsClassExtension())
264      return CDecl;
265  return 0;
266}
267
268ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
269                                              ObjCInterfaceDecl *&clsDeclared) {
270  // FIXME: Should make sure no callers ever do this.
271  if (!hasDefinition())
272    return 0;
273
274  if (data().ExternallyCompleted)
275    LoadExternalDefinition();
276
277  ObjCInterfaceDecl* ClassDecl = this;
278  while (ClassDecl != NULL) {
279    if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
280      clsDeclared = ClassDecl;
281      return I;
282    }
283    for (const ObjCCategoryDecl *CDecl = ClassDecl->getFirstClassExtension();
284         CDecl; CDecl = CDecl->getNextClassExtension()) {
285      if (ObjCIvarDecl *I = CDecl->getIvarDecl(ID)) {
286        clsDeclared = ClassDecl;
287        return I;
288      }
289    }
290
291    ClassDecl = ClassDecl->getSuperClass();
292  }
293  return NULL;
294}
295
296/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
297/// class whose name is passed as argument. If it is not one of the super classes
298/// the it returns NULL.
299ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
300                                        const IdentifierInfo*ICName) {
301  // FIXME: Should make sure no callers ever do this.
302  if (!hasDefinition())
303    return 0;
304
305  if (data().ExternallyCompleted)
306    LoadExternalDefinition();
307
308  ObjCInterfaceDecl* ClassDecl = this;
309  while (ClassDecl != NULL) {
310    if (ClassDecl->getIdentifier() == ICName)
311      return ClassDecl;
312    ClassDecl = ClassDecl->getSuperClass();
313  }
314  return NULL;
315}
316
317/// lookupMethod - This method returns an instance/class method by looking in
318/// the class, its categories, and its super classes (using a linear search).
319ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel,
320                                     bool isInstance,
321                                     bool shallowCategoryLookup) const {
322  // FIXME: Should make sure no callers ever do this.
323  if (!hasDefinition())
324    return 0;
325
326  const ObjCInterfaceDecl* ClassDecl = this;
327  ObjCMethodDecl *MethodDecl = 0;
328
329  if (data().ExternallyCompleted)
330    LoadExternalDefinition();
331
332  while (ClassDecl != NULL) {
333    if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
334      return MethodDecl;
335
336    // Didn't find one yet - look through protocols.
337    for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
338                                              E = ClassDecl->protocol_end();
339           I != E; ++I)
340      if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
341        return MethodDecl;
342
343    // Didn't find one yet - now look through categories.
344    ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
345    while (CatDecl) {
346      if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
347        return MethodDecl;
348
349      if (!shallowCategoryLookup) {
350        // Didn't find one yet - look through protocols.
351        const ObjCList<ObjCProtocolDecl> &Protocols =
352          CatDecl->getReferencedProtocols();
353        for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
354             E = Protocols.end(); I != E; ++I)
355          if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
356            return MethodDecl;
357      }
358      CatDecl = CatDecl->getNextClassCategory();
359    }
360
361    ClassDecl = ClassDecl->getSuperClass();
362  }
363  return NULL;
364}
365
366// Will search "local" class/category implementations for a method decl.
367// If failed, then we search in class's root for an instance method.
368// Returns 0 if no method is found.
369ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
370                                   const Selector &Sel,
371                                   bool Instance) const {
372  // FIXME: Should make sure no callers ever do this.
373  if (!hasDefinition())
374    return 0;
375
376  if (data().ExternallyCompleted)
377    LoadExternalDefinition();
378
379  ObjCMethodDecl *Method = 0;
380  if (ObjCImplementationDecl *ImpDecl = getImplementation())
381    Method = Instance ? ImpDecl->getInstanceMethod(Sel)
382                      : ImpDecl->getClassMethod(Sel);
383
384  // Look through local category implementations associated with the class.
385  if (!Method)
386    Method = Instance ? getCategoryInstanceMethod(Sel)
387                      : getCategoryClassMethod(Sel);
388
389  // Before we give up, check if the selector is an instance method.
390  // But only in the root. This matches gcc's behavior and what the
391  // runtime expects.
392  if (!Instance && !Method && !getSuperClass()) {
393    Method = lookupInstanceMethod(Sel);
394    // Look through local category implementations associated
395    // with the root class.
396    if (!Method)
397      Method = lookupPrivateMethod(Sel, true);
398  }
399
400  if (!Method && getSuperClass())
401    return getSuperClass()->lookupPrivateMethod(Sel, Instance);
402  return Method;
403}
404
405//===----------------------------------------------------------------------===//
406// ObjCMethodDecl
407//===----------------------------------------------------------------------===//
408
409ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
410                                       SourceLocation beginLoc,
411                                       SourceLocation endLoc,
412                                       Selector SelInfo, QualType T,
413                                       TypeSourceInfo *ResultTInfo,
414                                       DeclContext *contextDecl,
415                                       bool isInstance,
416                                       bool isVariadic,
417                                       bool isSynthesized,
418                                       bool isImplicitlyDeclared,
419                                       bool isDefined,
420                                       ImplementationControl impControl,
421                                       bool HasRelatedResultType) {
422  return new (C) ObjCMethodDecl(beginLoc, endLoc,
423                                SelInfo, T, ResultTInfo, contextDecl,
424                                isInstance,
425                                isVariadic, isSynthesized, isImplicitlyDeclared,
426                                isDefined,
427                                impControl,
428                                HasRelatedResultType);
429}
430
431ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
432  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCMethodDecl));
433  return new (Mem) ObjCMethodDecl(SourceLocation(), SourceLocation(),
434                                  Selector(), QualType(), 0, 0);
435}
436
437void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
438  assert(PrevMethod);
439  getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
440  IsRedeclaration = true;
441  PrevMethod->HasRedeclaration = true;
442}
443
444void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
445                                         ArrayRef<ParmVarDecl*> Params,
446                                         ArrayRef<SourceLocation> SelLocs) {
447  ParamsAndSelLocs = 0;
448  NumParams = Params.size();
449  if (Params.empty() && SelLocs.empty())
450    return;
451
452  unsigned Size = sizeof(ParmVarDecl *) * NumParams +
453                  sizeof(SourceLocation) * SelLocs.size();
454  ParamsAndSelLocs = C.Allocate(Size);
455  std::copy(Params.begin(), Params.end(), getParams());
456  std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
457}
458
459void ObjCMethodDecl::getSelectorLocs(
460                               SmallVectorImpl<SourceLocation> &SelLocs) const {
461  for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
462    SelLocs.push_back(getSelectorLoc(i));
463}
464
465void ObjCMethodDecl::setMethodParams(ASTContext &C,
466                                     ArrayRef<ParmVarDecl*> Params,
467                                     ArrayRef<SourceLocation> SelLocs) {
468  assert((!SelLocs.empty() || isImplicit()) &&
469         "No selector locs for non-implicit method");
470  if (isImplicit())
471    return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
472
473  SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params,
474                                        DeclEndLoc);
475  if (SelLocsKind != SelLoc_NonStandard)
476    return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
477
478  setParamsAndSelLocs(C, Params, SelLocs);
479}
480
481/// \brief A definition will return its interface declaration.
482/// An interface declaration will return its definition.
483/// Otherwise it will return itself.
484ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
485  ASTContext &Ctx = getASTContext();
486  ObjCMethodDecl *Redecl = 0;
487  if (HasRedeclaration)
488    Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
489  if (Redecl)
490    return Redecl;
491
492  Decl *CtxD = cast<Decl>(getDeclContext());
493
494  if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
495    if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
496      Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
497
498  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
499    if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
500      Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
501
502  } else if (ObjCImplementationDecl *ImplD =
503               dyn_cast<ObjCImplementationDecl>(CtxD)) {
504    if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
505      Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
506
507  } else if (ObjCCategoryImplDecl *CImplD =
508               dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
509    if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
510      Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
511  }
512
513  if (!Redecl && isRedeclaration()) {
514    // This is the last redeclaration, go back to the first method.
515    return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
516                                                    isInstanceMethod());
517  }
518
519  return Redecl ? Redecl : this;
520}
521
522ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
523  Decl *CtxD = cast<Decl>(getDeclContext());
524
525  if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
526    if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
527      if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
528                                              isInstanceMethod()))
529        return MD;
530
531  } else if (ObjCCategoryImplDecl *CImplD =
532               dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
533    if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
534      if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
535                                               isInstanceMethod()))
536        return MD;
537  }
538
539  if (isRedeclaration())
540    return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
541                                                    isInstanceMethod());
542
543  return this;
544}
545
546SourceLocation ObjCMethodDecl::getLocEnd() const {
547  if (Stmt *Body = getBody())
548    return Body->getLocEnd();
549  return DeclEndLoc;
550}
551
552ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
553  ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
554  if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
555    return family;
556
557  // Check for an explicit attribute.
558  if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
559    // The unfortunate necessity of mapping between enums here is due
560    // to the attributes framework.
561    switch (attr->getFamily()) {
562    case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
563    case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
564    case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
565    case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
566    case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
567    case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
568    }
569    Family = static_cast<unsigned>(family);
570    return family;
571  }
572
573  family = getSelector().getMethodFamily();
574  switch (family) {
575  case OMF_None: break;
576
577  // init only has a conventional meaning for an instance method, and
578  // it has to return an object.
579  case OMF_init:
580    if (!isInstanceMethod() || !getResultType()->isObjCObjectPointerType())
581      family = OMF_None;
582    break;
583
584  // alloc/copy/new have a conventional meaning for both class and
585  // instance methods, but they require an object return.
586  case OMF_alloc:
587  case OMF_copy:
588  case OMF_mutableCopy:
589  case OMF_new:
590    if (!getResultType()->isObjCObjectPointerType())
591      family = OMF_None;
592    break;
593
594  // These selectors have a conventional meaning only for instance methods.
595  case OMF_dealloc:
596  case OMF_finalize:
597  case OMF_retain:
598  case OMF_release:
599  case OMF_autorelease:
600  case OMF_retainCount:
601  case OMF_self:
602    if (!isInstanceMethod())
603      family = OMF_None;
604    break;
605
606  case OMF_performSelector:
607    if (!isInstanceMethod() ||
608        !getResultType()->isObjCIdType())
609      family = OMF_None;
610    else {
611      unsigned noParams = param_size();
612      if (noParams < 1 || noParams > 3)
613        family = OMF_None;
614      else {
615        ObjCMethodDecl::arg_type_iterator it = arg_type_begin();
616        QualType ArgT = (*it);
617        if (!ArgT->isObjCSelType()) {
618          family = OMF_None;
619          break;
620        }
621        while (--noParams) {
622          it++;
623          ArgT = (*it);
624          if (!ArgT->isObjCIdType()) {
625            family = OMF_None;
626            break;
627          }
628        }
629      }
630    }
631    break;
632
633  }
634
635  // Cache the result.
636  Family = static_cast<unsigned>(family);
637  return family;
638}
639
640void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
641                                          const ObjCInterfaceDecl *OID) {
642  QualType selfTy;
643  if (isInstanceMethod()) {
644    // There may be no interface context due to error in declaration
645    // of the interface (which has been reported). Recover gracefully.
646    if (OID) {
647      selfTy = Context.getObjCInterfaceType(OID);
648      selfTy = Context.getObjCObjectPointerType(selfTy);
649    } else {
650      selfTy = Context.getObjCIdType();
651    }
652  } else // we have a factory method.
653    selfTy = Context.getObjCClassType();
654
655  bool selfIsPseudoStrong = false;
656  bool selfIsConsumed = false;
657
658  if (Context.getLangOpts().ObjCAutoRefCount) {
659    if (isInstanceMethod()) {
660      selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
661
662      // 'self' is always __strong.  It's actually pseudo-strong except
663      // in init methods (or methods labeled ns_consumes_self), though.
664      Qualifiers qs;
665      qs.setObjCLifetime(Qualifiers::OCL_Strong);
666      selfTy = Context.getQualifiedType(selfTy, qs);
667
668      // In addition, 'self' is const unless this is an init method.
669      if (getMethodFamily() != OMF_init && !selfIsConsumed) {
670        selfTy = selfTy.withConst();
671        selfIsPseudoStrong = true;
672      }
673    }
674    else {
675      assert(isClassMethod());
676      // 'self' is always const in class methods.
677      selfTy = selfTy.withConst();
678      selfIsPseudoStrong = true;
679    }
680  }
681
682  ImplicitParamDecl *self
683    = ImplicitParamDecl::Create(Context, this, SourceLocation(),
684                                &Context.Idents.get("self"), selfTy);
685  setSelfDecl(self);
686
687  if (selfIsConsumed)
688    self->addAttr(new (Context) NSConsumedAttr(SourceLocation(), Context));
689
690  if (selfIsPseudoStrong)
691    self->setARCPseudoStrong(true);
692
693  setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
694                                       &Context.Idents.get("_cmd"),
695                                       Context.getObjCSelType()));
696}
697
698ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
699  if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
700    return ID;
701  if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
702    return CD->getClassInterface();
703  if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
704    return IMD->getClassInterface();
705
706  assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
707  llvm_unreachable("unknown method context");
708}
709
710//===----------------------------------------------------------------------===//
711// ObjCInterfaceDecl
712//===----------------------------------------------------------------------===//
713
714ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
715                                             DeclContext *DC,
716                                             SourceLocation atLoc,
717                                             IdentifierInfo *Id,
718                                             ObjCInterfaceDecl *PrevDecl,
719                                             SourceLocation ClassLoc,
720                                             bool isInternal){
721  ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc,
722                                                        PrevDecl, isInternal);
723  C.getObjCInterfaceType(Result, PrevDecl);
724  return Result;
725}
726
727ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C,
728                                                         unsigned ID) {
729  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCInterfaceDecl));
730  return new (Mem) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(),
731                                     0, false);
732}
733
734ObjCInterfaceDecl::
735ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
736                  SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
737                  bool isInternal)
738  : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
739    TypeForDecl(0), Data()
740{
741  setPreviousDeclaration(PrevDecl);
742
743  // Copy the 'data' pointer over.
744  if (PrevDecl)
745    Data = PrevDecl->Data;
746
747  setImplicit(isInternal);
748}
749
750void ObjCInterfaceDecl::LoadExternalDefinition() const {
751  assert(data().ExternallyCompleted && "Class is not externally completed");
752  data().ExternallyCompleted = false;
753  getASTContext().getExternalSource()->CompleteType(
754                                        const_cast<ObjCInterfaceDecl *>(this));
755}
756
757void ObjCInterfaceDecl::setExternallyCompleted() {
758  assert(getASTContext().getExternalSource() &&
759         "Class can't be externally completed without an external source");
760  assert(hasDefinition() &&
761         "Forward declarations can't be externally completed");
762  data().ExternallyCompleted = true;
763}
764
765ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
766  if (const ObjCInterfaceDecl *Def = getDefinition()) {
767    if (data().ExternallyCompleted)
768      LoadExternalDefinition();
769
770    return getASTContext().getObjCImplementation(
771             const_cast<ObjCInterfaceDecl*>(Def));
772  }
773
774  // FIXME: Should make sure no callers ever do this.
775  return 0;
776}
777
778void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
779  getASTContext().setObjCImplementation(getDefinition(), ImplD);
780}
781
782/// all_declared_ivar_begin - return first ivar declared in this class,
783/// its extensions and its implementation. Lazily build the list on first
784/// access.
785ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
786  // FIXME: Should make sure no callers ever do this.
787  if (!hasDefinition())
788    return 0;
789
790  if (data().IvarList)
791    return data().IvarList;
792
793  ObjCIvarDecl *curIvar = 0;
794  if (!ivar_empty()) {
795    ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
796    data().IvarList = *I; ++I;
797    for (curIvar = data().IvarList; I != E; curIvar = *I, ++I)
798      curIvar->setNextIvar(*I);
799  }
800
801  for (const ObjCCategoryDecl *CDecl = getFirstClassExtension(); CDecl;
802       CDecl = CDecl->getNextClassExtension()) {
803    if (!CDecl->ivar_empty()) {
804      ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
805                                          E = CDecl->ivar_end();
806      if (!data().IvarList) {
807        data().IvarList = *I; ++I;
808        curIvar = data().IvarList;
809      }
810      for ( ;I != E; curIvar = *I, ++I)
811        curIvar->setNextIvar(*I);
812    }
813  }
814
815  if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
816    if (!ImplDecl->ivar_empty()) {
817      ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
818                                            E = ImplDecl->ivar_end();
819      if (!data().IvarList) {
820        data().IvarList = *I; ++I;
821        curIvar = data().IvarList;
822      }
823      for ( ;I != E; curIvar = *I, ++I)
824        curIvar->setNextIvar(*I);
825    }
826  }
827  return data().IvarList;
828}
829
830/// FindCategoryDeclaration - Finds category declaration in the list of
831/// categories for this class and returns it. Name of the category is passed
832/// in 'CategoryId'. If category not found, return 0;
833///
834ObjCCategoryDecl *
835ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
836  // FIXME: Should make sure no callers ever do this.
837  if (!hasDefinition())
838    return 0;
839
840  if (data().ExternallyCompleted)
841    LoadExternalDefinition();
842
843  for (ObjCCategoryDecl *Category = getCategoryList();
844       Category; Category = Category->getNextClassCategory())
845    if (Category->getIdentifier() == CategoryId)
846      return Category;
847  return 0;
848}
849
850ObjCMethodDecl *
851ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
852  for (ObjCCategoryDecl *Category = getCategoryList();
853       Category; Category = Category->getNextClassCategory())
854    if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
855      if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
856        return MD;
857  return 0;
858}
859
860ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
861  for (ObjCCategoryDecl *Category = getCategoryList();
862       Category; Category = Category->getNextClassCategory())
863    if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
864      if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
865        return MD;
866  return 0;
867}
868
869/// ClassImplementsProtocol - Checks that 'lProto' protocol
870/// has been implemented in IDecl class, its super class or categories (if
871/// lookupCategory is true).
872bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
873                                    bool lookupCategory,
874                                    bool RHSIsQualifiedID) {
875  if (!hasDefinition())
876    return false;
877
878  ObjCInterfaceDecl *IDecl = this;
879  // 1st, look up the class.
880  for (ObjCInterfaceDecl::protocol_iterator
881        PI = IDecl->protocol_begin(), E = IDecl->protocol_end(); PI != E; ++PI){
882    if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
883      return true;
884    // This is dubious and is added to be compatible with gcc.  In gcc, it is
885    // also allowed assigning a protocol-qualified 'id' type to a LHS object
886    // when protocol in qualified LHS is in list of protocols in the rhs 'id'
887    // object. This IMO, should be a bug.
888    // FIXME: Treat this as an extension, and flag this as an error when GCC
889    // extensions are not enabled.
890    if (RHSIsQualifiedID &&
891        getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
892      return true;
893  }
894
895  // 2nd, look up the category.
896  if (lookupCategory)
897    for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
898         CDecl = CDecl->getNextClassCategory()) {
899      for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
900           E = CDecl->protocol_end(); PI != E; ++PI)
901        if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
902          return true;
903    }
904
905  // 3rd, look up the super class(s)
906  if (IDecl->getSuperClass())
907    return
908  IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
909                                                  RHSIsQualifiedID);
910
911  return false;
912}
913
914//===----------------------------------------------------------------------===//
915// ObjCIvarDecl
916//===----------------------------------------------------------------------===//
917
918void ObjCIvarDecl::anchor() { }
919
920ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
921                                   SourceLocation StartLoc,
922                                   SourceLocation IdLoc, IdentifierInfo *Id,
923                                   QualType T, TypeSourceInfo *TInfo,
924                                   AccessControl ac, Expr *BW,
925                                   bool synthesized) {
926  if (DC) {
927    // Ivar's can only appear in interfaces, implementations (via synthesized
928    // properties), and class extensions (via direct declaration, or synthesized
929    // properties).
930    //
931    // FIXME: This should really be asserting this:
932    //   (isa<ObjCCategoryDecl>(DC) &&
933    //    cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
934    // but unfortunately we sometimes place ivars into non-class extension
935    // categories on error. This breaks an AST invariant, and should not be
936    // fixed.
937    assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
938            isa<ObjCCategoryDecl>(DC)) &&
939           "Invalid ivar decl context!");
940    // Once a new ivar is created in any of class/class-extension/implementation
941    // decl contexts, the previously built IvarList must be rebuilt.
942    ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
943    if (!ID) {
944      if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC))
945        ID = IM->getClassInterface();
946      else
947        ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
948    }
949    ID->setIvarList(0);
950  }
951
952  return new (C) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo,
953                              ac, BW, synthesized);
954}
955
956ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
957  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCIvarDecl));
958  return new (Mem) ObjCIvarDecl(0, SourceLocation(), SourceLocation(), 0,
959                                QualType(), 0, ObjCIvarDecl::None, 0, false);
960}
961
962const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
963  const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
964
965  switch (DC->getKind()) {
966  default:
967  case ObjCCategoryImpl:
968  case ObjCProtocol:
969    llvm_unreachable("invalid ivar container!");
970
971    // Ivars can only appear in class extension categories.
972  case ObjCCategory: {
973    const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
974    assert(CD->IsClassExtension() && "invalid container for ivar!");
975    return CD->getClassInterface();
976  }
977
978  case ObjCImplementation:
979    return cast<ObjCImplementationDecl>(DC)->getClassInterface();
980
981  case ObjCInterface:
982    return cast<ObjCInterfaceDecl>(DC);
983  }
984}
985
986//===----------------------------------------------------------------------===//
987// ObjCAtDefsFieldDecl
988//===----------------------------------------------------------------------===//
989
990void ObjCAtDefsFieldDecl::anchor() { }
991
992ObjCAtDefsFieldDecl
993*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
994                             SourceLocation StartLoc,  SourceLocation IdLoc,
995                             IdentifierInfo *Id, QualType T, Expr *BW) {
996  return new (C) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
997}
998
999ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
1000                                                             unsigned ID) {
1001  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCAtDefsFieldDecl));
1002  return new (Mem) ObjCAtDefsFieldDecl(0, SourceLocation(), SourceLocation(),
1003                                       0, QualType(), 0);
1004}
1005
1006//===----------------------------------------------------------------------===//
1007// ObjCProtocolDecl
1008//===----------------------------------------------------------------------===//
1009
1010void ObjCProtocolDecl::anchor() { }
1011
1012ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
1013                                   SourceLocation nameLoc,
1014                                   SourceLocation atStartLoc,
1015                                   ObjCProtocolDecl *PrevDecl)
1016  : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data()
1017{
1018  setPreviousDeclaration(PrevDecl);
1019  if (PrevDecl)
1020    Data = PrevDecl->Data;
1021}
1022
1023ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
1024                                           IdentifierInfo *Id,
1025                                           SourceLocation nameLoc,
1026                                           SourceLocation atStartLoc,
1027                                           ObjCProtocolDecl *PrevDecl) {
1028  ObjCProtocolDecl *Result
1029    = new (C) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl);
1030
1031  return Result;
1032}
1033
1034ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
1035                                                       unsigned ID) {
1036  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCProtocolDecl));
1037  return new (Mem) ObjCProtocolDecl(0, 0, SourceLocation(), SourceLocation(),
1038                                    0);
1039}
1040
1041ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
1042  ObjCProtocolDecl *PDecl = this;
1043
1044  if (Name == getIdentifier())
1045    return PDecl;
1046
1047  for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1048    if ((PDecl = (*I)->lookupProtocolNamed(Name)))
1049      return PDecl;
1050
1051  return NULL;
1052}
1053
1054// lookupMethod - Lookup a instance/class method in the protocol and protocols
1055// it inherited.
1056ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
1057                                               bool isInstance) const {
1058  ObjCMethodDecl *MethodDecl = NULL;
1059
1060  if ((MethodDecl = getMethod(Sel, isInstance)))
1061    return MethodDecl;
1062
1063  for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
1064    if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
1065      return MethodDecl;
1066  return NULL;
1067}
1068
1069void ObjCProtocolDecl::allocateDefinitionData() {
1070  assert(!Data && "Protocol already has a definition!");
1071  Data = new (getASTContext()) DefinitionData;
1072  Data->Definition = this;
1073}
1074
1075void ObjCProtocolDecl::startDefinition() {
1076  allocateDefinitionData();
1077
1078  // Update all of the declarations with a pointer to the definition.
1079  for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
1080       RD != RDEnd; ++RD)
1081    RD->Data = this->Data;
1082}
1083
1084//===----------------------------------------------------------------------===//
1085// ObjCCategoryDecl
1086//===----------------------------------------------------------------------===//
1087
1088void ObjCCategoryDecl::anchor() { }
1089
1090ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
1091                                           SourceLocation AtLoc,
1092                                           SourceLocation ClassNameLoc,
1093                                           SourceLocation CategoryNameLoc,
1094                                           IdentifierInfo *Id,
1095                                           ObjCInterfaceDecl *IDecl,
1096                                           SourceLocation IvarLBraceLoc,
1097                                           SourceLocation IvarRBraceLoc) {
1098  ObjCCategoryDecl *CatDecl = new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc,
1099                                                       CategoryNameLoc, Id,
1100                                                       IDecl,
1101                                                       IvarLBraceLoc, IvarRBraceLoc);
1102  if (IDecl) {
1103    // Link this category into its class's category list.
1104    CatDecl->NextClassCategory = IDecl->getCategoryList();
1105    if (IDecl->hasDefinition()) {
1106      IDecl->setCategoryList(CatDecl);
1107      if (ASTMutationListener *L = C.getASTMutationListener())
1108        L->AddedObjCCategoryToInterface(CatDecl, IDecl);
1109    }
1110  }
1111
1112  return CatDecl;
1113}
1114
1115ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
1116                                                       unsigned ID) {
1117  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryDecl));
1118  return new (Mem) ObjCCategoryDecl(0, SourceLocation(), SourceLocation(),
1119                                    SourceLocation(), 0, 0);
1120}
1121
1122ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
1123  return getASTContext().getObjCImplementation(
1124                                           const_cast<ObjCCategoryDecl*>(this));
1125}
1126
1127void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
1128  getASTContext().setObjCImplementation(this, ImplD);
1129}
1130
1131
1132//===----------------------------------------------------------------------===//
1133// ObjCCategoryImplDecl
1134//===----------------------------------------------------------------------===//
1135
1136void ObjCCategoryImplDecl::anchor() { }
1137
1138ObjCCategoryImplDecl *
1139ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
1140                             IdentifierInfo *Id,
1141                             ObjCInterfaceDecl *ClassInterface,
1142                             SourceLocation nameLoc,
1143                             SourceLocation atStartLoc,
1144                             SourceLocation CategoryNameLoc) {
1145  if (ClassInterface && ClassInterface->hasDefinition())
1146    ClassInterface = ClassInterface->getDefinition();
1147  return new (C) ObjCCategoryImplDecl(DC, Id, ClassInterface,
1148                                      nameLoc, atStartLoc, CategoryNameLoc);
1149}
1150
1151ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C,
1152                                                               unsigned ID) {
1153  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryImplDecl));
1154  return new (Mem) ObjCCategoryImplDecl(0, 0, 0, SourceLocation(),
1155                                        SourceLocation(), SourceLocation());
1156}
1157
1158ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
1159  // The class interface might be NULL if we are working with invalid code.
1160  if (const ObjCInterfaceDecl *ID = getClassInterface())
1161    return ID->FindCategoryDeclaration(getIdentifier());
1162  return 0;
1163}
1164
1165
1166void ObjCImplDecl::anchor() { }
1167
1168void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
1169  // FIXME: The context should be correct before we get here.
1170  property->setLexicalDeclContext(this);
1171  addDecl(property);
1172}
1173
1174void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
1175  ASTContext &Ctx = getASTContext();
1176
1177  if (ObjCImplementationDecl *ImplD
1178        = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
1179    if (IFace)
1180      Ctx.setObjCImplementation(IFace, ImplD);
1181
1182  } else if (ObjCCategoryImplDecl *ImplD =
1183             dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
1184    if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
1185      Ctx.setObjCImplementation(CD, ImplD);
1186  }
1187
1188  ClassInterface = IFace;
1189}
1190
1191/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
1192/// properties implemented in this category \@implementation block and returns
1193/// the implemented property that uses it.
1194///
1195ObjCPropertyImplDecl *ObjCImplDecl::
1196FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
1197  for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
1198    ObjCPropertyImplDecl *PID = *i;
1199    if (PID->getPropertyIvarDecl() &&
1200        PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
1201      return PID;
1202  }
1203  return 0;
1204}
1205
1206/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
1207/// added to the list of those properties \@synthesized/\@dynamic in this
1208/// category \@implementation block.
1209///
1210ObjCPropertyImplDecl *ObjCImplDecl::
1211FindPropertyImplDecl(IdentifierInfo *Id) const {
1212  for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
1213    ObjCPropertyImplDecl *PID = *i;
1214    if (PID->getPropertyDecl()->getIdentifier() == Id)
1215      return PID;
1216  }
1217  return 0;
1218}
1219
1220raw_ostream &clang::operator<<(raw_ostream &OS,
1221                               const ObjCCategoryImplDecl &CID) {
1222  OS << CID.getName();
1223  return OS;
1224}
1225
1226//===----------------------------------------------------------------------===//
1227// ObjCImplementationDecl
1228//===----------------------------------------------------------------------===//
1229
1230void ObjCImplementationDecl::anchor() { }
1231
1232ObjCImplementationDecl *
1233ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
1234                               ObjCInterfaceDecl *ClassInterface,
1235                               ObjCInterfaceDecl *SuperDecl,
1236                               SourceLocation nameLoc,
1237                               SourceLocation atStartLoc,
1238                               SourceLocation IvarLBraceLoc,
1239                               SourceLocation IvarRBraceLoc) {
1240  if (ClassInterface && ClassInterface->hasDefinition())
1241    ClassInterface = ClassInterface->getDefinition();
1242  return new (C) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
1243                                        nameLoc, atStartLoc,
1244                                        IvarLBraceLoc, IvarRBraceLoc);
1245}
1246
1247ObjCImplementationDecl *
1248ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1249  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCImplementationDecl));
1250  return new (Mem) ObjCImplementationDecl(0, 0, 0, SourceLocation(),
1251                                          SourceLocation());
1252}
1253
1254void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
1255                                             CXXCtorInitializer ** initializers,
1256                                                 unsigned numInitializers) {
1257  if (numInitializers > 0) {
1258    NumIvarInitializers = numInitializers;
1259    CXXCtorInitializer **ivarInitializers =
1260    new (C) CXXCtorInitializer*[NumIvarInitializers];
1261    memcpy(ivarInitializers, initializers,
1262           numInitializers * sizeof(CXXCtorInitializer*));
1263    IvarInitializers = ivarInitializers;
1264  }
1265}
1266
1267raw_ostream &clang::operator<<(raw_ostream &OS,
1268                               const ObjCImplementationDecl &ID) {
1269  OS << ID.getName();
1270  return OS;
1271}
1272
1273//===----------------------------------------------------------------------===//
1274// ObjCCompatibleAliasDecl
1275//===----------------------------------------------------------------------===//
1276
1277void ObjCCompatibleAliasDecl::anchor() { }
1278
1279ObjCCompatibleAliasDecl *
1280ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
1281                                SourceLocation L,
1282                                IdentifierInfo *Id,
1283                                ObjCInterfaceDecl* AliasedClass) {
1284  return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
1285}
1286
1287ObjCCompatibleAliasDecl *
1288ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1289  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCompatibleAliasDecl));
1290  return new (Mem) ObjCCompatibleAliasDecl(0, SourceLocation(), 0, 0);
1291}
1292
1293//===----------------------------------------------------------------------===//
1294// ObjCPropertyDecl
1295//===----------------------------------------------------------------------===//
1296
1297void ObjCPropertyDecl::anchor() { }
1298
1299ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
1300                                           SourceLocation L,
1301                                           IdentifierInfo *Id,
1302                                           SourceLocation AtLoc,
1303                                           SourceLocation LParenLoc,
1304                                           TypeSourceInfo *T,
1305                                           PropertyControl propControl) {
1306  return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
1307}
1308
1309ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
1310                                                       unsigned ID) {
1311  void * Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyDecl));
1312  return new (Mem) ObjCPropertyDecl(0, SourceLocation(), 0, SourceLocation(),
1313                                    SourceLocation(),
1314                                    0);
1315}
1316
1317//===----------------------------------------------------------------------===//
1318// ObjCPropertyImplDecl
1319//===----------------------------------------------------------------------===//
1320
1321ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
1322                                                   DeclContext *DC,
1323                                                   SourceLocation atLoc,
1324                                                   SourceLocation L,
1325                                                   ObjCPropertyDecl *property,
1326                                                   Kind PK,
1327                                                   ObjCIvarDecl *ivar,
1328                                                   SourceLocation ivarLoc) {
1329  return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
1330                                      ivarLoc);
1331}
1332
1333ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
1334                                                               unsigned ID) {
1335  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyImplDecl));
1336  return new (Mem) ObjCPropertyImplDecl(0, SourceLocation(), SourceLocation(),
1337                                        0, Dynamic, 0, SourceLocation());
1338}
1339
1340SourceRange ObjCPropertyImplDecl::getSourceRange() const {
1341  SourceLocation EndLoc = getLocation();
1342  if (IvarLoc.isValid())
1343    EndLoc = IvarLoc;
1344
1345  return SourceRange(AtLoc, EndLoc);
1346}
1347