1 //===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the Objective-C related Decl classes. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/DeclObjC.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/Stmt.h" 17 #include "llvm/ADT/STLExtras.h" 18 using namespace clang; 19 20 //===----------------------------------------------------------------------===// 21 // ObjCListBase 22 //===----------------------------------------------------------------------===// 23 24 void ObjCListBase::Destroy(ASTContext &Ctx) { 25 Ctx.Deallocate(List); 26 NumElts = 0; 27 List = 0; 28 } 29 30 void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) { 31 assert(List == 0 && "Elements already set!"); 32 if (Elts == 0) return; // Setting to an empty list is a noop. 33 34 35 List = new (Ctx) void*[Elts]; 36 NumElts = Elts; 37 memcpy(List, InList, sizeof(void*)*Elts); 38 } 39 40 41 //===----------------------------------------------------------------------===// 42 // ObjCInterfaceDecl 43 //===----------------------------------------------------------------------===// 44 45 /// getIvarDecl - This method looks up an ivar in this ContextDecl. 46 /// 47 ObjCIvarDecl * 48 ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const { 49 lookup_const_iterator Ivar, IvarEnd; 50 for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) { 51 if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar)) 52 return ivar; 53 } 54 return 0; 55 } 56 57 // Get the local instance/class method declared in this interface. 58 ObjCMethodDecl * 59 ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const { 60 // Since instance & class methods can have the same name, the loop below 61 // ensures we get the correct method. 62 // 63 // @interface Whatever 64 // - (int) class_method; 65 // + (float) class_method; 66 // @end 67 // 68 lookup_const_iterator Meth, MethEnd; 69 for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) { 70 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth); 71 if (MD && MD->isInstanceMethod() == isInstance) 72 return MD; 73 } 74 return 0; 75 } 76 77 /// FindPropertyDeclaration - Finds declaration of the property given its name 78 /// in 'PropertyId' and returns it. It returns 0, if not found. 79 /// FIXME: Convert to DeclContext lookup... 80 /// 81 ObjCPropertyDecl * 82 ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { 83 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) 84 if ((*I)->getIdentifier() == PropertyId) 85 return *I; 86 87 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this); 88 if (PID) { 89 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), 90 E = PID->protocol_end(); I != E; ++I) 91 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) 92 return P; 93 } 94 95 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) { 96 // Look through categories. 97 for (ObjCCategoryDecl *Category = OID->getCategoryList(); 98 Category; Category = Category->getNextClassCategory()) { 99 if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId)) 100 return P; 101 } 102 // Look through protocols. 103 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(), 104 E = OID->protocol_end(); I != E; ++I) { 105 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) 106 return P; 107 } 108 if (OID->getSuperClass()) 109 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId); 110 } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) { 111 // Look through protocols. 112 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(), 113 E = OCD->protocol_end(); I != E; ++I) { 114 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) 115 return P; 116 } 117 } 118 return 0; 119 } 120 121 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID, 122 ObjCInterfaceDecl *&clsDeclared) { 123 ObjCInterfaceDecl* ClassDecl = this; 124 while (ClassDecl != NULL) { 125 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) { 126 clsDeclared = ClassDecl; 127 return I; 128 } 129 ClassDecl = ClassDecl->getSuperClass(); 130 } 131 return NULL; 132 } 133 134 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super 135 /// class whose name is passed as argument. If it is not one of the super classes 136 /// the it returns NULL. 137 ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass( 138 const IdentifierInfo*ICName) { 139 ObjCInterfaceDecl* ClassDecl = this; 140 while (ClassDecl != NULL) { 141 if (ClassDecl->getIdentifier() == ICName) 142 return ClassDecl; 143 ClassDecl = ClassDecl->getSuperClass(); 144 } 145 return NULL; 146 } 147 148 /// lookupMethod - This method returns an instance/class method by looking in 149 /// the class, its categories, and its super classes (using a linear search). 150 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, 151 bool isInstance) const { 152 const ObjCInterfaceDecl* ClassDecl = this; 153 ObjCMethodDecl *MethodDecl = 0; 154 155 while (ClassDecl != NULL) { 156 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance))) 157 return MethodDecl; 158 159 // Didn't find one yet - look through protocols. 160 const ObjCList<ObjCProtocolDecl> &Protocols = 161 ClassDecl->getReferencedProtocols(); 162 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 163 E = Protocols.end(); I != E; ++I) 164 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance))) 165 return MethodDecl; 166 167 // Didn't find one yet - now look through categories. 168 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); 169 while (CatDecl) { 170 if ((MethodDecl = CatDecl->getMethod(Sel, isInstance))) 171 return MethodDecl; 172 173 // Didn't find one yet - look through protocols. 174 const ObjCList<ObjCProtocolDecl> &Protocols = 175 CatDecl->getReferencedProtocols(); 176 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 177 E = Protocols.end(); I != E; ++I) 178 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance))) 179 return MethodDecl; 180 CatDecl = CatDecl->getNextClassCategory(); 181 } 182 ClassDecl = ClassDecl->getSuperClass(); 183 } 184 return NULL; 185 } 186 187 188 189 //===----------------------------------------------------------------------===// 190 // ObjCMethodDecl 191 //===----------------------------------------------------------------------===// 192 193 ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, 194 SourceLocation beginLoc, 195 SourceLocation endLoc, 196 Selector SelInfo, QualType T, 197 DeclContext *contextDecl, 198 bool isInstance, 199 bool isVariadic, 200 bool isSynthesized, 201 ImplementationControl impControl) { 202 return new (C) ObjCMethodDecl(beginLoc, endLoc, 203 SelInfo, T, contextDecl, 204 isInstance, 205 isVariadic, isSynthesized, impControl); 206 } 207 208 void ObjCMethodDecl::Destroy(ASTContext &C) { 209 if (Body) Body->Destroy(C); 210 if (SelfDecl) SelfDecl->Destroy(C); 211 212 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 213 if (*I) (*I)->Destroy(C); 214 215 ParamInfo.Destroy(C); 216 217 Decl::Destroy(C); 218 } 219 220 /// \brief A definition will return its interface declaration. 221 /// An interface declaration will return its definition. 222 /// Otherwise it will return itself. 223 ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() { 224 ASTContext &Ctx = getASTContext(); 225 ObjCMethodDecl *Redecl = 0; 226 Decl *CtxD = cast<Decl>(getDeclContext()); 227 228 if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) { 229 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD)) 230 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); 231 232 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) { 233 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD)) 234 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); 235 236 } else if (ObjCImplementationDecl *ImplD = 237 dyn_cast<ObjCImplementationDecl>(CtxD)) { 238 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) 239 Redecl = IFD->getMethod(getSelector(), isInstanceMethod()); 240 241 } else if (ObjCCategoryImplDecl *CImplD = 242 dyn_cast<ObjCCategoryImplDecl>(CtxD)) { 243 if (ObjCCategoryDecl *CatD = CImplD->getCategoryClass()) 244 Redecl = CatD->getMethod(getSelector(), isInstanceMethod()); 245 } 246 247 return Redecl ? Redecl : this; 248 } 249 250 ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() { 251 Decl *CtxD = cast<Decl>(getDeclContext()); 252 253 if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) { 254 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) 255 if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(), 256 isInstanceMethod())) 257 return MD; 258 259 } else if (ObjCCategoryImplDecl *CImplD = 260 dyn_cast<ObjCCategoryImplDecl>(CtxD)) { 261 if (ObjCCategoryDecl *CatD = CImplD->getCategoryClass()) 262 if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(), 263 isInstanceMethod())) 264 return MD; 265 } 266 267 return this; 268 } 269 270 void ObjCMethodDecl::createImplicitParams(ASTContext &Context, 271 const ObjCInterfaceDecl *OID) { 272 QualType selfTy; 273 if (isInstanceMethod()) { 274 // There may be no interface context due to error in declaration 275 // of the interface (which has been reported). Recover gracefully. 276 if (OID) { 277 selfTy = Context.getObjCInterfaceType(OID); 278 selfTy = Context.getObjCObjectPointerType(selfTy); 279 } else { 280 selfTy = Context.getObjCIdType(); 281 } 282 } else // we have a factory method. 283 selfTy = Context.getObjCClassType(); 284 285 setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(), 286 &Context.Idents.get("self"), selfTy)); 287 288 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(), 289 &Context.Idents.get("_cmd"), 290 Context.getObjCSelType())); 291 } 292 293 294 295 /// getSynthesizedMethodSize - Compute size of synthesized method name 296 /// as done be the rewrite. 297 /// 298 unsigned ObjCMethodDecl::getSynthesizedMethodSize() const { 299 // syntesized method name is a concatenation of -/+[class-name selector] 300 // Get length of this name. 301 unsigned length = 3; // _I_ or _C_ 302 length += getClassInterface()->getNameAsString().size()+1; // extra for _ 303 if (const ObjCCategoryImplDecl *CID = 304 dyn_cast<ObjCCategoryImplDecl>(getDeclContext())) 305 length += CID->getNameAsString().size()+1; 306 length += getSelector().getAsString().size(); // selector name 307 return length; 308 } 309 310 ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() { 311 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext())) 312 return ID; 313 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext())) 314 return CD->getClassInterface(); 315 if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext())) 316 return IMD->getClassInterface(); 317 318 assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method"); 319 assert(false && "unknown method context"); 320 return 0; 321 } 322 323 //===----------------------------------------------------------------------===// 324 // ObjCInterfaceDecl 325 //===----------------------------------------------------------------------===// 326 327 ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, 328 DeclContext *DC, 329 SourceLocation atLoc, 330 IdentifierInfo *Id, 331 SourceLocation ClassLoc, 332 bool ForwardDecl, bool isInternal){ 333 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl, 334 isInternal); 335 } 336 337 ObjCInterfaceDecl:: 338 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, 339 SourceLocation CLoc, bool FD, bool isInternal) 340 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id), 341 TypeForDecl(0), SuperClass(0), 342 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal), 343 ClassLoc(CLoc) { 344 } 345 346 void ObjCInterfaceDecl::Destroy(ASTContext &C) { 347 for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I) 348 if (*I) (*I)->Destroy(C); 349 350 IVars.Destroy(C); 351 // FIXME: CategoryList? 352 353 // FIXME: Because there is no clear ownership 354 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they 355 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit. 356 Decl::Destroy(C); 357 } 358 359 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const { 360 return getASTContext().getObjCImplementation( 361 const_cast<ObjCInterfaceDecl*>(this)); 362 } 363 364 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) { 365 getASTContext().setObjCImplementation(this, ImplD); 366 } 367 368 369 /// FindCategoryDeclaration - Finds category declaration in the list of 370 /// categories for this class and returns it. Name of the category is passed 371 /// in 'CategoryId'. If category not found, return 0; 372 /// 373 ObjCCategoryDecl * 374 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const { 375 for (ObjCCategoryDecl *Category = getCategoryList(); 376 Category; Category = Category->getNextClassCategory()) 377 if (Category->getIdentifier() == CategoryId) 378 return Category; 379 return 0; 380 } 381 382 ObjCMethodDecl * 383 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const { 384 for (ObjCCategoryDecl *Category = getCategoryList(); 385 Category; Category = Category->getNextClassCategory()) 386 if (ObjCCategoryImplDecl *Impl = Category->getImplementation()) 387 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel)) 388 return MD; 389 return 0; 390 } 391 392 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const { 393 for (ObjCCategoryDecl *Category = getCategoryList(); 394 Category; Category = Category->getNextClassCategory()) 395 if (ObjCCategoryImplDecl *Impl = Category->getImplementation()) 396 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel)) 397 return MD; 398 return 0; 399 } 400 401 //===----------------------------------------------------------------------===// 402 // ObjCIvarDecl 403 //===----------------------------------------------------------------------===// 404 405 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC, 406 SourceLocation L, IdentifierInfo *Id, 407 QualType T, AccessControl ac, Expr *BW) { 408 return new (C) ObjCIvarDecl(DC, L, Id, T, ac, BW); 409 } 410 411 412 413 //===----------------------------------------------------------------------===// 414 // ObjCAtDefsFieldDecl 415 //===----------------------------------------------------------------------===// 416 417 ObjCAtDefsFieldDecl 418 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 419 IdentifierInfo *Id, QualType T, Expr *BW) { 420 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW); 421 } 422 423 void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) { 424 this->~ObjCAtDefsFieldDecl(); 425 C.Deallocate((void *)this); 426 } 427 428 //===----------------------------------------------------------------------===// 429 // ObjCProtocolDecl 430 //===----------------------------------------------------------------------===// 431 432 ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, 433 SourceLocation L, 434 IdentifierInfo *Id) { 435 return new (C) ObjCProtocolDecl(DC, L, Id); 436 } 437 438 void ObjCProtocolDecl::Destroy(ASTContext &C) { 439 ReferencedProtocols.Destroy(C); 440 ObjCContainerDecl::Destroy(C); 441 } 442 443 ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) { 444 ObjCProtocolDecl *PDecl = this; 445 446 if (Name == getIdentifier()) 447 return PDecl; 448 449 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I) 450 if ((PDecl = (*I)->lookupProtocolNamed(Name))) 451 return PDecl; 452 453 return NULL; 454 } 455 456 // lookupMethod - Lookup a instance/class method in the protocol and protocols 457 // it inherited. 458 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel, 459 bool isInstance) const { 460 ObjCMethodDecl *MethodDecl = NULL; 461 462 if ((MethodDecl = getMethod(Sel, isInstance))) 463 return MethodDecl; 464 465 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I) 466 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance))) 467 return MethodDecl; 468 return NULL; 469 } 470 471 //===----------------------------------------------------------------------===// 472 // ObjCClassDecl 473 //===----------------------------------------------------------------------===// 474 475 ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L, 476 ObjCInterfaceDecl *const *Elts, unsigned nElts, 477 ASTContext &C) 478 : Decl(ObjCClass, DC, L) { 479 ForwardDecls.set(Elts, nElts, C); 480 } 481 482 483 ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC, 484 SourceLocation L, 485 ObjCInterfaceDecl *const *Elts, 486 unsigned nElts) { 487 return new (C) ObjCClassDecl(DC, L, Elts, nElts, C); 488 } 489 490 void ObjCClassDecl::Destroy(ASTContext &C) { 491 492 // FIXME: There is no clear ownership policy now for referenced 493 // ObjCInterfaceDecls. Some of them can be forward declarations that 494 // are never later defined (in which case the ObjCClassDecl owns them) 495 // or the ObjCInterfaceDecl later becomes a real definition later. Ideally 496 // we should have separate objects for forward declarations and definitions, 497 // obviating this problem. Because of this situation, referenced 498 // ObjCInterfaceDecls are destroyed in ~TranslationUnit. 499 500 ForwardDecls.Destroy(C); 501 Decl::Destroy(C); 502 } 503 504 //===----------------------------------------------------------------------===// 505 // ObjCForwardProtocolDecl 506 //===----------------------------------------------------------------------===// 507 508 ObjCForwardProtocolDecl:: 509 ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, 510 ObjCProtocolDecl *const *Elts, unsigned nElts, 511 ASTContext &C) 512 : Decl(ObjCForwardProtocol, DC, L) { 513 ReferencedProtocols.set(Elts, nElts, C); 514 } 515 516 517 ObjCForwardProtocolDecl * 518 ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC, 519 SourceLocation L, 520 ObjCProtocolDecl *const *Elts, 521 unsigned NumElts) { 522 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C); 523 } 524 525 void ObjCForwardProtocolDecl::Destroy(ASTContext &C) { 526 ReferencedProtocols.Destroy(C); 527 Decl::Destroy(C); 528 } 529 530 //===----------------------------------------------------------------------===// 531 // ObjCCategoryDecl 532 //===----------------------------------------------------------------------===// 533 534 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, 535 SourceLocation L, 536 IdentifierInfo *Id) { 537 return new (C) ObjCCategoryDecl(DC, L, Id); 538 } 539 540 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const { 541 return getASTContext().getObjCImplementation( 542 const_cast<ObjCCategoryDecl*>(this)); 543 } 544 545 void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) { 546 getASTContext().setObjCImplementation(this, ImplD); 547 } 548 549 550 //===----------------------------------------------------------------------===// 551 // ObjCCategoryImplDecl 552 //===----------------------------------------------------------------------===// 553 554 ObjCCategoryImplDecl * 555 ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC, 556 SourceLocation L,IdentifierInfo *Id, 557 ObjCInterfaceDecl *ClassInterface) { 558 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface); 559 } 560 561 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryClass() const { 562 return getClassInterface()->FindCategoryDeclaration(getIdentifier()); 563 } 564 565 566 void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) { 567 // FIXME: The context should be correct before we get here. 568 property->setLexicalDeclContext(this); 569 addDecl(property); 570 } 571 572 void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) { 573 ASTContext &Ctx = getASTContext(); 574 575 if (ObjCImplementationDecl *ImplD 576 = dyn_cast_or_null<ObjCImplementationDecl>(this)) { 577 if (IFace) 578 Ctx.setObjCImplementation(IFace, ImplD); 579 580 } else if (ObjCCategoryImplDecl *ImplD = 581 dyn_cast_or_null<ObjCCategoryImplDecl>(this)) { 582 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier())) 583 Ctx.setObjCImplementation(CD, ImplD); 584 } 585 586 ClassInterface = IFace; 587 } 588 589 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of 590 /// properties implemented in this category @implementation block and returns 591 /// the implemented property that uses it. 592 /// 593 ObjCPropertyImplDecl *ObjCImplDecl:: 594 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { 595 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){ 596 ObjCPropertyImplDecl *PID = *i; 597 if (PID->getPropertyIvarDecl() && 598 PID->getPropertyIvarDecl()->getIdentifier() == ivarId) 599 return PID; 600 } 601 return 0; 602 } 603 604 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl 605 /// added to the list of those properties @synthesized/@dynamic in this 606 /// category @implementation block. 607 /// 608 ObjCPropertyImplDecl *ObjCImplDecl:: 609 FindPropertyImplDecl(IdentifierInfo *Id) const { 610 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){ 611 ObjCPropertyImplDecl *PID = *i; 612 if (PID->getPropertyDecl()->getIdentifier() == Id) 613 return PID; 614 } 615 return 0; 616 } 617 618 //===----------------------------------------------------------------------===// 619 // ObjCImplementationDecl 620 //===----------------------------------------------------------------------===// 621 622 ObjCImplementationDecl * 623 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, 624 SourceLocation L, 625 ObjCInterfaceDecl *ClassInterface, 626 ObjCInterfaceDecl *SuperDecl) { 627 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl); 628 } 629 630 //===----------------------------------------------------------------------===// 631 // ObjCCompatibleAliasDecl 632 //===----------------------------------------------------------------------===// 633 634 ObjCCompatibleAliasDecl * 635 ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, 636 SourceLocation L, 637 IdentifierInfo *Id, 638 ObjCInterfaceDecl* AliasedClass) { 639 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass); 640 } 641 642 //===----------------------------------------------------------------------===// 643 // ObjCPropertyDecl 644 //===----------------------------------------------------------------------===// 645 646 ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, 647 SourceLocation L, 648 IdentifierInfo *Id, 649 QualType T, 650 PropertyControl propControl) { 651 return new (C) ObjCPropertyDecl(DC, L, Id, T); 652 } 653 654 655 //===----------------------------------------------------------------------===// 656 // ObjCPropertyImplDecl 657 //===----------------------------------------------------------------------===// 658 659 ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, 660 DeclContext *DC, 661 SourceLocation atLoc, 662 SourceLocation L, 663 ObjCPropertyDecl *property, 664 Kind PK, 665 ObjCIvarDecl *ivar) { 666 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar); 667 } 668 669 670