DeclObjC.cpp revision a66793ee8d2589ead81739d9b8a968650db3d452
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" 17using namespace clang; 18 19//===----------------------------------------------------------------------===// 20// ObjC Decl Allocation/Deallocation Method Implementations 21//===----------------------------------------------------------------------===// 22 23ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, 24 SourceLocation beginLoc, 25 SourceLocation endLoc, 26 Selector SelInfo, QualType T, 27 DeclContext *contextDecl, 28 bool isInstance, 29 bool isVariadic, 30 bool isSynthesized, 31 ImplementationControl impControl) { 32 void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>(); 33 return new (Mem) ObjCMethodDecl(beginLoc, endLoc, 34 SelInfo, T, contextDecl, 35 isInstance, 36 isVariadic, isSynthesized, impControl); 37} 38 39ObjCMethodDecl::~ObjCMethodDecl() { 40 delete [] ParamInfo; 41} 42 43void ObjCMethodDecl::Destroy(ASTContext& C) { 44 if (Body) Body->Destroy(C); 45 if (SelfDecl) SelfDecl->Destroy(C); 46 47 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 48 if (*I) (*I)->Destroy(C); 49 50 Decl::Destroy(C); 51} 52 53ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, 54 DeclContext *DC, 55 SourceLocation atLoc, 56 IdentifierInfo *Id, 57 SourceLocation ClassLoc, 58 bool ForwardDecl, bool isInternal){ 59 void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>(); 60 return new (Mem) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl, 61 isInternal); 62} 63 64ObjCContainerDecl::~ObjCContainerDecl() { 65 delete [] PropertyDecl; 66} 67 68ObjCInterfaceDecl::~ObjCInterfaceDecl() { 69 delete [] Ivars; 70 // FIXME: CategoryList? 71} 72 73void ObjCInterfaceDecl::Destroy(ASTContext& C) { 74 for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I) 75 if (*I) (*I)->Destroy(C); 76 77 for (method_iterator I=meth_begin(), E=meth_end(); I!=E; ++I) 78 if (*I) const_cast<ObjCMethodDecl*>((*I))->Destroy(C); 79 80 // FIXME: Because there is no clear ownership 81 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they 82 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit. 83 84 Decl::Destroy(C); 85} 86 87 88ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L, 89 IdentifierInfo *Id, QualType T, 90 AccessControl ac, Expr *BW) { 91 void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>(); 92 return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW); 93} 94 95 96ObjCAtDefsFieldDecl 97*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 98 IdentifierInfo *Id, QualType T, Expr *BW) { 99 void *Mem = C.getAllocator().Allocate<ObjCAtDefsFieldDecl>(); 100 return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW); 101} 102 103void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) { 104 this->~ObjCAtDefsFieldDecl(); 105 C.getAllocator().Deallocate((void *)this); 106} 107 108ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, 109 SourceLocation L, 110 IdentifierInfo *Id) { 111 void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>(); 112 return new (Mem) ObjCProtocolDecl(DC, L, Id); 113} 114 115ObjCProtocolDecl::~ObjCProtocolDecl() { 116 delete [] PropertyDecl; 117} 118 119void ObjCProtocolDecl::Destroy(ASTContext& C) { 120 121 // Referenced Protocols are not owned, so don't Destroy them. 122 123 for (method_iterator I=meth_begin(), E=meth_end(); I!=E; ++I) 124 if (*I) const_cast<ObjCMethodDecl*>((*I))->Destroy(C); 125 126 // FIXME: Because there is no clear ownership 127 // role between ObjCProtocolDecls and the ObjCPropertyDecls that they 128 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit. 129 130 Decl::Destroy(C); 131} 132 133 134ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC, 135 SourceLocation L, 136 ObjCInterfaceDecl **Elts, unsigned nElts) { 137 void *Mem = C.getAllocator().Allocate<ObjCClassDecl>(); 138 return new (Mem) ObjCClassDecl(DC, L, Elts, nElts); 139} 140 141ObjCClassDecl::~ObjCClassDecl() { 142 delete [] ForwardDecls; 143} 144 145void ObjCClassDecl::Destroy(ASTContext& C) { 146 147 // FIXME: There is no clear ownership policy now for referenced 148 // ObjCInterfaceDecls. Some of them can be forward declarations that 149 // are never later defined (in which case the ObjCClassDecl owns them) 150 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally 151 // we should have separate objects for forward declarations and definitions, 152 // obviating this problem. Because of this situation, referenced 153 // ObjCInterfaceDecls are destroyed in ~TranslationUnit. 154 155 Decl::Destroy(C); 156} 157 158ObjCForwardProtocolDecl * 159ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC, 160 SourceLocation L, 161 ObjCProtocolDecl **Elts, unsigned NumElts) { 162 void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>(); 163 return new (Mem) ObjCForwardProtocolDecl(DC, L, Elts, NumElts); 164} 165 166ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() { 167 delete [] ReferencedProtocols; 168} 169 170ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, 171 SourceLocation L, 172 IdentifierInfo *Id) { 173 void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>(); 174 return new (Mem) ObjCCategoryDecl(DC, L, Id); 175} 176 177ObjCCategoryImplDecl * 178ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC, 179 SourceLocation L,IdentifierInfo *Id, 180 ObjCInterfaceDecl *ClassInterface) { 181 void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>(); 182 return new (Mem) ObjCCategoryImplDecl(DC, L, Id, ClassInterface); 183} 184 185ObjCImplementationDecl * 186ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, 187 SourceLocation L, 188 IdentifierInfo *Id, 189 ObjCInterfaceDecl *ClassInterface, 190 ObjCInterfaceDecl *SuperDecl) { 191 void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>(); 192 return new (Mem) ObjCImplementationDecl(DC, L, Id, ClassInterface, SuperDecl); 193} 194 195ObjCCompatibleAliasDecl * 196ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, 197 SourceLocation L, 198 IdentifierInfo *Id, 199 ObjCInterfaceDecl* AliasedClass) { 200 void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>(); 201 return new (Mem) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass); 202} 203 204ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, 205 SourceLocation L, 206 IdentifierInfo *Id, 207 QualType T, 208 PropertyControl propControl) { 209 void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>(); 210 return new (Mem) ObjCPropertyDecl(DC, L, Id, T); 211} 212 213//===----------------------------------------------------------------------===// 214// Objective-C Decl Implementation 215//===----------------------------------------------------------------------===// 216 217void ObjCMethodDecl::createImplicitParams(ASTContext &Context, 218 const ObjCInterfaceDecl *OID) { 219 QualType selfTy; 220 if (isInstanceMethod()) { 221 // There may be no interface context due to error in declaration 222 // of the interface (which has been reported). Recover gracefully. 223 if (OID) { 224 selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID)); 225 selfTy = Context.getPointerType(selfTy); 226 } else { 227 selfTy = Context.getObjCIdType(); 228 } 229 } else // we have a factory method. 230 selfTy = Context.getObjCClassType(); 231 232 SelfDecl = ImplicitParamDecl::Create(Context, this, 233 SourceLocation(), 234 &Context.Idents.get("self"), 235 selfTy, 0); 236 237 CmdDecl = ImplicitParamDecl::Create(Context, this, 238 SourceLocation(), 239 &Context.Idents.get("_cmd"), 240 Context.getObjCSelType(), 0); 241} 242 243void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo, 244 unsigned NumParams) { 245 assert(ParamInfo == 0 && "Already has param info!"); 246 247 // Zero params -> null pointer. 248 if (NumParams) { 249 ParamInfo = new ParmVarDecl*[NumParams]; 250 memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); 251 NumMethodParams = NumParams; 252 } 253} 254 255/// isPropertyReadonly - Return true if property is readonly, by searching 256/// for the property in the class and in its categories. 257/// 258bool ObjCInterfaceDecl::isPropertyReadonly(ObjCPropertyDecl *PDecl) const 259{ 260 if (!PDecl->isReadOnly()) 261 return false; 262 263 // Main class has the property as 'readonly'. Must search 264 // through the category list to see if the property's 265 // attribute has been over-ridden to 'readwrite'. 266 for (ObjCCategoryDecl *Category = getCategoryList(); 267 Category; Category = Category->getNextClassCategory()) { 268 ObjCPropertyDecl *P = 269 Category->FindPropertyDeclaration(PDecl->getIdentifier()); 270 if (P && !P->isReadOnly()) 271 return false; 272 } 273 274 return true; 275} 276 277/// FindCategoryDeclaration - Finds category declaration in the list of 278/// categories for this class and returns it. Name of the category is passed 279/// in 'CategoryId'. If category not found, return 0; 280/// 281ObjCCategoryDecl * 282 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const { 283 for (ObjCCategoryDecl *Category = getCategoryList(); 284 Category; Category = Category->getNextClassCategory()) 285 if (Category->getIdentifier() == CategoryId) 286 return Category; 287 return 0; 288} 289 290/// FindIvarDeclaration - Find an Ivar declaration in this class given its 291/// name in 'IvarId'. On failure to find, return 0; 292/// 293ObjCIvarDecl * 294 ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const { 295 for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(), 296 IVE = ivar_end(); IVI != IVE; ++IVI) { 297 ObjCIvarDecl* Ivar = (*IVI); 298 if (Ivar->getIdentifier() == IvarId) 299 return Ivar; 300 } 301 if (getSuperClass()) 302 return getSuperClass()->FindIvarDeclaration(IvarId); 303 return 0; 304} 305 306/// ObjCAddInstanceVariablesToClass - Inserts instance variables 307/// into ObjCInterfaceDecl's fields. 308/// 309void ObjCInterfaceDecl::addInstanceVariablesToClass(ObjCIvarDecl **ivars, 310 unsigned numIvars, 311 SourceLocation RBrac) { 312 NumIvars = numIvars; 313 if (numIvars) { 314 Ivars = new ObjCIvarDecl*[numIvars]; 315 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*)); 316 } 317 setLocEnd(RBrac); 318} 319 320/// lookupFieldDeclForIvar - looks up a field decl' in the laid out 321/// storage which matches this 'ivar'. 322/// 323FieldDecl *ObjCInterfaceDecl::lookupFieldDeclForIvar(ASTContext &Context, 324 const ObjCIvarDecl *ivar) { 325 const RecordDecl *RecordForDecl = Context.addRecordToClass(this); 326 assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class"); 327 DeclarationName Member = ivar->getDeclName(); 328 DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl)) 329 ->lookup(Member); 330 assert((Lookup.first != Lookup.second) && "field decl not found"); 331 FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first); 332 assert(MemberDecl && "field decl not found"); 333 return MemberDecl; 334} 335 336/// ObjCAddInstanceVariablesToClassImpl - Checks for correctness of Instance 337/// Variables (Ivars) relative to what declared in @implementation;s class. 338/// Ivars into ObjCImplementationDecl's fields. 339/// 340void ObjCImplementationDecl::ObjCAddInstanceVariablesToClassImpl( 341 ObjCIvarDecl **ivars, unsigned numIvars) { 342 NumIvars = numIvars; 343 if (numIvars) { 344 Ivars = new ObjCIvarDecl*[numIvars]; 345 memcpy(Ivars, ivars, numIvars*sizeof(ObjCIvarDecl*)); 346 } 347} 348 349// Get the local instance method declared in this interface. 350// FIXME: handle overloading, instance & class methods can have the same name. 351ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const { 352 lookup_const_result MethodResult = lookup(Sel); 353 if (MethodResult.first) 354 return const_cast<ObjCMethodDecl*>( 355 dyn_cast<ObjCMethodDecl>(*MethodResult.first)); 356 return 0; 357} 358 359// Get the local class method declared in this interface. 360ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const { 361 lookup_const_result MethodResult = lookup(Sel); 362 if (MethodResult.first) 363 return const_cast<ObjCMethodDecl*>( 364 dyn_cast<ObjCMethodDecl>(*MethodResult.first)); 365 return 0; 366} 367 368unsigned ObjCContainerDecl::getNumInstanceMethods() const { 369 unsigned sum = 0; 370 for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I) 371 sum++; 372 return sum; 373} 374unsigned ObjCContainerDecl::getNumClassMethods() const { 375 unsigned sum = 0; 376 for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I) 377 sum++; 378 return sum; 379} 380 381/// addProperties - Insert property declaration AST nodes into 382/// ObjCContainerDecl's PropertyDecl field. 383/// 384void ObjCContainerDecl::addProperties(ObjCPropertyDecl **Properties, 385 unsigned NumProperties) { 386 if (NumProperties == 0) return; 387 388 NumPropertyDecl = NumProperties; 389 PropertyDecl = new ObjCPropertyDecl*[NumProperties]; 390 memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*)); 391} 392 393/// FindPropertyDeclaration - Finds declaration of the property given its name 394/// in 'PropertyId' and returns it. It returns 0, if not found. 395/// 396ObjCPropertyDecl * 397ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { 398 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) { 399 ObjCPropertyDecl *property = *I; 400 if (property->getIdentifier() == PropertyId) 401 return property; 402 } 403 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this); 404 if (PID) { 405 for (ObjCProtocolDecl::protocol_iterator P = PID->protocol_begin(), 406 E = PID->protocol_end(); 407 P != E; ++P) 408 if (ObjCPropertyDecl *property = 409 (*P)->FindPropertyDeclaration(PropertyId)) 410 return property; 411 } 412 413 const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this); 414 if (OID) { 415 // Look through categories. 416 for (ObjCCategoryDecl *Category = OID->getCategoryList(); 417 Category; Category = Category->getNextClassCategory()) { 418 ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId); 419 if (property) 420 return property; 421 } 422 // Look through protocols. 423 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(), 424 E = OID->protocol_end(); I != E; ++I) { 425 ObjCProtocolDecl *Protocol = *I; 426 ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId); 427 if (property) 428 return property; 429 } 430 if (OID->getSuperClass()) 431 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId); 432 } 433 return 0; 434} 435 436ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable( 437 IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) { 438 ObjCInterfaceDecl* ClassDecl = this; 439 while (ClassDecl != NULL) { 440 for (ivar_iterator I = ClassDecl->ivar_begin(), E = ClassDecl->ivar_end(); 441 I != E; ++I) { 442 if ((*I)->getIdentifier() == ID) { 443 clsDeclared = ClassDecl; 444 return *I; 445 } 446 } 447 ClassDecl = ClassDecl->getSuperClass(); 448 } 449 return NULL; 450} 451 452/// lookupInstanceMethod - This method returns an instance method by looking in 453/// the class, its categories, and its super classes (using a linear search). 454ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) { 455 ObjCInterfaceDecl* ClassDecl = this; 456 ObjCMethodDecl *MethodDecl = 0; 457 458 while (ClassDecl != NULL) { 459 if ((MethodDecl = ClassDecl->getInstanceMethod(Sel))) 460 return MethodDecl; 461 462 // Didn't find one yet - look through protocols. 463 const ObjCList<ObjCProtocolDecl> &Protocols = 464 ClassDecl->getReferencedProtocols(); 465 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 466 E = Protocols.end(); I != E; ++I) 467 if ((MethodDecl = (*I)->getInstanceMethod(Sel))) 468 return MethodDecl; 469 470 // Didn't find one yet - now look through categories. 471 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); 472 while (CatDecl) { 473 if ((MethodDecl = CatDecl->getInstanceMethod(Sel))) 474 return MethodDecl; 475 476 // Didn't find one yet - look through protocols. 477 const ObjCList<ObjCProtocolDecl> &Protocols = 478 CatDecl->getReferencedProtocols(); 479 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 480 E = Protocols.end(); I != E; ++I) 481 if ((MethodDecl = (*I)->getInstanceMethod(Sel))) 482 return MethodDecl; 483 CatDecl = CatDecl->getNextClassCategory(); 484 } 485 ClassDecl = ClassDecl->getSuperClass(); 486 } 487 return NULL; 488} 489 490// lookupClassMethod - This method returns a class method by looking in the 491// class, its categories, and its super classes (using a linear search). 492ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) { 493 ObjCInterfaceDecl* ClassDecl = this; 494 ObjCMethodDecl *MethodDecl = 0; 495 496 while (ClassDecl != NULL) { 497 if ((MethodDecl = ClassDecl->getClassMethod(Sel))) 498 return MethodDecl; 499 500 // Didn't find one yet - look through protocols. 501 for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(), 502 E = ClassDecl->protocol_end(); I != E; ++I) 503 if ((MethodDecl = (*I)->getClassMethod(Sel))) 504 return MethodDecl; 505 506 // Didn't find one yet - now look through categories. 507 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); 508 while (CatDecl) { 509 if ((MethodDecl = CatDecl->getClassMethod(Sel))) 510 return MethodDecl; 511 CatDecl = CatDecl->getNextClassCategory(); 512 } 513 ClassDecl = ClassDecl->getSuperClass(); 514 } 515 return NULL; 516} 517 518/// getInstanceMethod - This method returns an instance method by 519/// looking in the class implementation. Unlike interfaces, we don't 520/// look outside the implementation. 521ObjCMethodDecl *ObjCImplementationDecl::getInstanceMethod(Selector Sel) const { 522 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I) 523 if ((*I)->getSelector() == Sel) 524 return *I; 525 return NULL; 526} 527 528/// getClassMethod - This method returns a class method by looking in 529/// the class implementation. Unlike interfaces, we don't look outside 530/// the implementation. 531ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const { 532 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 533 I != E; ++I) 534 if ((*I)->getSelector() == Sel) 535 return *I; 536 return NULL; 537} 538 539/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl 540/// added to the list of those properties @synthesized/@dynamic in this 541/// @implementation block. 542/// 543ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const { 544 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { 545 ObjCPropertyImplDecl *PID = *i; 546 if (PID->getPropertyDecl()->getIdentifier() == Id) 547 return PID; 548 } 549 return 0; 550} 551 552/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of 553/// properties implemented in this @implementation block and returns the 554/// implemented property that uses it. 555/// 556ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { 557 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { 558 ObjCPropertyImplDecl *PID = *i; 559 if (PID->getPropertyIvarDecl() && 560 PID->getPropertyIvarDecl()->getIdentifier() == ivarId) 561 return PID; 562 } 563 return 0; 564} 565 566/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of 567/// properties implemented in this category @implementation block and returns the 568/// implemented property that uses it. 569/// 570ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { 571 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { 572 ObjCPropertyImplDecl *PID = *i; 573 if (PID->getPropertyIvarDecl() && 574 PID->getPropertyIvarDecl()->getIdentifier() == ivarId) 575 return PID; 576 } 577 return 0; 578} 579 580/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl 581/// added to the list of those properties @synthesized/@dynamic in this 582/// category @implementation block. 583/// 584ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const { 585 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { 586 ObjCPropertyImplDecl *PID = *i; 587 if (PID->getPropertyDecl()->getIdentifier() == Id) 588 return PID; 589 } 590 return 0; 591} 592 593// lookupInstanceMethod - This method returns an instance method by looking in 594// the class implementation. Unlike interfaces, we don't look outside the 595// implementation. 596ObjCMethodDecl *ObjCCategoryImplDecl::getInstanceMethod(Selector Sel) const { 597 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I) 598 if ((*I)->getSelector() == Sel) 599 return *I; 600 return NULL; 601} 602 603// lookupClassMethod - This method returns an instance method by looking in 604// the class implementation. Unlike interfaces, we don't look outside the 605// implementation. 606ObjCMethodDecl *ObjCCategoryImplDecl::getClassMethod(Selector Sel) const { 607 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 608 I != E; ++I) 609 if ((*I)->getSelector() == Sel) 610 return *I; 611 return NULL; 612} 613 614// lookupInstanceMethod - Lookup a instance method in the protocol and protocols 615// it inherited. 616ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) { 617 ObjCMethodDecl *MethodDecl = NULL; 618 619 if ((MethodDecl = getInstanceMethod(Sel))) 620 return MethodDecl; 621 622 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I) 623 if ((MethodDecl = (*I)->lookupInstanceMethod(Sel))) 624 return MethodDecl; 625 return NULL; 626} 627 628// lookupInstanceMethod - Lookup a class method in the protocol and protocols 629// it inherited. 630ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) { 631 ObjCMethodDecl *MethodDecl = NULL; 632 633 if ((MethodDecl = getClassMethod(Sel))) 634 return MethodDecl; 635 636 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I) 637 if ((MethodDecl = (*I)->lookupClassMethod(Sel))) 638 return MethodDecl; 639 return NULL; 640} 641 642/// getSynthesizedMethodSize - Compute size of synthesized method name 643/// as done be the rewrite. 644/// 645unsigned ObjCMethodDecl::getSynthesizedMethodSize() const { 646 // syntesized method name is a concatenation of -/+[class-name selector] 647 // Get length of this name. 648 unsigned length = 3; // _I_ or _C_ 649 length += getClassInterface()->getNameAsString().size()+1; // extra for _ 650 if (const ObjCCategoryImplDecl *CID = 651 dyn_cast<ObjCCategoryImplDecl>(getDeclContext())) 652 length += CID->getNameAsString().size()+1; 653 length += getSelector().getAsString().size(); // selector name 654 return length; 655} 656 657ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() { 658 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext())) 659 return ID; 660 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext())) 661 return CD->getClassInterface(); 662 if (ObjCImplementationDecl *IMD = 663 dyn_cast<ObjCImplementationDecl>(getDeclContext())) 664 return IMD->getClassInterface(); 665 if (ObjCCategoryImplDecl *CID = 666 dyn_cast<ObjCCategoryImplDecl>(getDeclContext())) 667 return CID->getClassInterface(); 668 assert(false && "unknown method context"); 669 return 0; 670} 671 672ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, 673 DeclContext *DC, 674 SourceLocation atLoc, 675 SourceLocation L, 676 ObjCPropertyDecl *property, 677 Kind PK, 678 ObjCIvarDecl *ivar) { 679 void *Mem = C.getAllocator().Allocate<ObjCPropertyImplDecl>(); 680 return new (Mem) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar); 681} 682 683 684