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