clang API Documentation

DeclObjC.cpp
Go to the documentation of this file.
00001 //===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the Objective-C related Decl classes.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/AST/DeclObjC.h"
00015 #include "clang/AST/ASTContext.h"
00016 #include "clang/AST/Stmt.h"
00017 #include "clang/AST/ASTMutationListener.h"
00018 #include "llvm/ADT/STLExtras.h"
00019 using namespace clang;
00020 
00021 //===----------------------------------------------------------------------===//
00022 // ObjCListBase
00023 //===----------------------------------------------------------------------===//
00024 
00025 void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
00026   List = 0;
00027   if (Elts == 0) return;  // Setting to an empty list is a noop.
00028 
00029 
00030   List = new (Ctx) void*[Elts];
00031   NumElts = Elts;
00032   memcpy(List, InList, sizeof(void*)*Elts);
00033 }
00034 
00035 void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts, 
00036                            const SourceLocation *Locs, ASTContext &Ctx) {
00037   if (Elts == 0)
00038     return;
00039 
00040   Locations = new (Ctx) SourceLocation[Elts];
00041   memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
00042   set(InList, Elts, Ctx);
00043 }
00044 
00045 //===----------------------------------------------------------------------===//
00046 // ObjCInterfaceDecl
00047 //===----------------------------------------------------------------------===//
00048 
00049 void ObjCContainerDecl::anchor() { }
00050 
00051 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
00052 ///
00053 ObjCIvarDecl *
00054 ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
00055   lookup_const_iterator Ivar, IvarEnd;
00056   for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
00057     if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
00058       return ivar;
00059   }
00060   return 0;
00061 }
00062 
00063 // Get the local instance/class method declared in this interface.
00064 ObjCMethodDecl *
00065 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const {
00066   // Since instance & class methods can have the same name, the loop below
00067   // ensures we get the correct method.
00068   //
00069   // @interface Whatever
00070   // - (int) class_method;
00071   // + (float) class_method;
00072   // @end
00073   //
00074   lookup_const_iterator Meth, MethEnd;
00075   for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
00076     ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
00077     if (MD && MD->isInstanceMethod() == isInstance)
00078       return MD;
00079   }
00080   return 0;
00081 }
00082 
00083 ObjCPropertyDecl *
00084 ObjCPropertyDecl::findPropertyDecl(const DeclContext *DC,
00085                                    IdentifierInfo *propertyID) {
00086 
00087   DeclContext::lookup_const_iterator I, E;
00088   llvm::tie(I, E) = DC->lookup(propertyID);
00089   for ( ; I != E; ++I)
00090     if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
00091       return PD;
00092 
00093   return 0;
00094 }
00095 
00096 /// FindPropertyDeclaration - Finds declaration of the property given its name
00097 /// in 'PropertyId' and returns it. It returns 0, if not found.
00098 ObjCPropertyDecl *
00099 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
00100 
00101   if (ObjCPropertyDecl *PD =
00102         ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
00103     return PD;
00104 
00105   switch (getKind()) {
00106     default:
00107       break;
00108     case Decl::ObjCProtocol: {
00109       const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
00110       for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
00111            E = PID->protocol_end(); I != E; ++I)
00112         if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
00113           return P;
00114       break;
00115     }
00116     case Decl::ObjCInterface: {
00117       const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
00118       // Look through categories.
00119       for (ObjCCategoryDecl *Cat = OID->getCategoryList();
00120            Cat; Cat = Cat->getNextClassCategory())
00121         if (!Cat->IsClassExtension())
00122           if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
00123             return P;
00124 
00125       // Look through protocols.
00126       for (ObjCInterfaceDecl::all_protocol_iterator
00127             I = OID->all_referenced_protocol_begin(),
00128             E = OID->all_referenced_protocol_end(); I != E; ++I)
00129         if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
00130           return P;
00131 
00132       // Finally, check the super class.
00133       if (const ObjCInterfaceDecl *superClass = OID->getSuperClass())
00134         return superClass->FindPropertyDeclaration(PropertyId);
00135       break;
00136     }
00137     case Decl::ObjCCategory: {
00138       const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
00139       // Look through protocols.
00140       if (!OCD->IsClassExtension())
00141         for (ObjCCategoryDecl::protocol_iterator
00142               I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
00143         if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
00144           return P;
00145 
00146       break;
00147     }
00148   }
00149   return 0;
00150 }
00151 
00152 void ObjCInterfaceDecl::anchor() { }
00153 
00154 /// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
00155 /// with name 'PropertyId' in the primary class; including those in protocols
00156 /// (direct or indirect) used by the primary class.
00157 ///
00158 ObjCPropertyDecl *
00159 ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
00160                                             IdentifierInfo *PropertyId) const {
00161   // FIXME: Should make sure no callers ever do this.
00162   if (!hasDefinition())
00163     return 0;
00164   
00165   if (data().ExternallyCompleted)
00166     LoadExternalDefinition();
00167 
00168   if (ObjCPropertyDecl *PD =
00169       ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(this), PropertyId))
00170     return PD;
00171 
00172   // Look through protocols.
00173   for (ObjCInterfaceDecl::all_protocol_iterator
00174         I = all_referenced_protocol_begin(),
00175         E = all_referenced_protocol_end(); I != E; ++I)
00176     if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
00177       return P;
00178 
00179   return 0;
00180 }
00181 
00182 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
00183                               ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
00184                               ASTContext &C)
00185 {
00186   if (data().ExternallyCompleted)
00187     LoadExternalDefinition();
00188 
00189   if (data().AllReferencedProtocols.empty() && 
00190       data().ReferencedProtocols.empty()) {
00191     data().AllReferencedProtocols.set(ExtList, ExtNum, C);
00192     return;
00193   }
00194   
00195   // Check for duplicate protocol in class's protocol list.
00196   // This is O(n*m). But it is extremely rare and number of protocols in
00197   // class or its extension are very few.
00198   SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
00199   for (unsigned i = 0; i < ExtNum; i++) {
00200     bool protocolExists = false;
00201     ObjCProtocolDecl *ProtoInExtension = ExtList[i];
00202     for (all_protocol_iterator
00203           p = all_referenced_protocol_begin(),
00204           e = all_referenced_protocol_end(); p != e; ++p) {
00205       ObjCProtocolDecl *Proto = (*p);
00206       if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
00207         protocolExists = true;
00208         break;
00209       }      
00210     }
00211     // Do we want to warn on a protocol in extension class which
00212     // already exist in the class? Probably not.
00213     if (!protocolExists)
00214       ProtocolRefs.push_back(ProtoInExtension);
00215   }
00216 
00217   if (ProtocolRefs.empty())
00218     return;
00219 
00220   // Merge ProtocolRefs into class's protocol list;
00221   for (all_protocol_iterator p = all_referenced_protocol_begin(), 
00222         e = all_referenced_protocol_end(); p != e; ++p) {
00223     ProtocolRefs.push_back(*p);
00224   }
00225 
00226   data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
00227 }
00228 
00229 void ObjCInterfaceDecl::allocateDefinitionData() {
00230   assert(!hasDefinition() && "ObjC class already has a definition");
00231   Data = new (getASTContext()) DefinitionData();
00232   Data->Definition = this;
00233 
00234   // Make the type point at the definition, now that we have one.
00235   if (TypeForDecl)
00236     cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
00237 }
00238 
00239 void ObjCInterfaceDecl::startDefinition() {
00240   allocateDefinitionData();
00241 
00242   // Update all of the declarations with a pointer to the definition.
00243   for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
00244        RD != RDEnd; ++RD) {
00245     if (*RD != this)
00246       RD->Data = Data;
00247   }
00248 }
00249 
00250 /// getFirstClassExtension - Find first class extension of the given class.
00251 ObjCCategoryDecl* ObjCInterfaceDecl::getFirstClassExtension() const {
00252   for (ObjCCategoryDecl *CDecl = getCategoryList(); CDecl;
00253        CDecl = CDecl->getNextClassCategory())
00254     if (CDecl->IsClassExtension())
00255       return CDecl;
00256   return 0;
00257 }
00258 
00259 /// getNextClassCategory - Find next class extension in list of categories.
00260 const ObjCCategoryDecl* ObjCCategoryDecl::getNextClassExtension() const {
00261   for (const ObjCCategoryDecl *CDecl = getNextClassCategory(); CDecl; 
00262         CDecl = CDecl->getNextClassCategory())
00263     if (CDecl->IsClassExtension())
00264       return CDecl;
00265   return 0;
00266 }
00267 
00268 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
00269                                               ObjCInterfaceDecl *&clsDeclared) {
00270   // FIXME: Should make sure no callers ever do this.
00271   if (!hasDefinition())
00272     return 0;  
00273 
00274   if (data().ExternallyCompleted)
00275     LoadExternalDefinition();
00276 
00277   ObjCInterfaceDecl* ClassDecl = this;
00278   while (ClassDecl != NULL) {
00279     if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
00280       clsDeclared = ClassDecl;
00281       return I;
00282     }
00283     for (const ObjCCategoryDecl *CDecl = ClassDecl->getFirstClassExtension();
00284          CDecl; CDecl = CDecl->getNextClassExtension()) {
00285       if (ObjCIvarDecl *I = CDecl->getIvarDecl(ID)) {
00286         clsDeclared = ClassDecl;
00287         return I;
00288       }
00289     }
00290       
00291     ClassDecl = ClassDecl->getSuperClass();
00292   }
00293   return NULL;
00294 }
00295 
00296 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
00297 /// class whose name is passed as argument. If it is not one of the super classes
00298 /// the it returns NULL.
00299 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
00300                                         const IdentifierInfo*ICName) {
00301   // FIXME: Should make sure no callers ever do this.
00302   if (!hasDefinition())
00303     return 0;
00304 
00305   if (data().ExternallyCompleted)
00306     LoadExternalDefinition();
00307 
00308   ObjCInterfaceDecl* ClassDecl = this;
00309   while (ClassDecl != NULL) {
00310     if (ClassDecl->getIdentifier() == ICName)
00311       return ClassDecl;
00312     ClassDecl = ClassDecl->getSuperClass();
00313   }
00314   return NULL;
00315 }
00316 
00317 /// lookupMethod - This method returns an instance/class method by looking in
00318 /// the class, its categories, and its super classes (using a linear search).
00319 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, 
00320                                      bool isInstance,
00321                                      bool shallowCategoryLookup) const {
00322   // FIXME: Should make sure no callers ever do this.
00323   if (!hasDefinition())
00324     return 0;
00325 
00326   const ObjCInterfaceDecl* ClassDecl = this;
00327   ObjCMethodDecl *MethodDecl = 0;
00328 
00329   if (data().ExternallyCompleted)
00330     LoadExternalDefinition();
00331 
00332   while (ClassDecl != NULL) {
00333     if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
00334       return MethodDecl;
00335 
00336     // Didn't find one yet - look through protocols.
00337     for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
00338                                               E = ClassDecl->protocol_end();
00339            I != E; ++I)
00340       if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
00341         return MethodDecl;
00342     
00343     // Didn't find one yet - now look through categories.
00344     ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
00345     while (CatDecl) {
00346       if ((MethodDecl = CatDecl->getMethod(Sel, isInstance)))
00347         return MethodDecl;
00348 
00349       if (!shallowCategoryLookup) {
00350         // Didn't find one yet - look through protocols.
00351         const ObjCList<ObjCProtocolDecl> &Protocols =
00352           CatDecl->getReferencedProtocols();
00353         for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
00354              E = Protocols.end(); I != E; ++I)
00355           if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
00356             return MethodDecl;
00357       }
00358       CatDecl = CatDecl->getNextClassCategory();
00359     }
00360   
00361     ClassDecl = ClassDecl->getSuperClass();
00362   }
00363   return NULL;
00364 }
00365 
00366 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
00367                                    const Selector &Sel,
00368                                    bool Instance) {
00369   // FIXME: Should make sure no callers ever do this.
00370   if (!hasDefinition())
00371     return 0;
00372 
00373   if (data().ExternallyCompleted)
00374     LoadExternalDefinition();
00375 
00376   ObjCMethodDecl *Method = 0;
00377   if (ObjCImplementationDecl *ImpDecl = getImplementation())
00378     Method = Instance ? ImpDecl->getInstanceMethod(Sel) 
00379                       : ImpDecl->getClassMethod(Sel);
00380   
00381   if (!Method && getSuperClass())
00382     return getSuperClass()->lookupPrivateMethod(Sel, Instance);
00383   return Method;
00384 }
00385 
00386 //===----------------------------------------------------------------------===//
00387 // ObjCMethodDecl
00388 //===----------------------------------------------------------------------===//
00389 
00390 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
00391                                        SourceLocation beginLoc,
00392                                        SourceLocation endLoc,
00393                                        Selector SelInfo, QualType T,
00394                                        TypeSourceInfo *ResultTInfo,
00395                                        DeclContext *contextDecl,
00396                                        bool isInstance,
00397                                        bool isVariadic,
00398                                        bool isSynthesized,
00399                                        bool isImplicitlyDeclared,
00400                                        bool isDefined,
00401                                        ImplementationControl impControl,
00402                                        bool HasRelatedResultType) {
00403   return new (C) ObjCMethodDecl(beginLoc, endLoc,
00404                                 SelInfo, T, ResultTInfo, contextDecl,
00405                                 isInstance,
00406                                 isVariadic, isSynthesized, isImplicitlyDeclared,
00407                                 isDefined,
00408                                 impControl,
00409                                 HasRelatedResultType);
00410 }
00411 
00412 ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
00413   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCMethodDecl));
00414   return new (Mem) ObjCMethodDecl(SourceLocation(), SourceLocation(), 
00415                                   Selector(), QualType(), 0, 0);
00416 }
00417 
00418 void ObjCMethodDecl::setAsRedeclaration(const ObjCMethodDecl *PrevMethod) {
00419   assert(PrevMethod);
00420   getASTContext().setObjCMethodRedeclaration(PrevMethod, this);
00421   IsRedeclaration = true;
00422   PrevMethod->HasRedeclaration = true;
00423 }
00424 
00425 void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
00426                                          ArrayRef<ParmVarDecl*> Params,
00427                                          ArrayRef<SourceLocation> SelLocs) {
00428   ParamsAndSelLocs = 0;
00429   NumParams = Params.size();
00430   if (Params.empty() && SelLocs.empty())
00431     return;
00432 
00433   unsigned Size = sizeof(ParmVarDecl *) * NumParams +
00434                   sizeof(SourceLocation) * SelLocs.size();
00435   ParamsAndSelLocs = C.Allocate(Size);
00436   std::copy(Params.begin(), Params.end(), getParams());
00437   std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs());
00438 }
00439 
00440 void ObjCMethodDecl::getSelectorLocs(
00441                                SmallVectorImpl<SourceLocation> &SelLocs) const {
00442   for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i)
00443     SelLocs.push_back(getSelectorLoc(i));
00444 }
00445 
00446 void ObjCMethodDecl::setMethodParams(ASTContext &C,
00447                                      ArrayRef<ParmVarDecl*> Params,
00448                                      ArrayRef<SourceLocation> SelLocs) {
00449   assert((!SelLocs.empty() || isImplicit()) &&
00450          "No selector locs for non-implicit method");
00451   if (isImplicit())
00452     return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
00453 
00454   SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params, EndLoc);
00455   if (SelLocsKind != SelLoc_NonStandard)
00456     return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>());
00457 
00458   setParamsAndSelLocs(C, Params, SelLocs);
00459 }
00460 
00461 /// \brief A definition will return its interface declaration.
00462 /// An interface declaration will return its definition.
00463 /// Otherwise it will return itself.
00464 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
00465   ASTContext &Ctx = getASTContext();
00466   ObjCMethodDecl *Redecl = 0;
00467   if (HasRedeclaration)
00468     Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
00469   if (Redecl)
00470     return Redecl;
00471 
00472   Decl *CtxD = cast<Decl>(getDeclContext());
00473 
00474   if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
00475     if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
00476       Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
00477 
00478   } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
00479     if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
00480       Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
00481 
00482   } else if (ObjCImplementationDecl *ImplD =
00483                dyn_cast<ObjCImplementationDecl>(CtxD)) {
00484     if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
00485       Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
00486 
00487   } else if (ObjCCategoryImplDecl *CImplD =
00488                dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
00489     if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
00490       Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
00491   }
00492 
00493   if (!Redecl && isRedeclaration()) {
00494     // This is the last redeclaration, go back to the first method.
00495     return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
00496                                                     isInstanceMethod());
00497   }
00498 
00499   return Redecl ? Redecl : this;
00500 }
00501 
00502 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
00503   Decl *CtxD = cast<Decl>(getDeclContext());
00504 
00505   if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) {
00506     if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
00507       if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
00508                                               isInstanceMethod()))
00509         return MD;
00510 
00511   } else if (ObjCCategoryImplDecl *CImplD =
00512                dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
00513     if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
00514       if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
00515                                                isInstanceMethod()))
00516         return MD;
00517   }
00518 
00519   if (isRedeclaration())
00520     return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
00521                                                     isInstanceMethod());
00522 
00523   return this;
00524 }
00525 
00526 ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
00527   ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
00528   if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
00529     return family;
00530 
00531   // Check for an explicit attribute.
00532   if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
00533     // The unfortunate necessity of mapping between enums here is due
00534     // to the attributes framework.
00535     switch (attr->getFamily()) {
00536     case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
00537     case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
00538     case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
00539     case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
00540     case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
00541     case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
00542     }
00543     Family = static_cast<unsigned>(family);
00544     return family;
00545   }
00546 
00547   family = getSelector().getMethodFamily();
00548   switch (family) {
00549   case OMF_None: break;
00550 
00551   // init only has a conventional meaning for an instance method, and
00552   // it has to return an object.
00553   case OMF_init:
00554     if (!isInstanceMethod() || !getResultType()->isObjCObjectPointerType())
00555       family = OMF_None;
00556     break;
00557 
00558   // alloc/copy/new have a conventional meaning for both class and
00559   // instance methods, but they require an object return.
00560   case OMF_alloc:
00561   case OMF_copy:
00562   case OMF_mutableCopy:
00563   case OMF_new:
00564     if (!getResultType()->isObjCObjectPointerType())
00565       family = OMF_None;
00566     break;
00567 
00568   // These selectors have a conventional meaning only for instance methods.
00569   case OMF_dealloc:
00570   case OMF_finalize:
00571   case OMF_retain:
00572   case OMF_release:
00573   case OMF_autorelease:
00574   case OMF_retainCount:
00575   case OMF_self:
00576     if (!isInstanceMethod())
00577       family = OMF_None;
00578     break;
00579       
00580   case OMF_performSelector:
00581     if (!isInstanceMethod() ||
00582         !getResultType()->isObjCIdType())
00583       family = OMF_None;
00584     else {
00585       unsigned noParams = param_size();
00586       if (noParams < 1 || noParams > 3)
00587         family = OMF_None;
00588       else {
00589         ObjCMethodDecl::arg_type_iterator it = arg_type_begin();
00590         QualType ArgT = (*it);
00591         if (!ArgT->isObjCSelType()) {
00592           family = OMF_None;
00593           break;
00594         }
00595         while (--noParams) {
00596           it++;
00597           ArgT = (*it);
00598           if (!ArgT->isObjCIdType()) {
00599             family = OMF_None;
00600             break;
00601           }
00602         }
00603       }
00604     }
00605     break;
00606       
00607   }
00608 
00609   // Cache the result.
00610   Family = static_cast<unsigned>(family);
00611   return family;
00612 }
00613 
00614 void ObjCMethodDecl::createImplicitParams(ASTContext &Context,
00615                                           const ObjCInterfaceDecl *OID) {
00616   QualType selfTy;
00617   if (isInstanceMethod()) {
00618     // There may be no interface context due to error in declaration
00619     // of the interface (which has been reported). Recover gracefully.
00620     if (OID) {
00621       selfTy = Context.getObjCInterfaceType(OID);
00622       selfTy = Context.getObjCObjectPointerType(selfTy);
00623     } else {
00624       selfTy = Context.getObjCIdType();
00625     }
00626   } else // we have a factory method.
00627     selfTy = Context.getObjCClassType();
00628 
00629   bool selfIsPseudoStrong = false;
00630   bool selfIsConsumed = false;
00631   
00632   if (Context.getLangOpts().ObjCAutoRefCount) {
00633     if (isInstanceMethod()) {
00634       selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
00635 
00636       // 'self' is always __strong.  It's actually pseudo-strong except
00637       // in init methods (or methods labeled ns_consumes_self), though.
00638       Qualifiers qs;
00639       qs.setObjCLifetime(Qualifiers::OCL_Strong);
00640       selfTy = Context.getQualifiedType(selfTy, qs);
00641 
00642       // In addition, 'self' is const unless this is an init method.
00643       if (getMethodFamily() != OMF_init && !selfIsConsumed) {
00644         selfTy = selfTy.withConst();
00645         selfIsPseudoStrong = true;
00646       }
00647     }
00648     else {
00649       assert(isClassMethod());
00650       // 'self' is always const in class methods.
00651       selfTy = selfTy.withConst();
00652       selfIsPseudoStrong = true;
00653     }
00654   }
00655 
00656   ImplicitParamDecl *self
00657     = ImplicitParamDecl::Create(Context, this, SourceLocation(),
00658                                 &Context.Idents.get("self"), selfTy);
00659   setSelfDecl(self);
00660 
00661   if (selfIsConsumed)
00662     self->addAttr(new (Context) NSConsumedAttr(SourceLocation(), Context));
00663 
00664   if (selfIsPseudoStrong)
00665     self->setARCPseudoStrong(true);
00666 
00667   setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(),
00668                                        &Context.Idents.get("_cmd"),
00669                                        Context.getObjCSelType()));
00670 }
00671 
00672 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() {
00673   if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext()))
00674     return ID;
00675   if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext()))
00676     return CD->getClassInterface();
00677   if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
00678     return IMD->getClassInterface();
00679 
00680   assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
00681   llvm_unreachable("unknown method context");
00682 }
00683 
00684 //===----------------------------------------------------------------------===//
00685 // ObjCInterfaceDecl
00686 //===----------------------------------------------------------------------===//
00687 
00688 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(const ASTContext &C,
00689                                              DeclContext *DC,
00690                                              SourceLocation atLoc,
00691                                              IdentifierInfo *Id,
00692                                              ObjCInterfaceDecl *PrevDecl,
00693                                              SourceLocation ClassLoc,
00694                                              bool isInternal){
00695   ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, 
00696                                                         PrevDecl, isInternal);
00697   C.getObjCInterfaceType(Result, PrevDecl);
00698   return Result;
00699 }
00700 
00701 ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C, 
00702                                                          unsigned ID) {
00703   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCInterfaceDecl));
00704   return new (Mem) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(),
00705                                      0, false);
00706 }
00707 
00708 ObjCInterfaceDecl::
00709 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
00710                   SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
00711                   bool isInternal)
00712   : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
00713     TypeForDecl(0), Data()
00714 {
00715   setPreviousDeclaration(PrevDecl);
00716   
00717   // Copy the 'data' pointer over.
00718   if (PrevDecl)
00719     Data = PrevDecl->Data;
00720   
00721   setImplicit(isInternal);
00722 }
00723 
00724 void ObjCInterfaceDecl::LoadExternalDefinition() const {
00725   assert(data().ExternallyCompleted && "Class is not externally completed");
00726   data().ExternallyCompleted = false;
00727   getASTContext().getExternalSource()->CompleteType(
00728                                         const_cast<ObjCInterfaceDecl *>(this));
00729 }
00730 
00731 void ObjCInterfaceDecl::setExternallyCompleted() {
00732   assert(getASTContext().getExternalSource() && 
00733          "Class can't be externally completed without an external source");
00734   assert(hasDefinition() && 
00735          "Forward declarations can't be externally completed");
00736   data().ExternallyCompleted = true;
00737 }
00738 
00739 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
00740   if (const ObjCInterfaceDecl *Def = getDefinition()) {
00741     if (data().ExternallyCompleted)
00742       LoadExternalDefinition();
00743     
00744     return getASTContext().getObjCImplementation(
00745              const_cast<ObjCInterfaceDecl*>(Def));
00746   }
00747   
00748   // FIXME: Should make sure no callers ever do this.
00749   return 0;
00750 }
00751 
00752 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
00753   getASTContext().setObjCImplementation(getDefinition(), ImplD);
00754 }
00755 
00756 /// all_declared_ivar_begin - return first ivar declared in this class,
00757 /// its extensions and its implementation. Lazily build the list on first
00758 /// access.
00759 ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
00760   // FIXME: Should make sure no callers ever do this.
00761   if (!hasDefinition())
00762     return 0;
00763   
00764   if (data().IvarList)
00765     return data().IvarList;
00766   
00767   ObjCIvarDecl *curIvar = 0;
00768   if (!ivar_empty()) {
00769     ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
00770     data().IvarList = &*I; ++I;
00771     for (curIvar = data().IvarList; I != E; curIvar = &*I, ++I)
00772       curIvar->setNextIvar(&*I);
00773   }
00774   
00775   for (const ObjCCategoryDecl *CDecl = getFirstClassExtension(); CDecl;
00776        CDecl = CDecl->getNextClassExtension()) {
00777     if (!CDecl->ivar_empty()) {
00778       ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
00779                                           E = CDecl->ivar_end();
00780       if (!data().IvarList) {
00781         data().IvarList = &*I; ++I;
00782         curIvar = data().IvarList;
00783       }
00784       for ( ;I != E; curIvar = &*I, ++I)
00785         curIvar->setNextIvar(&*I);
00786     }
00787   }
00788   
00789   if (ObjCImplementationDecl *ImplDecl = getImplementation()) {
00790     if (!ImplDecl->ivar_empty()) {
00791       ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
00792                                             E = ImplDecl->ivar_end();
00793       if (!data().IvarList) {
00794         data().IvarList = &*I; ++I;
00795         curIvar = data().IvarList;
00796       }
00797       for ( ;I != E; curIvar = &*I, ++I)
00798         curIvar->setNextIvar(&*I);
00799     }
00800   }
00801   return data().IvarList;
00802 }
00803 
00804 /// FindCategoryDeclaration - Finds category declaration in the list of
00805 /// categories for this class and returns it. Name of the category is passed
00806 /// in 'CategoryId'. If category not found, return 0;
00807 ///
00808 ObjCCategoryDecl *
00809 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
00810   // FIXME: Should make sure no callers ever do this.
00811   if (!hasDefinition())
00812     return 0;
00813 
00814   if (data().ExternallyCompleted)
00815     LoadExternalDefinition();
00816 
00817   for (ObjCCategoryDecl *Category = getCategoryList();
00818        Category; Category = Category->getNextClassCategory())
00819     if (Category->getIdentifier() == CategoryId)
00820       return Category;
00821   return 0;
00822 }
00823 
00824 ObjCMethodDecl *
00825 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
00826   for (ObjCCategoryDecl *Category = getCategoryList();
00827        Category; Category = Category->getNextClassCategory())
00828     if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
00829       if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
00830         return MD;
00831   return 0;
00832 }
00833 
00834 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
00835   for (ObjCCategoryDecl *Category = getCategoryList();
00836        Category; Category = Category->getNextClassCategory())
00837     if (ObjCCategoryImplDecl *Impl = Category->getImplementation())
00838       if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
00839         return MD;
00840   return 0;
00841 }
00842 
00843 /// ClassImplementsProtocol - Checks that 'lProto' protocol
00844 /// has been implemented in IDecl class, its super class or categories (if
00845 /// lookupCategory is true).
00846 bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
00847                                     bool lookupCategory,
00848                                     bool RHSIsQualifiedID) {
00849   if (!hasDefinition())
00850     return false;
00851   
00852   ObjCInterfaceDecl *IDecl = this;
00853   // 1st, look up the class.
00854   for (ObjCInterfaceDecl::protocol_iterator
00855         PI = IDecl->protocol_begin(), E = IDecl->protocol_end(); PI != E; ++PI){
00856     if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
00857       return true;
00858     // This is dubious and is added to be compatible with gcc.  In gcc, it is
00859     // also allowed assigning a protocol-qualified 'id' type to a LHS object
00860     // when protocol in qualified LHS is in list of protocols in the rhs 'id'
00861     // object. This IMO, should be a bug.
00862     // FIXME: Treat this as an extension, and flag this as an error when GCC
00863     // extensions are not enabled.
00864     if (RHSIsQualifiedID &&
00865         getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
00866       return true;
00867   }
00868 
00869   // 2nd, look up the category.
00870   if (lookupCategory)
00871     for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
00872          CDecl = CDecl->getNextClassCategory()) {
00873       for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
00874            E = CDecl->protocol_end(); PI != E; ++PI)
00875         if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
00876           return true;
00877     }
00878 
00879   // 3rd, look up the super class(s)
00880   if (IDecl->getSuperClass())
00881     return
00882   IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory,
00883                                                   RHSIsQualifiedID);
00884 
00885   return false;
00886 }
00887 
00888 //===----------------------------------------------------------------------===//
00889 // ObjCIvarDecl
00890 //===----------------------------------------------------------------------===//
00891 
00892 void ObjCIvarDecl::anchor() { }
00893 
00894 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
00895                                    SourceLocation StartLoc,
00896                                    SourceLocation IdLoc, IdentifierInfo *Id,
00897                                    QualType T, TypeSourceInfo *TInfo,
00898                                    AccessControl ac, Expr *BW,
00899                                    bool synthesized) {
00900   if (DC) {
00901     // Ivar's can only appear in interfaces, implementations (via synthesized
00902     // properties), and class extensions (via direct declaration, or synthesized
00903     // properties).
00904     //
00905     // FIXME: This should really be asserting this:
00906     //   (isa<ObjCCategoryDecl>(DC) &&
00907     //    cast<ObjCCategoryDecl>(DC)->IsClassExtension()))
00908     // but unfortunately we sometimes place ivars into non-class extension
00909     // categories on error. This breaks an AST invariant, and should not be
00910     // fixed.
00911     assert((isa<ObjCInterfaceDecl>(DC) || isa<ObjCImplementationDecl>(DC) ||
00912             isa<ObjCCategoryDecl>(DC)) &&
00913            "Invalid ivar decl context!");
00914     // Once a new ivar is created in any of class/class-extension/implementation
00915     // decl contexts, the previously built IvarList must be rebuilt.
00916     ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(DC);
00917     if (!ID) {
00918       if (ObjCImplementationDecl *IM = dyn_cast<ObjCImplementationDecl>(DC)) {
00919         ID = IM->getClassInterface();
00920         if (BW)
00921           IM->setHasSynthBitfield(true);
00922       } else {
00923         ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
00924         ID = CD->getClassInterface();
00925         if (BW)
00926           CD->setHasSynthBitfield(true);
00927       }
00928     }
00929     ID->setIvarList(0);
00930   }
00931 
00932   return new (C) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo,
00933                               ac, BW, synthesized);
00934 }
00935 
00936 ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
00937   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCIvarDecl));
00938   return new (Mem) ObjCIvarDecl(0, SourceLocation(), SourceLocation(), 0,
00939                                 QualType(), 0, ObjCIvarDecl::None, 0, false);
00940 }
00941 
00942 const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
00943   const ObjCContainerDecl *DC = cast<ObjCContainerDecl>(getDeclContext());
00944 
00945   switch (DC->getKind()) {
00946   default:
00947   case ObjCCategoryImpl:
00948   case ObjCProtocol:
00949     llvm_unreachable("invalid ivar container!");
00950 
00951     // Ivars can only appear in class extension categories.
00952   case ObjCCategory: {
00953     const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(DC);
00954     assert(CD->IsClassExtension() && "invalid container for ivar!");
00955     return CD->getClassInterface();
00956   }
00957 
00958   case ObjCImplementation:
00959     return cast<ObjCImplementationDecl>(DC)->getClassInterface();
00960 
00961   case ObjCInterface:
00962     return cast<ObjCInterfaceDecl>(DC);
00963   }
00964 }
00965 
00966 //===----------------------------------------------------------------------===//
00967 // ObjCAtDefsFieldDecl
00968 //===----------------------------------------------------------------------===//
00969 
00970 void ObjCAtDefsFieldDecl::anchor() { }
00971 
00972 ObjCAtDefsFieldDecl
00973 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
00974                              SourceLocation StartLoc,  SourceLocation IdLoc,
00975                              IdentifierInfo *Id, QualType T, Expr *BW) {
00976   return new (C) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
00977 }
00978 
00979 ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, 
00980                                                              unsigned ID) {
00981   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCAtDefsFieldDecl));
00982   return new (Mem) ObjCAtDefsFieldDecl(0, SourceLocation(), SourceLocation(),
00983                                        0, QualType(), 0);
00984 }
00985 
00986 //===----------------------------------------------------------------------===//
00987 // ObjCProtocolDecl
00988 //===----------------------------------------------------------------------===//
00989 
00990 void ObjCProtocolDecl::anchor() { }
00991 
00992 ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
00993                                    SourceLocation nameLoc, 
00994                                    SourceLocation atStartLoc,
00995                                    ObjCProtocolDecl *PrevDecl)
00996   : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data()
00997 {
00998   setPreviousDeclaration(PrevDecl);
00999   if (PrevDecl)
01000     Data = PrevDecl->Data;
01001 }
01002 
01003 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC,
01004                                            IdentifierInfo *Id,
01005                                            SourceLocation nameLoc,
01006                                            SourceLocation atStartLoc,
01007                                            ObjCProtocolDecl *PrevDecl) {
01008   ObjCProtocolDecl *Result 
01009     = new (C) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl);
01010   
01011   return Result;
01012 }
01013 
01014 ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, 
01015                                                        unsigned ID) {
01016   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCProtocolDecl));
01017   return new (Mem) ObjCProtocolDecl(0, 0, SourceLocation(), SourceLocation(),
01018                                     0);
01019 }
01020 
01021 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
01022   ObjCProtocolDecl *PDecl = this;
01023 
01024   if (Name == getIdentifier())
01025     return PDecl;
01026 
01027   for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
01028     if ((PDecl = (*I)->lookupProtocolNamed(Name)))
01029       return PDecl;
01030 
01031   return NULL;
01032 }
01033 
01034 // lookupMethod - Lookup a instance/class method in the protocol and protocols
01035 // it inherited.
01036 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
01037                                                bool isInstance) const {
01038   ObjCMethodDecl *MethodDecl = NULL;
01039 
01040   if ((MethodDecl = getMethod(Sel, isInstance)))
01041     return MethodDecl;
01042 
01043   for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
01044     if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
01045       return MethodDecl;
01046   return NULL;
01047 }
01048 
01049 void ObjCProtocolDecl::allocateDefinitionData() {
01050   assert(!Data && "Protocol already has a definition!");
01051   Data = new (getASTContext()) DefinitionData;
01052   Data->Definition = this;
01053 }
01054 
01055 void ObjCProtocolDecl::startDefinition() {
01056   allocateDefinitionData();
01057   
01058   // Update all of the declarations with a pointer to the definition.
01059   for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
01060        RD != RDEnd; ++RD)
01061     RD->Data = this->Data;
01062 }
01063 
01064 //===----------------------------------------------------------------------===//
01065 // ObjCCategoryDecl
01066 //===----------------------------------------------------------------------===//
01067 
01068 void ObjCCategoryDecl::anchor() { }
01069 
01070 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
01071                                            SourceLocation AtLoc, 
01072                                            SourceLocation ClassNameLoc,
01073                                            SourceLocation CategoryNameLoc,
01074                                            IdentifierInfo *Id,
01075                                            ObjCInterfaceDecl *IDecl,
01076                                            SourceLocation IvarLBraceLoc,
01077                                            SourceLocation IvarRBraceLoc) {
01078   ObjCCategoryDecl *CatDecl = new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc,
01079                                                        CategoryNameLoc, Id,
01080                                                        IDecl,
01081                                                        IvarLBraceLoc, IvarRBraceLoc);
01082   if (IDecl) {
01083     // Link this category into its class's category list.
01084     CatDecl->NextClassCategory = IDecl->getCategoryList();
01085     if (IDecl->hasDefinition()) {
01086       IDecl->setCategoryList(CatDecl);
01087       if (ASTMutationListener *L = C.getASTMutationListener())
01088         L->AddedObjCCategoryToInterface(CatDecl, IDecl);
01089     }
01090   }
01091 
01092   return CatDecl;
01093 }
01094 
01095 ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, 
01096                                                        unsigned ID) {
01097   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryDecl));
01098   return new (Mem) ObjCCategoryDecl(0, SourceLocation(), SourceLocation(),
01099                                     SourceLocation(), 0, 0);
01100 }
01101 
01102 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
01103   return getASTContext().getObjCImplementation(
01104                                            const_cast<ObjCCategoryDecl*>(this));
01105 }
01106 
01107 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) {
01108   getASTContext().setObjCImplementation(this, ImplD);
01109 }
01110 
01111 
01112 //===----------------------------------------------------------------------===//
01113 // ObjCCategoryImplDecl
01114 //===----------------------------------------------------------------------===//
01115 
01116 void ObjCCategoryImplDecl::anchor() { }
01117 
01118 ObjCCategoryImplDecl *
01119 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
01120                              IdentifierInfo *Id,
01121                              ObjCInterfaceDecl *ClassInterface,
01122                              SourceLocation nameLoc,
01123                              SourceLocation atStartLoc,
01124                              SourceLocation CategoryNameLoc) {
01125   if (ClassInterface && ClassInterface->hasDefinition())
01126     ClassInterface = ClassInterface->getDefinition();
01127   return new (C) ObjCCategoryImplDecl(DC, Id, ClassInterface,
01128                                       nameLoc, atStartLoc, CategoryNameLoc);
01129 }
01130 
01131 ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, 
01132                                                                unsigned ID) {
01133   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryImplDecl));
01134   return new (Mem) ObjCCategoryImplDecl(0, 0, 0, SourceLocation(), 
01135                                         SourceLocation(), SourceLocation());
01136 }
01137 
01138 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
01139   // The class interface might be NULL if we are working with invalid code.
01140   if (const ObjCInterfaceDecl *ID = getClassInterface())
01141     return ID->FindCategoryDeclaration(getIdentifier());
01142   return 0;
01143 }
01144 
01145 
01146 void ObjCImplDecl::anchor() { }
01147 
01148 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
01149   // FIXME: The context should be correct before we get here.
01150   property->setLexicalDeclContext(this);
01151   addDecl(property);
01152 }
01153 
01154 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
01155   ASTContext &Ctx = getASTContext();
01156 
01157   if (ObjCImplementationDecl *ImplD
01158         = dyn_cast_or_null<ObjCImplementationDecl>(this)) {
01159     if (IFace)
01160       Ctx.setObjCImplementation(IFace, ImplD);
01161 
01162   } else if (ObjCCategoryImplDecl *ImplD =
01163              dyn_cast_or_null<ObjCCategoryImplDecl>(this)) {
01164     if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier()))
01165       Ctx.setObjCImplementation(CD, ImplD);
01166   }
01167 
01168   ClassInterface = IFace;
01169 }
01170 
01171 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
01172 /// properties implemented in this category @implementation block and returns
01173 /// the implemented property that uses it.
01174 ///
01175 ObjCPropertyImplDecl *ObjCImplDecl::
01176 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
01177   for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
01178     ObjCPropertyImplDecl *PID = &*i;
01179     if (PID->getPropertyIvarDecl() &&
01180         PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
01181       return PID;
01182   }
01183   return 0;
01184 }
01185 
01186 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
01187 /// added to the list of those properties @synthesized/@dynamic in this
01188 /// category @implementation block.
01189 ///
01190 ObjCPropertyImplDecl *ObjCImplDecl::
01191 FindPropertyImplDecl(IdentifierInfo *Id) const {
01192   for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
01193     ObjCPropertyImplDecl *PID = &*i;
01194     if (PID->getPropertyDecl()->getIdentifier() == Id)
01195       return PID;
01196   }
01197   return 0;
01198 }
01199 
01200 raw_ostream &clang::operator<<(raw_ostream &OS,
01201                                const ObjCCategoryImplDecl &CID) {
01202   OS << CID.getName();
01203   return OS;
01204 }
01205 
01206 //===----------------------------------------------------------------------===//
01207 // ObjCImplementationDecl
01208 //===----------------------------------------------------------------------===//
01209 
01210 void ObjCImplementationDecl::anchor() { }
01211 
01212 ObjCImplementationDecl *
01213 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
01214                                ObjCInterfaceDecl *ClassInterface,
01215                                ObjCInterfaceDecl *SuperDecl,
01216                                SourceLocation nameLoc,
01217                                SourceLocation atStartLoc,
01218                                SourceLocation IvarLBraceLoc,
01219                                SourceLocation IvarRBraceLoc) {
01220   if (ClassInterface && ClassInterface->hasDefinition())
01221     ClassInterface = ClassInterface->getDefinition();
01222   return new (C) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
01223                                         nameLoc, atStartLoc,
01224                                         IvarLBraceLoc, IvarRBraceLoc);
01225 }
01226 
01227 ObjCImplementationDecl *
01228 ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
01229   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCImplementationDecl));
01230   return new (Mem) ObjCImplementationDecl(0, 0, 0, SourceLocation(), 
01231                                           SourceLocation());
01232 }
01233 
01234 void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
01235                                              CXXCtorInitializer ** initializers,
01236                                                  unsigned numInitializers) {
01237   if (numInitializers > 0) {
01238     NumIvarInitializers = numInitializers;
01239     CXXCtorInitializer **ivarInitializers =
01240     new (C) CXXCtorInitializer*[NumIvarInitializers];
01241     memcpy(ivarInitializers, initializers,
01242            numInitializers * sizeof(CXXCtorInitializer*));
01243     IvarInitializers = ivarInitializers;
01244   }
01245 }
01246 
01247 raw_ostream &clang::operator<<(raw_ostream &OS,
01248                                const ObjCImplementationDecl &ID) {
01249   OS << ID.getName();
01250   return OS;
01251 }
01252 
01253 //===----------------------------------------------------------------------===//
01254 // ObjCCompatibleAliasDecl
01255 //===----------------------------------------------------------------------===//
01256 
01257 void ObjCCompatibleAliasDecl::anchor() { }
01258 
01259 ObjCCompatibleAliasDecl *
01260 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
01261                                 SourceLocation L,
01262                                 IdentifierInfo *Id,
01263                                 ObjCInterfaceDecl* AliasedClass) {
01264   return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
01265 }
01266 
01267 ObjCCompatibleAliasDecl *
01268 ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
01269   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCompatibleAliasDecl));
01270   return new (Mem) ObjCCompatibleAliasDecl(0, SourceLocation(), 0, 0);
01271 }
01272 
01273 //===----------------------------------------------------------------------===//
01274 // ObjCPropertyDecl
01275 //===----------------------------------------------------------------------===//
01276 
01277 void ObjCPropertyDecl::anchor() { }
01278 
01279 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
01280                                            SourceLocation L,
01281                                            IdentifierInfo *Id,
01282                                            SourceLocation AtLoc,
01283                                            SourceLocation LParenLoc,
01284                                            TypeSourceInfo *T,
01285                                            PropertyControl propControl) {
01286   return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
01287 }
01288 
01289 ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, 
01290                                                        unsigned ID) {
01291   void * Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyDecl));
01292   return new (Mem) ObjCPropertyDecl(0, SourceLocation(), 0, SourceLocation(),
01293                                     SourceLocation(),
01294                                     0);
01295 }
01296 
01297 //===----------------------------------------------------------------------===//
01298 // ObjCPropertyImplDecl
01299 //===----------------------------------------------------------------------===//
01300 
01301 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C,
01302                                                    DeclContext *DC,
01303                                                    SourceLocation atLoc,
01304                                                    SourceLocation L,
01305                                                    ObjCPropertyDecl *property,
01306                                                    Kind PK,
01307                                                    ObjCIvarDecl *ivar,
01308                                                    SourceLocation ivarLoc) {
01309   return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
01310                                       ivarLoc);
01311 }
01312 
01313 ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, 
01314                                                                unsigned ID) {
01315   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyImplDecl));
01316   return new (Mem) ObjCPropertyImplDecl(0, SourceLocation(), SourceLocation(),
01317                                         0, Dynamic, 0, SourceLocation());
01318 }
01319 
01320 SourceRange ObjCPropertyImplDecl::getSourceRange() const {
01321   SourceLocation EndLoc = getLocation();
01322   if (IvarLoc.isValid())
01323     EndLoc = IvarLoc;
01324 
01325   return SourceRange(AtLoc, EndLoc);
01326 }