DeclObjC.cpp revision 4bc1cb6aa635a5bf8fae99bf69c56c724c1e786c
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" 18using namespace clang; 19 20//===----------------------------------------------------------------------===// 21// ObjCListBase 22//===----------------------------------------------------------------------===// 23 24void ObjCListBase::Destroy(ASTContext &Ctx) { 25 Ctx.Deallocate(List); 26 NumElts = 0; 27 List = 0; 28} 29 30void 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 40void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts, 41 const SourceLocation *Locs, ASTContext &Ctx) { 42 if (Elts == 0) 43 return; 44 45 Locations = new (Ctx) SourceLocation[Elts]; 46 memcpy(Locations, Locs, sizeof(SourceLocation) * Elts); 47 set(InList, Elts, Ctx); 48} 49 50void ObjCProtocolList::Destroy(ASTContext &Ctx) { 51 Ctx.Deallocate(Locations); 52 Locations = 0; 53 ObjCList<ObjCProtocolDecl>::Destroy(Ctx); 54} 55 56//===----------------------------------------------------------------------===// 57// ObjCInterfaceDecl 58//===----------------------------------------------------------------------===// 59 60/// getIvarDecl - This method looks up an ivar in this ContextDecl. 61/// 62ObjCIvarDecl * 63ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const { 64 lookup_const_iterator Ivar, IvarEnd; 65 for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) { 66 if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar)) 67 return ivar; 68 } 69 return 0; 70} 71 72// Get the local instance/class method declared in this interface. 73ObjCMethodDecl * 74ObjCContainerDecl::getMethod(Selector Sel, bool isInstance) const { 75 // Since instance & class methods can have the same name, the loop below 76 // ensures we get the correct method. 77 // 78 // @interface Whatever 79 // - (int) class_method; 80 // + (float) class_method; 81 // @end 82 // 83 lookup_const_iterator Meth, MethEnd; 84 for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) { 85 ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth); 86 if (MD && MD->isInstanceMethod() == isInstance) 87 return MD; 88 } 89 return 0; 90} 91 92/// FindPropertyDeclaration - Finds declaration of the property given its name 93/// in 'PropertyId' and returns it. It returns 0, if not found. 94/// FIXME: Convert to DeclContext lookup... 95/// 96ObjCPropertyDecl * 97ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { 98 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) 99 if ((*I)->getIdentifier() == PropertyId) 100 return *I; 101 102 const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this); 103 if (PID) { 104 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), 105 E = PID->protocol_end(); I != E; ++I) 106 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) 107 return P; 108 } 109 110 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this)) { 111 // Look through categories. 112 for (ObjCCategoryDecl *Category = OID->getCategoryList(); 113 Category; Category = Category->getNextClassCategory()) { 114 if (!Category->IsClassExtension()) 115 if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId)) 116 return P; 117 } 118 // Look through protocols. 119 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(), 120 E = OID->protocol_end(); I != E; ++I) { 121 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) 122 return P; 123 } 124 if (OID->getSuperClass()) 125 return OID->getSuperClass()->FindPropertyDeclaration(PropertyId); 126 } else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) { 127 // Look through protocols. 128 if (!OCD->IsClassExtension()) 129 for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(), 130 E = OCD->protocol_end(); I != E; ++I) { 131 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) 132 return P; 133 } 134 } 135 return 0; 136} 137 138/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property 139/// with name 'PropertyId' in the primary class; including those in protocols 140/// (direct or indirect) used by the promary class. 141/// FIXME: Convert to DeclContext lookup... 142/// 143ObjCPropertyDecl * 144ObjCContainerDecl::FindPropertyVisibleInPrimaryClass( 145 IdentifierInfo *PropertyId) const { 146 assert(isa<ObjCInterfaceDecl>(this) && "FindPropertyVisibleInPrimaryClass"); 147 for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) 148 if ((*I)->getIdentifier() == PropertyId) 149 return *I; 150 const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this); 151 // Look through protocols. 152 for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(), 153 E = OID->protocol_end(); I != E; ++I) 154 if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId)) 155 return P; 156 return 0; 157} 158 159void ObjCInterfaceDecl::mergeClassExtensionProtocolList( 160 ObjCProtocolDecl *const* ExtList, unsigned ExtNum, 161 const SourceLocation *Locs, 162 ASTContext &C) 163{ 164 if (ReferencedProtocols.empty()) { 165 ReferencedProtocols.set(ExtList, ExtNum, Locs, C); 166 return; 167 } 168 // Check for duplicate protocol in class's protocol list. 169 // This is (O)2. But it is extremely rare and number of protocols in 170 // class or its extension are very few. 171 llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs; 172 llvm::SmallVector<SourceLocation, 8> ProtocolLocs; 173 for (unsigned i = 0; i < ExtNum; i++) { 174 bool protocolExists = false; 175 ObjCProtocolDecl *ProtoInExtension = ExtList[i]; 176 for (protocol_iterator p = protocol_begin(), e = protocol_end(); 177 p != e; p++) { 178 ObjCProtocolDecl *Proto = (*p); 179 if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) { 180 protocolExists = true; 181 break; 182 } 183 } 184 // Do we want to warn on a protocol in extension class which 185 // already exist in the class? Probably not. 186 if (!protocolExists) { 187 ProtocolRefs.push_back(ProtoInExtension); 188 ProtocolLocs.push_back(Locs[i]); 189 } 190 } 191 if (ProtocolRefs.empty()) 192 return; 193 // Merge ProtocolRefs into class's protocol list; 194 protocol_loc_iterator pl = protocol_loc_begin(); 195 for (protocol_iterator p = protocol_begin(), e = protocol_end(); 196 p != e; ++p, ++pl) { 197 ProtocolRefs.push_back(*p); 198 ProtocolLocs.push_back(*pl); 199 } 200 ReferencedProtocols.Destroy(C); 201 unsigned NumProtoRefs = ProtocolRefs.size(); 202 setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C); 203} 204 205/// getClassExtension - Find class extension of the given class. 206// FIXME. can speed it up, if need be. 207ObjCCategoryDecl* ObjCInterfaceDecl::getClassExtension() const { 208 const ObjCInterfaceDecl* ClassDecl = this; 209 for (ObjCCategoryDecl *CDecl = ClassDecl->getCategoryList(); CDecl; 210 CDecl = CDecl->getNextClassCategory()) 211 if (CDecl->IsClassExtension()) 212 return CDecl; 213 return 0; 214} 215 216ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID, 217 ObjCInterfaceDecl *&clsDeclared) { 218 ObjCInterfaceDecl* ClassDecl = this; 219 while (ClassDecl != NULL) { 220 if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) { 221 clsDeclared = ClassDecl; 222 return I; 223 } 224 if (const ObjCCategoryDecl *CDecl = ClassDecl->getClassExtension()) 225 if (ObjCIvarDecl *I = CDecl->getIvarDecl(ID)) { 226 clsDeclared = ClassDecl; 227 return I; 228 } 229 230 ClassDecl = ClassDecl->getSuperClass(); 231 } 232 return NULL; 233} 234 235/// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super 236/// class whose name is passed as argument. If it is not one of the super classes 237/// the it returns NULL. 238ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass( 239 const IdentifierInfo*ICName) { 240 ObjCInterfaceDecl* ClassDecl = this; 241 while (ClassDecl != NULL) { 242 if (ClassDecl->getIdentifier() == ICName) 243 return ClassDecl; 244 ClassDecl = ClassDecl->getSuperClass(); 245 } 246 return NULL; 247} 248 249/// lookupMethod - This method returns an instance/class method by looking in 250/// the class, its categories, and its super classes (using a linear search). 251ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, 252 bool isInstance) const { 253 const ObjCInterfaceDecl* ClassDecl = this; 254 ObjCMethodDecl *MethodDecl = 0; 255 256 while (ClassDecl != NULL) { 257 if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance))) 258 return MethodDecl; 259 260 // Didn't find one yet - look through protocols. 261 const ObjCList<ObjCProtocolDecl> &Protocols = 262 ClassDecl->getReferencedProtocols(); 263 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 264 E = Protocols.end(); I != E; ++I) 265 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance))) 266 return MethodDecl; 267 268 // Didn't find one yet - now look through categories. 269 ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList(); 270 while (CatDecl) { 271 if ((MethodDecl = CatDecl->getMethod(Sel, isInstance))) 272 return MethodDecl; 273 274 // Didn't find one yet - look through protocols. 275 const ObjCList<ObjCProtocolDecl> &Protocols = 276 CatDecl->getReferencedProtocols(); 277 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 278 E = Protocols.end(); I != E; ++I) 279 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance))) 280 return MethodDecl; 281 CatDecl = CatDecl->getNextClassCategory(); 282 } 283 ClassDecl = ClassDecl->getSuperClass(); 284 } 285 return NULL; 286} 287 288ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateInstanceMethod( 289 const Selector &Sel) { 290 ObjCMethodDecl *Method = 0; 291 if (ObjCImplementationDecl *ImpDecl = getImplementation()) 292 Method = ImpDecl->getInstanceMethod(Sel); 293 294 if (!Method && getSuperClass()) 295 return getSuperClass()->lookupPrivateInstanceMethod(Sel); 296 return Method; 297} 298 299//===----------------------------------------------------------------------===// 300// ObjCMethodDecl 301//===----------------------------------------------------------------------===// 302 303ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, 304 SourceLocation beginLoc, 305 SourceLocation endLoc, 306 Selector SelInfo, QualType T, 307 TypeSourceInfo *ResultTInfo, 308 DeclContext *contextDecl, 309 bool isInstance, 310 bool isVariadic, 311 bool isSynthesized, 312 ImplementationControl impControl) { 313 return new (C) ObjCMethodDecl(beginLoc, endLoc, 314 SelInfo, T, ResultTInfo, contextDecl, 315 isInstance, 316 isVariadic, isSynthesized, impControl); 317} 318 319void ObjCMethodDecl::Destroy(ASTContext &C) { 320 if (Body) Body->Destroy(C); 321 if (SelfDecl) SelfDecl->Destroy(C); 322 323 for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) 324 if (*I) (*I)->Destroy(C); 325 326 ParamInfo.Destroy(C); 327 328 Decl::Destroy(C); 329} 330 331/// \brief A definition will return its interface declaration. 332/// An interface declaration will return its definition. 333/// Otherwise it will return itself. 334ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() { 335 ASTContext &Ctx = getASTContext(); 336 ObjCMethodDecl *Redecl = 0; 337 Decl *CtxD = cast<Decl>(getDeclContext()); 338 339 if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) { 340 if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD)) 341 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); 342 343 } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) { 344 if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD)) 345 Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); 346 347 } else if (ObjCImplementationDecl *ImplD = 348 dyn_cast<ObjCImplementationDecl>(CtxD)) { 349 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) 350 Redecl = IFD->getMethod(getSelector(), isInstanceMethod()); 351 352 } else if (ObjCCategoryImplDecl *CImplD = 353 dyn_cast<ObjCCategoryImplDecl>(CtxD)) { 354 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl()) 355 Redecl = CatD->getMethod(getSelector(), isInstanceMethod()); 356 } 357 358 return Redecl ? Redecl : this; 359} 360 361ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() { 362 Decl *CtxD = cast<Decl>(getDeclContext()); 363 364 if (ObjCImplementationDecl *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) { 365 if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) 366 if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(), 367 isInstanceMethod())) 368 return MD; 369 370 } else if (ObjCCategoryImplDecl *CImplD = 371 dyn_cast<ObjCCategoryImplDecl>(CtxD)) { 372 if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl()) 373 if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(), 374 isInstanceMethod())) 375 return MD; 376 } 377 378 return this; 379} 380 381void ObjCMethodDecl::createImplicitParams(ASTContext &Context, 382 const ObjCInterfaceDecl *OID) { 383 QualType selfTy; 384 if (isInstanceMethod()) { 385 // There may be no interface context due to error in declaration 386 // of the interface (which has been reported). Recover gracefully. 387 if (OID) { 388 selfTy = Context.getObjCInterfaceType(OID); 389 selfTy = Context.getObjCObjectPointerType(selfTy); 390 } else { 391 selfTy = Context.getObjCIdType(); 392 } 393 } else // we have a factory method. 394 selfTy = Context.getObjCClassType(); 395 396 setSelfDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(), 397 &Context.Idents.get("self"), selfTy)); 398 399 setCmdDecl(ImplicitParamDecl::Create(Context, this, SourceLocation(), 400 &Context.Idents.get("_cmd"), 401 Context.getObjCSelType())); 402} 403 404ObjCInterfaceDecl *ObjCMethodDecl::getClassInterface() { 405 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(getDeclContext())) 406 return ID; 407 if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(getDeclContext())) 408 return CD->getClassInterface(); 409 if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext())) 410 return IMD->getClassInterface(); 411 412 assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method"); 413 assert(false && "unknown method context"); 414 return 0; 415} 416 417//===----------------------------------------------------------------------===// 418// ObjCInterfaceDecl 419//===----------------------------------------------------------------------===// 420 421ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, 422 DeclContext *DC, 423 SourceLocation atLoc, 424 IdentifierInfo *Id, 425 SourceLocation ClassLoc, 426 bool ForwardDecl, bool isInternal){ 427 return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl, 428 isInternal); 429} 430 431ObjCInterfaceDecl:: 432ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, 433 SourceLocation CLoc, bool FD, bool isInternal) 434 : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id), 435 TypeForDecl(0), SuperClass(0), 436 CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal), 437 ClassLoc(CLoc) { 438} 439 440void ObjCInterfaceDecl::Destroy(ASTContext &C) { 441 for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I) 442 if (*I) (*I)->Destroy(C); 443 444 IVars.Destroy(C); 445 // FIXME: CategoryList? 446 447 // FIXME: Because there is no clear ownership 448 // role between ObjCInterfaceDecls and the ObjCPropertyDecls that they 449 // reference, we destroy ObjCPropertyDecls in ~TranslationUnit. 450 Decl::Destroy(C); 451} 452 453ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const { 454 return getASTContext().getObjCImplementation( 455 const_cast<ObjCInterfaceDecl*>(this)); 456} 457 458void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) { 459 getASTContext().setObjCImplementation(this, ImplD); 460} 461 462 463/// FindCategoryDeclaration - Finds category declaration in the list of 464/// categories for this class and returns it. Name of the category is passed 465/// in 'CategoryId'. If category not found, return 0; 466/// 467ObjCCategoryDecl * 468ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const { 469 for (ObjCCategoryDecl *Category = getCategoryList(); 470 Category; Category = Category->getNextClassCategory()) 471 if (Category->getIdentifier() == CategoryId) 472 return Category; 473 return 0; 474} 475 476ObjCMethodDecl * 477ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const { 478 for (ObjCCategoryDecl *Category = getCategoryList(); 479 Category; Category = Category->getNextClassCategory()) 480 if (ObjCCategoryImplDecl *Impl = Category->getImplementation()) 481 if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel)) 482 return MD; 483 return 0; 484} 485 486ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const { 487 for (ObjCCategoryDecl *Category = getCategoryList(); 488 Category; Category = Category->getNextClassCategory()) 489 if (ObjCCategoryImplDecl *Impl = Category->getImplementation()) 490 if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel)) 491 return MD; 492 return 0; 493} 494 495/// ClassImplementsProtocol - Checks that 'lProto' protocol 496/// has been implemented in IDecl class, its super class or categories (if 497/// lookupCategory is true). 498bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto, 499 bool lookupCategory, 500 bool RHSIsQualifiedID) { 501 ObjCInterfaceDecl *IDecl = this; 502 // 1st, look up the class. 503 const ObjCList<ObjCProtocolDecl> &Protocols = 504 IDecl->getReferencedProtocols(); 505 506 for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(), 507 E = Protocols.end(); PI != E; ++PI) { 508 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI)) 509 return true; 510 // This is dubious and is added to be compatible with gcc. In gcc, it is 511 // also allowed assigning a protocol-qualified 'id' type to a LHS object 512 // when protocol in qualified LHS is in list of protocols in the rhs 'id' 513 // object. This IMO, should be a bug. 514 // FIXME: Treat this as an extension, and flag this as an error when GCC 515 // extensions are not enabled. 516 if (RHSIsQualifiedID && 517 getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto)) 518 return true; 519 } 520 521 // 2nd, look up the category. 522 if (lookupCategory) 523 for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl; 524 CDecl = CDecl->getNextClassCategory()) { 525 for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(), 526 E = CDecl->protocol_end(); PI != E; ++PI) 527 if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI)) 528 return true; 529 } 530 531 // 3rd, look up the super class(s) 532 if (IDecl->getSuperClass()) 533 return 534 IDecl->getSuperClass()->ClassImplementsProtocol(lProto, lookupCategory, 535 RHSIsQualifiedID); 536 537 return false; 538} 539 540//===----------------------------------------------------------------------===// 541// ObjCIvarDecl 542//===----------------------------------------------------------------------===// 543 544ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, DeclContext *DC, 545 SourceLocation L, IdentifierInfo *Id, 546 QualType T, TypeSourceInfo *TInfo, 547 AccessControl ac, Expr *BW) { 548 return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW); 549} 550 551 552 553//===----------------------------------------------------------------------===// 554// ObjCAtDefsFieldDecl 555//===----------------------------------------------------------------------===// 556 557ObjCAtDefsFieldDecl 558*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 559 IdentifierInfo *Id, QualType T, Expr *BW) { 560 return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW); 561} 562 563void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) { 564 this->~ObjCAtDefsFieldDecl(); 565 C.Deallocate((void *)this); 566} 567 568//===----------------------------------------------------------------------===// 569// ObjCProtocolDecl 570//===----------------------------------------------------------------------===// 571 572ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, 573 SourceLocation L, 574 IdentifierInfo *Id) { 575 return new (C) ObjCProtocolDecl(DC, L, Id); 576} 577 578void ObjCProtocolDecl::Destroy(ASTContext &C) { 579 ReferencedProtocols.Destroy(C); 580 ObjCContainerDecl::Destroy(C); 581} 582 583ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) { 584 ObjCProtocolDecl *PDecl = this; 585 586 if (Name == getIdentifier()) 587 return PDecl; 588 589 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I) 590 if ((PDecl = (*I)->lookupProtocolNamed(Name))) 591 return PDecl; 592 593 return NULL; 594} 595 596// lookupMethod - Lookup a instance/class method in the protocol and protocols 597// it inherited. 598ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel, 599 bool isInstance) const { 600 ObjCMethodDecl *MethodDecl = NULL; 601 602 if ((MethodDecl = getMethod(Sel, isInstance))) 603 return MethodDecl; 604 605 for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I) 606 if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance))) 607 return MethodDecl; 608 return NULL; 609} 610 611//===----------------------------------------------------------------------===// 612// ObjCClassDecl 613//===----------------------------------------------------------------------===// 614 615ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L, 616 ObjCInterfaceDecl *const *Elts, 617 const SourceLocation *Locs, 618 unsigned nElts, 619 ASTContext &C) 620 : Decl(ObjCClass, DC, L) { 621 setClassList(C, Elts, Locs, nElts); 622} 623 624void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, 625 const SourceLocation *Locs, unsigned Num) { 626 ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num, 627 llvm::alignof<ObjCClassRef>()); 628 for (unsigned i = 0; i < Num; ++i) 629 new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]); 630 631 NumDecls = Num; 632} 633 634ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC, 635 SourceLocation L, 636 ObjCInterfaceDecl *const *Elts, 637 const SourceLocation *Locs, 638 unsigned nElts) { 639 return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C); 640} 641 642void ObjCClassDecl::Destroy(ASTContext &C) { 643 // ObjCInterfaceDecls registered with a DeclContext will get destroyed 644 // when the DeclContext is destroyed. For those created only by a forward 645 // declaration, the first @class that created the ObjCInterfaceDecl gets 646 // to destroy it. 647 // FIXME: Note that this ownership role is very brittle; a better 648 // polict is surely need in the future. 649 for (iterator I = begin(), E = end(); I !=E ; ++I) { 650 ObjCInterfaceDecl *ID = I->getInterface(); 651 if (ID->isForwardDecl() && ID->getLocStart() == getLocStart()) 652 ID->Destroy(C); 653 } 654 655 C.Deallocate(ForwardDecls); 656 Decl::Destroy(C); 657} 658 659SourceRange ObjCClassDecl::getSourceRange() const { 660 // FIXME: We should include the semicolon 661 assert(NumDecls); 662 return SourceRange(getLocation(), ForwardDecls[NumDecls-1].getLocation()); 663} 664 665//===----------------------------------------------------------------------===// 666// ObjCForwardProtocolDecl 667//===----------------------------------------------------------------------===// 668 669ObjCForwardProtocolDecl:: 670ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, 671 ObjCProtocolDecl *const *Elts, unsigned nElts, 672 const SourceLocation *Locs, ASTContext &C) 673: Decl(ObjCForwardProtocol, DC, L) { 674 ReferencedProtocols.set(Elts, nElts, Locs, C); 675} 676 677 678ObjCForwardProtocolDecl * 679ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC, 680 SourceLocation L, 681 ObjCProtocolDecl *const *Elts, 682 unsigned NumElts, 683 const SourceLocation *Locs) { 684 return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C); 685} 686 687void ObjCForwardProtocolDecl::Destroy(ASTContext &C) { 688 ReferencedProtocols.Destroy(C); 689 Decl::Destroy(C); 690} 691 692//===----------------------------------------------------------------------===// 693// ObjCCategoryDecl 694//===----------------------------------------------------------------------===// 695 696ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, 697 SourceLocation AtLoc, 698 SourceLocation ClassNameLoc, 699 SourceLocation CategoryNameLoc, 700 IdentifierInfo *Id) { 701 return new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id); 702} 703 704ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const { 705 return getASTContext().getObjCImplementation( 706 const_cast<ObjCCategoryDecl*>(this)); 707} 708 709void ObjCCategoryDecl::setImplementation(ObjCCategoryImplDecl *ImplD) { 710 getASTContext().setObjCImplementation(this, ImplD); 711} 712 713 714//===----------------------------------------------------------------------===// 715// ObjCCategoryImplDecl 716//===----------------------------------------------------------------------===// 717 718ObjCCategoryImplDecl * 719ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC, 720 SourceLocation L,IdentifierInfo *Id, 721 ObjCInterfaceDecl *ClassInterface) { 722 return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface); 723} 724 725ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const { 726 return getClassInterface()->FindCategoryDeclaration(getIdentifier()); 727} 728 729 730void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) { 731 // FIXME: The context should be correct before we get here. 732 property->setLexicalDeclContext(this); 733 addDecl(property); 734} 735 736void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) { 737 ASTContext &Ctx = getASTContext(); 738 739 if (ObjCImplementationDecl *ImplD 740 = dyn_cast_or_null<ObjCImplementationDecl>(this)) { 741 if (IFace) 742 Ctx.setObjCImplementation(IFace, ImplD); 743 744 } else if (ObjCCategoryImplDecl *ImplD = 745 dyn_cast_or_null<ObjCCategoryImplDecl>(this)) { 746 if (ObjCCategoryDecl *CD = IFace->FindCategoryDeclaration(getIdentifier())) 747 Ctx.setObjCImplementation(CD, ImplD); 748 } 749 750 ClassInterface = IFace; 751} 752 753/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of 754/// properties implemented in this category @implementation block and returns 755/// the implemented property that uses it. 756/// 757ObjCPropertyImplDecl *ObjCImplDecl:: 758FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { 759 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){ 760 ObjCPropertyImplDecl *PID = *i; 761 if (PID->getPropertyIvarDecl() && 762 PID->getPropertyIvarDecl()->getIdentifier() == ivarId) 763 return PID; 764 } 765 return 0; 766} 767 768/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl 769/// added to the list of those properties @synthesized/@dynamic in this 770/// category @implementation block. 771/// 772ObjCPropertyImplDecl *ObjCImplDecl:: 773FindPropertyImplDecl(IdentifierInfo *Id) const { 774 for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){ 775 ObjCPropertyImplDecl *PID = *i; 776 if (PID->getPropertyDecl()->getIdentifier() == Id) 777 return PID; 778 } 779 return 0; 780} 781 782//===----------------------------------------------------------------------===// 783// ObjCImplementationDecl 784//===----------------------------------------------------------------------===// 785 786ObjCImplementationDecl * 787ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, 788 SourceLocation L, 789 ObjCInterfaceDecl *ClassInterface, 790 ObjCInterfaceDecl *SuperDecl) { 791 return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl); 792} 793 794//===----------------------------------------------------------------------===// 795// ObjCCompatibleAliasDecl 796//===----------------------------------------------------------------------===// 797 798ObjCCompatibleAliasDecl * 799ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, 800 SourceLocation L, 801 IdentifierInfo *Id, 802 ObjCInterfaceDecl* AliasedClass) { 803 return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass); 804} 805 806//===----------------------------------------------------------------------===// 807// ObjCPropertyDecl 808//===----------------------------------------------------------------------===// 809 810ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, 811 SourceLocation L, 812 IdentifierInfo *Id, 813 SourceLocation AtLoc, 814 QualType T, 815 PropertyControl propControl) { 816 return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T); 817} 818 819 820//===----------------------------------------------------------------------===// 821// ObjCPropertyImplDecl 822//===----------------------------------------------------------------------===// 823 824ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, 825 DeclContext *DC, 826 SourceLocation atLoc, 827 SourceLocation L, 828 ObjCPropertyDecl *property, 829 Kind PK, 830 ObjCIvarDecl *ivar) { 831 return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar); 832} 833 834 835