SemaObjCProperty.cpp revision 4341d80260f9337a505e0875f3006e052c28e6d7
1//===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===// 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 semantic analysis for Objective C @property and 11// @synthesize declarations. 12// 13//===----------------------------------------------------------------------===// 14 15#include "Sema.h" 16#include "SemaInit.h" 17#include "clang/AST/ExprObjC.h" 18 19using namespace clang; 20 21//===----------------------------------------------------------------------===// 22// Grammar actions. 23//===----------------------------------------------------------------------===// 24 25Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, 26 FieldDeclarator &FD, 27 ObjCDeclSpec &ODS, 28 Selector GetterSel, 29 Selector SetterSel, 30 DeclPtrTy ClassCategory, 31 bool *isOverridingProperty, 32 tok::ObjCKeywordKind MethodImplKind) { 33 unsigned Attributes = ODS.getPropertyAttributes(); 34 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) || 35 // default is readwrite! 36 !(Attributes & ObjCDeclSpec::DQ_PR_readonly)); 37 // property is defaulted to 'assign' if it is readwrite and is 38 // not retain or copy 39 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) || 40 (isReadWrite && 41 !(Attributes & ObjCDeclSpec::DQ_PR_retain) && 42 !(Attributes & ObjCDeclSpec::DQ_PR_copy))); 43 44 QualType T = GetTypeForDeclarator(FD.D, S); 45 if (T->isReferenceType()) { 46 Diag(AtLoc, diag::error_reference_property); 47 return DeclPtrTy(); 48 } 49 // Proceed with constructing the ObjCPropertDecls. 50 ObjCContainerDecl *ClassDecl = 51 cast<ObjCContainerDecl>(ClassCategory.getAs<Decl>()); 52 53 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) 54 if (CDecl->IsClassExtension()) 55 return HandlePropertyInClassExtension(S, CDecl, AtLoc, 56 FD, GetterSel, SetterSel, 57 isAssign, isReadWrite, 58 Attributes, 59 isOverridingProperty, T, 60 MethodImplKind); 61 62 DeclPtrTy Res = DeclPtrTy::make(CreatePropertyDecl(S, ClassDecl, AtLoc, FD, 63 GetterSel, SetterSel, 64 isAssign, isReadWrite, 65 Attributes, T, MethodImplKind)); 66 // Validate the attributes on the @property. 67 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); 68 return Res; 69} 70 71Sema::DeclPtrTy 72Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl, 73 SourceLocation AtLoc, FieldDeclarator &FD, 74 Selector GetterSel, Selector SetterSel, 75 const bool isAssign, 76 const bool isReadWrite, 77 const unsigned Attributes, 78 bool *isOverridingProperty, 79 QualType T, 80 tok::ObjCKeywordKind MethodImplKind) { 81 82 // Diagnose if this property is already in continuation class. 83 DeclContext *DC = cast<DeclContext>(CDecl); 84 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 85 86 if (ObjCPropertyDecl *prevDecl = 87 ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) { 88 Diag(AtLoc, diag::err_duplicate_property); 89 Diag(prevDecl->getLocation(), diag::note_property_declare); 90 return DeclPtrTy(); 91 } 92 93 // Create a new ObjCPropertyDecl with the DeclContext being 94 // the class extension. 95 ObjCPropertyDecl *PDecl = 96 ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(), 97 PropertyId, AtLoc, T); 98 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 99 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 100 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 101 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 102 103 DC->addDecl(PDecl); 104 105 // We need to look in the @interface to see if the @property was 106 // already declared. 107 ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface(); 108 if (!CCPrimary) { 109 Diag(CDecl->getLocation(), diag::err_continuation_class); 110 *isOverridingProperty = true; 111 return DeclPtrTy(); 112 } 113 114 // Find the property in continuation class's primary class only. 115 ObjCPropertyDecl *PIDecl = 116 CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId); 117 118 if (!PIDecl) { 119 // No matching property found in the primary class. Just fall thru 120 // and add property to continuation class's primary class. 121 ObjCPropertyDecl *PDecl = 122 CreatePropertyDecl(S, CCPrimary, AtLoc, 123 FD, GetterSel, SetterSel, isAssign, isReadWrite, 124 Attributes, T, MethodImplKind); 125 126 // A case of continuation class adding a new property in the class. This 127 // is not what it was meant for. However, gcc supports it and so should we. 128 // Make sure setter/getters are declared here. 129 ProcessPropertyDecl(PDecl, CCPrimary); 130 return DeclPtrTy::make(PDecl); 131 132 } 133 134 // The property 'PIDecl's readonly attribute will be over-ridden 135 // with continuation class's readwrite property attribute! 136 unsigned PIkind = PIDecl->getPropertyAttributes(); 137 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { 138 unsigned retainCopyNonatomic = 139 (ObjCPropertyDecl::OBJC_PR_retain | 140 ObjCPropertyDecl::OBJC_PR_copy | 141 ObjCPropertyDecl::OBJC_PR_nonatomic); 142 if ((Attributes & retainCopyNonatomic) != 143 (PIkind & retainCopyNonatomic)) { 144 Diag(AtLoc, diag::warn_property_attr_mismatch); 145 Diag(PIDecl->getLocation(), diag::note_property_declare); 146 } 147 DeclContext *DC = cast<DeclContext>(CCPrimary); 148 if (!ObjCPropertyDecl::findPropertyDecl(DC, 149 PIDecl->getDeclName().getAsIdentifierInfo())) { 150 // Protocol is not in the primary class. Must build one for it. 151 ObjCDeclSpec ProtocolPropertyODS; 152 // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind 153 // and ObjCPropertyDecl::PropertyAttributeKind have identical 154 // values. Should consolidate both into one enum type. 155 ProtocolPropertyODS. 156 setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind) 157 PIkind); 158 159 DeclPtrTy ProtocolPtrTy = 160 ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS, 161 PIDecl->getGetterName(), 162 PIDecl->getSetterName(), 163 DeclPtrTy::make(CCPrimary), isOverridingProperty, 164 MethodImplKind); 165 PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy.getAs<Decl>()); 166 } 167 PIDecl->makeitReadWriteAttribute(); 168 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 169 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 170 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 171 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 172 PIDecl->setSetterName(SetterSel); 173 } else { 174 Diag(AtLoc, diag::err_use_continuation_class) 175 << CCPrimary->getDeclName(); 176 Diag(PIDecl->getLocation(), diag::note_property_declare); 177 } 178 *isOverridingProperty = true; 179 // Make sure setter decl is synthesized, and added to primary class's list. 180 ProcessPropertyDecl(PIDecl, CCPrimary); 181 return DeclPtrTy(); 182} 183 184ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, 185 ObjCContainerDecl *CDecl, 186 SourceLocation AtLoc, 187 FieldDeclarator &FD, 188 Selector GetterSel, 189 Selector SetterSel, 190 const bool isAssign, 191 const bool isReadWrite, 192 const unsigned Attributes, 193 QualType T, 194 tok::ObjCKeywordKind MethodImplKind){ 195 196 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 197 198 // Issue a warning if property is 'assign' as default and its object, which is 199 // gc'able conforms to NSCopying protocol 200 if (getLangOptions().getGCMode() != LangOptions::NonGC && 201 isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign)) 202 if (T->isObjCObjectPointerType()) { 203 QualType InterfaceTy = T->getPointeeType(); 204 if (const ObjCInterfaceType *OIT = 205 InterfaceTy->getAs<ObjCInterfaceType>()) { 206 ObjCInterfaceDecl *IDecl = OIT->getDecl(); 207 if (IDecl) 208 if (ObjCProtocolDecl* PNSCopying = 209 LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc)) 210 if (IDecl->ClassImplementsProtocol(PNSCopying, true)) 211 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId; 212 } 213 } 214 if (T->isObjCInterfaceType()) 215 Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object); 216 217 DeclContext *DC = cast<DeclContext>(CDecl); 218 ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC, 219 FD.D.getIdentifierLoc(), 220 PropertyId, AtLoc, T); 221 222 if (ObjCPropertyDecl *prevDecl = 223 ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) { 224 Diag(PDecl->getLocation(), diag::err_duplicate_property); 225 Diag(prevDecl->getLocation(), diag::note_property_declare); 226 PDecl->setInvalidDecl(); 227 } 228 else 229 DC->addDecl(PDecl); 230 231 if (T->isArrayType() || T->isFunctionType()) { 232 Diag(AtLoc, diag::err_property_type) << T; 233 PDecl->setInvalidDecl(); 234 } 235 236 ProcessDeclAttributes(S, PDecl, FD.D); 237 238 // Regardless of setter/getter attribute, we save the default getter/setter 239 // selector names in anticipation of declaration of setter/getter methods. 240 PDecl->setGetterName(GetterSel); 241 PDecl->setSetterName(SetterSel); 242 243 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 244 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 245 246 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 247 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter); 248 249 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 250 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter); 251 252 if (isReadWrite) 253 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 254 255 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 256 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 257 258 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 259 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 260 261 if (isAssign) 262 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 263 264 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 265 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); 266 267 if (MethodImplKind == tok::objc_required) 268 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required); 269 else if (MethodImplKind == tok::objc_optional) 270 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional); 271 272 return PDecl; 273} 274 275 276/// ActOnPropertyImplDecl - This routine performs semantic checks and 277/// builds the AST node for a property implementation declaration; declared 278/// as @synthesize or @dynamic. 279/// 280Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S, 281 SourceLocation AtLoc, 282 SourceLocation PropertyLoc, 283 bool Synthesize, 284 DeclPtrTy ClassCatImpDecl, 285 IdentifierInfo *PropertyId, 286 IdentifierInfo *PropertyIvar) { 287 ObjCContainerDecl *ClassImpDecl = 288 cast_or_null<ObjCContainerDecl>(ClassCatImpDecl.getAs<Decl>()); 289 // Make sure we have a context for the property implementation declaration. 290 if (!ClassImpDecl) { 291 Diag(AtLoc, diag::error_missing_property_context); 292 return DeclPtrTy(); 293 } 294 ObjCPropertyDecl *property = 0; 295 ObjCInterfaceDecl* IDecl = 0; 296 // Find the class or category class where this property must have 297 // a declaration. 298 ObjCImplementationDecl *IC = 0; 299 ObjCCategoryImplDecl* CatImplClass = 0; 300 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) { 301 IDecl = IC->getClassInterface(); 302 // We always synthesize an interface for an implementation 303 // without an interface decl. So, IDecl is always non-zero. 304 assert(IDecl && 305 "ActOnPropertyImplDecl - @implementation without @interface"); 306 307 // Look for this property declaration in the @implementation's @interface 308 property = IDecl->FindPropertyDeclaration(PropertyId); 309 if (!property) { 310 Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName(); 311 return DeclPtrTy(); 312 } 313 if (const ObjCCategoryDecl *CD = 314 dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) { 315 if (!CD->IsClassExtension()) { 316 Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName(); 317 Diag(property->getLocation(), diag::note_property_declare); 318 return DeclPtrTy(); 319 } 320 } 321 } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) { 322 if (Synthesize) { 323 Diag(AtLoc, diag::error_synthesize_category_decl); 324 return DeclPtrTy(); 325 } 326 IDecl = CatImplClass->getClassInterface(); 327 if (!IDecl) { 328 Diag(AtLoc, diag::error_missing_property_interface); 329 return DeclPtrTy(); 330 } 331 ObjCCategoryDecl *Category = 332 IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier()); 333 334 // If category for this implementation not found, it is an error which 335 // has already been reported eralier. 336 if (!Category) 337 return DeclPtrTy(); 338 // Look for this property declaration in @implementation's category 339 property = Category->FindPropertyDeclaration(PropertyId); 340 if (!property) { 341 Diag(PropertyLoc, diag::error_bad_category_property_decl) 342 << Category->getDeclName(); 343 return DeclPtrTy(); 344 } 345 } else { 346 Diag(AtLoc, diag::error_bad_property_context); 347 return DeclPtrTy(); 348 } 349 ObjCIvarDecl *Ivar = 0; 350 // Check that we have a valid, previously declared ivar for @synthesize 351 if (Synthesize) { 352 // @synthesize 353 if (!PropertyIvar) 354 PropertyIvar = PropertyId; 355 QualType PropType = Context.getCanonicalType(property->getType()); 356 // Check that this is a previously declared 'ivar' in 'IDecl' interface 357 ObjCInterfaceDecl *ClassDeclared; 358 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared); 359 if (!Ivar) { 360 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc, 361 PropertyIvar, PropType, /*Dinfo=*/0, 362 ObjCIvarDecl::Protected, 363 (Expr *)0); 364 ClassImpDecl->addDecl(Ivar); 365 IDecl->makeDeclVisibleInContext(Ivar, false); 366 property->setPropertyIvarDecl(Ivar); 367 368 if (!getLangOptions().ObjCNonFragileABI) 369 Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId; 370 // Note! I deliberately want it to fall thru so, we have a 371 // a property implementation and to avoid future warnings. 372 } else if (getLangOptions().ObjCNonFragileABI && 373 ClassDeclared != IDecl) { 374 Diag(PropertyLoc, diag::error_ivar_in_superclass_use) 375 << property->getDeclName() << Ivar->getDeclName() 376 << ClassDeclared->getDeclName(); 377 Diag(Ivar->getLocation(), diag::note_previous_access_declaration) 378 << Ivar << Ivar->getNameAsCString(); 379 // Note! I deliberately want it to fall thru so more errors are caught. 380 } 381 QualType IvarType = Context.getCanonicalType(Ivar->getType()); 382 383 // Check that type of property and its ivar are type compatible. 384 if (PropType != IvarType) { 385 if (CheckAssignmentConstraints(PropType, IvarType) != Compatible) { 386 Diag(PropertyLoc, diag::error_property_ivar_type) 387 << property->getDeclName() << PropType 388 << Ivar->getDeclName() << IvarType; 389 Diag(Ivar->getLocation(), diag::note_ivar_decl); 390 // Note! I deliberately want it to fall thru so, we have a 391 // a property implementation and to avoid future warnings. 392 } 393 394 // FIXME! Rules for properties are somewhat different that those 395 // for assignments. Use a new routine to consolidate all cases; 396 // specifically for property redeclarations as well as for ivars. 397 QualType lhsType =Context.getCanonicalType(PropType).getUnqualifiedType(); 398 QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType(); 399 if (lhsType != rhsType && 400 lhsType->isArithmeticType()) { 401 Diag(PropertyLoc, diag::error_property_ivar_type) 402 << property->getDeclName() << PropType 403 << Ivar->getDeclName() << IvarType; 404 Diag(Ivar->getLocation(), diag::note_ivar_decl); 405 // Fall thru - see previous comment 406 } 407 // __weak is explicit. So it works on Canonical type. 408 if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() && 409 getLangOptions().getGCMode() != LangOptions::NonGC) { 410 Diag(PropertyLoc, diag::error_weak_property) 411 << property->getDeclName() << Ivar->getDeclName(); 412 // Fall thru - see previous comment 413 } 414 if ((property->getType()->isObjCObjectPointerType() || 415 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() && 416 getLangOptions().getGCMode() != LangOptions::NonGC) { 417 Diag(PropertyLoc, diag::error_strong_property) 418 << property->getDeclName() << Ivar->getDeclName(); 419 // Fall thru - see previous comment 420 } 421 } 422 } else if (PropertyIvar) 423 // @dynamic 424 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl); 425 assert (property && "ActOnPropertyImplDecl - property declaration missing"); 426 ObjCPropertyImplDecl *PIDecl = 427 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, 428 property, 429 (Synthesize ? 430 ObjCPropertyImplDecl::Synthesize 431 : ObjCPropertyImplDecl::Dynamic), 432 Ivar); 433 if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) { 434 getterMethod->createImplicitParams(Context, IDecl); 435 if (getLangOptions().CPlusPlus && Synthesize) { 436 // For Objective-C++, need to synthesize the AST for the IVAR object to be 437 // returned by the getter as it must conform to C++'s copy-return rules. 438 // FIXME. Eventually we want to do this for Objective-C as well. 439 ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); 440 DeclRefExpr *SelfExpr = 441 new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(), 442 SourceLocation()); 443 Expr *IvarRefExpr = 444 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 445 SelfExpr, true, true); 446 OwningExprResult Res = 447 PerformCopyInitialization(InitializedEntity::InitializeResult( 448 SourceLocation(), 449 getterMethod->getResultType()), 450 SourceLocation(), 451 Owned(IvarRefExpr)); 452 if (!Res.isInvalid()) { 453 Expr *ResExpr = Res.takeAs<Expr>(); 454 if (ResExpr) 455 ResExpr = MaybeCreateCXXExprWithTemporaries(ResExpr); 456 PIDecl->setGetterCXXConstructor(ResExpr); 457 } 458 } 459 } 460 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) { 461 setterMethod->createImplicitParams(Context, IDecl); 462 if (getLangOptions().CPlusPlus && Synthesize) { 463 // FIXME. Eventually we want to do this for Objective-C as well. 464 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); 465 DeclRefExpr *SelfExpr = 466 new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(), 467 SourceLocation()); 468 Expr *lhs = 469 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 470 SelfExpr, true, true); 471 ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); 472 ParmVarDecl *Param = (*P); 473 Expr *rhs = new (Context) DeclRefExpr(Param,Param->getType(), 474 SourceLocation()); 475 OwningExprResult Res = BuildBinOp(S, SourceLocation(), 476 BinaryOperator::Assign, lhs, rhs); 477 PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>()); 478 } 479 } 480 481 if (IC) { 482 if (Synthesize) 483 if (ObjCPropertyImplDecl *PPIDecl = 484 IC->FindPropertyImplIvarDecl(PropertyIvar)) { 485 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 486 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 487 << PropertyIvar; 488 Diag(PPIDecl->getLocation(), diag::note_previous_use); 489 } 490 491 if (ObjCPropertyImplDecl *PPIDecl 492 = IC->FindPropertyImplDecl(PropertyId)) { 493 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 494 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 495 return DeclPtrTy(); 496 } 497 IC->addPropertyImplementation(PIDecl); 498 } else { 499 if (Synthesize) 500 if (ObjCPropertyImplDecl *PPIDecl = 501 CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) { 502 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 503 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 504 << PropertyIvar; 505 Diag(PPIDecl->getLocation(), diag::note_previous_use); 506 } 507 508 if (ObjCPropertyImplDecl *PPIDecl = 509 CatImplClass->FindPropertyImplDecl(PropertyId)) { 510 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 511 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 512 return DeclPtrTy(); 513 } 514 CatImplClass->addPropertyImplementation(PIDecl); 515 } 516 517 return DeclPtrTy::make(PIDecl); 518} 519 520//===----------------------------------------------------------------------===// 521// Helper methods. 522//===----------------------------------------------------------------------===// 523 524/// DiagnosePropertyMismatch - Compares two properties for their 525/// attributes and types and warns on a variety of inconsistencies. 526/// 527void 528Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, 529 ObjCPropertyDecl *SuperProperty, 530 const IdentifierInfo *inheritedName) { 531 ObjCPropertyDecl::PropertyAttributeKind CAttr = 532 Property->getPropertyAttributes(); 533 ObjCPropertyDecl::PropertyAttributeKind SAttr = 534 SuperProperty->getPropertyAttributes(); 535 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) 536 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) 537 Diag(Property->getLocation(), diag::warn_readonly_property) 538 << Property->getDeclName() << inheritedName; 539 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) 540 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) 541 Diag(Property->getLocation(), diag::warn_property_attribute) 542 << Property->getDeclName() << "copy" << inheritedName; 543 else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain) 544 != (SAttr & ObjCPropertyDecl::OBJC_PR_retain)) 545 Diag(Property->getLocation(), diag::warn_property_attribute) 546 << Property->getDeclName() << "retain" << inheritedName; 547 548 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) 549 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) 550 Diag(Property->getLocation(), diag::warn_property_attribute) 551 << Property->getDeclName() << "atomic" << inheritedName; 552 if (Property->getSetterName() != SuperProperty->getSetterName()) 553 Diag(Property->getLocation(), diag::warn_property_attribute) 554 << Property->getDeclName() << "setter" << inheritedName; 555 if (Property->getGetterName() != SuperProperty->getGetterName()) 556 Diag(Property->getLocation(), diag::warn_property_attribute) 557 << Property->getDeclName() << "getter" << inheritedName; 558 559 QualType LHSType = 560 Context.getCanonicalType(SuperProperty->getType()); 561 QualType RHSType = 562 Context.getCanonicalType(Property->getType()); 563 564 if (!Context.typesAreCompatible(LHSType, RHSType)) { 565 // FIXME: Incorporate this test with typesAreCompatible. 566 if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType()) 567 if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false)) 568 return; 569 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) 570 << Property->getType() << SuperProperty->getType() << inheritedName; 571 } 572} 573 574bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, 575 ObjCMethodDecl *GetterMethod, 576 SourceLocation Loc) { 577 if (GetterMethod && 578 GetterMethod->getResultType() != property->getType()) { 579 AssignConvertType result = Incompatible; 580 if (property->getType()->isObjCObjectPointerType()) 581 result = CheckAssignmentConstraints(GetterMethod->getResultType(), 582 property->getType()); 583 if (result != Compatible) { 584 Diag(Loc, diag::warn_accessor_property_type_mismatch) 585 << property->getDeclName() 586 << GetterMethod->getSelector(); 587 Diag(GetterMethod->getLocation(), diag::note_declared_at); 588 return true; 589 } 590 } 591 return false; 592} 593 594/// ComparePropertiesInBaseAndSuper - This routine compares property 595/// declarations in base and its super class, if any, and issues 596/// diagnostics in a variety of inconsistant situations. 597/// 598void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) { 599 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); 600 if (!SDecl) 601 return; 602 // FIXME: O(N^2) 603 for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(), 604 E = SDecl->prop_end(); S != E; ++S) { 605 ObjCPropertyDecl *SuperPDecl = (*S); 606 // Does property in super class has declaration in current class? 607 for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(), 608 E = IDecl->prop_end(); I != E; ++I) { 609 ObjCPropertyDecl *PDecl = (*I); 610 if (SuperPDecl->getIdentifier() == PDecl->getIdentifier()) 611 DiagnosePropertyMismatch(PDecl, SuperPDecl, 612 SDecl->getIdentifier()); 613 } 614 } 615} 616 617/// MatchOneProtocolPropertiesInClass - This routine goes thru the list 618/// of properties declared in a protocol and compares their attribute against 619/// the same property declared in the class or category. 620void 621Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl, 622 ObjCProtocolDecl *PDecl) { 623 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 624 if (!IDecl) { 625 // Category 626 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 627 assert (CatDecl && "MatchOneProtocolPropertiesInClass"); 628 if (!CatDecl->IsClassExtension()) 629 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 630 E = PDecl->prop_end(); P != E; ++P) { 631 ObjCPropertyDecl *Pr = (*P); 632 ObjCCategoryDecl::prop_iterator CP, CE; 633 // Is this property already in category's list of properties? 634 for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP!=CE; ++CP) 635 if ((*CP)->getIdentifier() == Pr->getIdentifier()) 636 break; 637 if (CP != CE) 638 // Property protocol already exist in class. Diagnose any mismatch. 639 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier()); 640 } 641 return; 642 } 643 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 644 E = PDecl->prop_end(); P != E; ++P) { 645 ObjCPropertyDecl *Pr = (*P); 646 ObjCInterfaceDecl::prop_iterator CP, CE; 647 // Is this property already in class's list of properties? 648 for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP) 649 if ((*CP)->getIdentifier() == Pr->getIdentifier()) 650 break; 651 if (CP != CE) 652 // Property protocol already exist in class. Diagnose any mismatch. 653 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier()); 654 } 655} 656 657/// CompareProperties - This routine compares properties 658/// declared in 'ClassOrProtocol' objects (which can be a class or an 659/// inherited protocol with the list of properties for class/category 'CDecl' 660/// 661void Sema::CompareProperties(Decl *CDecl, 662 DeclPtrTy ClassOrProtocol) { 663 Decl *ClassDecl = ClassOrProtocol.getAs<Decl>(); 664 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 665 666 if (!IDecl) { 667 // Category 668 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 669 assert (CatDecl && "CompareProperties"); 670 if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 671 for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(), 672 E = MDecl->protocol_end(); P != E; ++P) 673 // Match properties of category with those of protocol (*P) 674 MatchOneProtocolPropertiesInClass(CatDecl, *P); 675 676 // Go thru the list of protocols for this category and recursively match 677 // their properties with those in the category. 678 for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(), 679 E = CatDecl->protocol_end(); P != E; ++P) 680 CompareProperties(CatDecl, DeclPtrTy::make(*P)); 681 } else { 682 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 683 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 684 E = MD->protocol_end(); P != E; ++P) 685 MatchOneProtocolPropertiesInClass(CatDecl, *P); 686 } 687 return; 688 } 689 690 if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { 691 for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(), 692 E = MDecl->protocol_end(); P != E; ++P) 693 // Match properties of class IDecl with those of protocol (*P). 694 MatchOneProtocolPropertiesInClass(IDecl, *P); 695 696 // Go thru the list of protocols for this class and recursively match 697 // their properties with those declared in the class. 698 for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(), 699 E = IDecl->protocol_end(); P != E; ++P) 700 CompareProperties(IDecl, DeclPtrTy::make(*P)); 701 } else { 702 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 703 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 704 E = MD->protocol_end(); P != E; ++P) 705 MatchOneProtocolPropertiesInClass(IDecl, *P); 706 } 707} 708 709/// isPropertyReadonly - Return true if property is readonly, by searching 710/// for the property in the class and in its categories and implementations 711/// 712bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl, 713 ObjCInterfaceDecl *IDecl) { 714 // by far the most common case. 715 if (!PDecl->isReadOnly()) 716 return false; 717 // Even if property is ready only, if interface has a user defined setter, 718 // it is not considered read only. 719 if (IDecl->getInstanceMethod(PDecl->getSetterName())) 720 return false; 721 722 // Main class has the property as 'readonly'. Must search 723 // through the category list to see if the property's 724 // attribute has been over-ridden to 'readwrite'. 725 for (ObjCCategoryDecl *Category = IDecl->getCategoryList(); 726 Category; Category = Category->getNextClassCategory()) { 727 // Even if property is ready only, if a category has a user defined setter, 728 // it is not considered read only. 729 if (Category->getInstanceMethod(PDecl->getSetterName())) 730 return false; 731 ObjCPropertyDecl *P = 732 Category->FindPropertyDeclaration(PDecl->getIdentifier()); 733 if (P && !P->isReadOnly()) 734 return false; 735 } 736 737 // Also, check for definition of a setter method in the implementation if 738 // all else failed. 739 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) { 740 if (ObjCImplementationDecl *IMD = 741 dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) { 742 if (IMD->getInstanceMethod(PDecl->getSetterName())) 743 return false; 744 } else if (ObjCCategoryImplDecl *CIMD = 745 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 746 if (CIMD->getInstanceMethod(PDecl->getSetterName())) 747 return false; 748 } 749 } 750 // Lastly, look through the implementation (if one is in scope). 751 if (ObjCImplementationDecl *ImpDecl = IDecl->getImplementation()) 752 if (ImpDecl->getInstanceMethod(PDecl->getSetterName())) 753 return false; 754 // If all fails, look at the super class. 755 if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass()) 756 return isPropertyReadonly(PDecl, SIDecl); 757 return true; 758} 759 760/// CollectImmediateProperties - This routine collects all properties in 761/// the class and its conforming protocols; but not those it its super class. 762void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, 763 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 764 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 765 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 766 E = IDecl->prop_end(); P != E; ++P) { 767 ObjCPropertyDecl *Prop = (*P); 768 PropMap[Prop->getIdentifier()] = Prop; 769 } 770 // scan through class's protocols. 771 for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(), 772 E = IDecl->protocol_end(); PI != E; ++PI) 773 // Exclude property for protocols which conform to class's super-class, 774 // as super-class has to implement the property. 775 if (!ProtocolConformsToSuperClass(IDecl, (*PI))) 776 CollectImmediateProperties((*PI), PropMap); 777 } 778 if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) { 779 if (!CATDecl->IsClassExtension()) 780 for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(), 781 E = CATDecl->prop_end(); P != E; ++P) { 782 ObjCPropertyDecl *Prop = (*P); 783 PropMap[Prop->getIdentifier()] = Prop; 784 } 785 // scan through class's protocols. 786 for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(), 787 E = CATDecl->protocol_end(); PI != E; ++PI) 788 CollectImmediateProperties((*PI), PropMap); 789 } 790 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 791 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 792 E = PDecl->prop_end(); P != E; ++P) { 793 ObjCPropertyDecl *Prop = (*P); 794 ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()]; 795 if (!PropEntry) 796 PropEntry = Prop; 797 } 798 // scan through protocol's protocols. 799 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 800 E = PDecl->protocol_end(); PI != E; ++PI) 801 CollectImmediateProperties((*PI), PropMap); 802 } 803} 804 805/// CollectClassPropertyImplementations - This routine collects list of 806/// properties to be implemented in the class. This includes, class's 807/// and its conforming protocols' properties. 808static void CollectClassPropertyImplementations(ObjCContainerDecl *CDecl, 809 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 810 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 811 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 812 E = IDecl->prop_end(); P != E; ++P) { 813 ObjCPropertyDecl *Prop = (*P); 814 PropMap[Prop->getIdentifier()] = Prop; 815 } 816 for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(), 817 E = IDecl->protocol_end(); PI != E; ++PI) 818 CollectClassPropertyImplementations((*PI), PropMap); 819 } 820 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 821 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 822 E = PDecl->prop_end(); P != E; ++P) { 823 ObjCPropertyDecl *Prop = (*P); 824 PropMap[Prop->getIdentifier()] = Prop; 825 } 826 // scan through protocol's protocols. 827 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 828 E = PDecl->protocol_end(); PI != E; ++PI) 829 CollectClassPropertyImplementations((*PI), PropMap); 830 } 831} 832 833/// CollectSuperClassPropertyImplementations - This routine collects list of 834/// properties to be implemented in super class(s) and also coming from their 835/// conforming protocols. 836static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, 837 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 838 if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) { 839 while (SDecl) { 840 CollectClassPropertyImplementations(SDecl, PropMap); 841 SDecl = SDecl->getSuperClass(); 842 } 843 } 844} 845 846/// ProtocolConformsToSuperClass - Returns true if class's given protocol 847/// conforms to one of its super class's protocols. 848bool Sema::ProtocolConformsToSuperClass(const ObjCInterfaceDecl *IDecl, 849 const ObjCProtocolDecl *PDecl) { 850 if (const ObjCInterfaceDecl *CDecl = IDecl->getSuperClass()) { 851 for (ObjCInterfaceDecl::protocol_iterator PI = CDecl->protocol_begin(), 852 E = CDecl->protocol_end(); PI != E; ++PI) { 853 if (ProtocolConformsToProtocol((*PI), PDecl)) 854 return true; 855 return ProtocolConformsToSuperClass(CDecl, PDecl); 856 } 857 } 858 return false; 859} 860 861bool Sema::ProtocolConformsToProtocol(const ObjCProtocolDecl *NestedProtocol, 862 const ObjCProtocolDecl *PDecl) { 863 if (PDecl->getIdentifier() == NestedProtocol->getIdentifier()) 864 return true; 865 // scan through protocol's protocols. 866 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 867 E = PDecl->protocol_end(); PI != E; ++PI) 868 if (ProtocolConformsToProtocol(NestedProtocol, (*PI))) 869 return true; 870 return false; 871} 872 873/// LookupPropertyDecl - Looks up a property in the current class and all 874/// its protocols. 875ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, 876 IdentifierInfo *II) { 877 if (const ObjCInterfaceDecl *IDecl = 878 dyn_cast<ObjCInterfaceDecl>(CDecl)) { 879 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 880 E = IDecl->prop_end(); P != E; ++P) { 881 ObjCPropertyDecl *Prop = (*P); 882 if (Prop->getIdentifier() == II) 883 return Prop; 884 } 885 // scan through class's protocols. 886 for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(), 887 E = IDecl->protocol_end(); PI != E; ++PI) { 888 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 889 if (Prop) 890 return Prop; 891 } 892 } 893 else if (const ObjCProtocolDecl *PDecl = 894 dyn_cast<ObjCProtocolDecl>(CDecl)) { 895 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 896 E = PDecl->prop_end(); P != E; ++P) { 897 ObjCPropertyDecl *Prop = (*P); 898 if (Prop->getIdentifier() == II) 899 return Prop; 900 } 901 // scan through protocol's protocols. 902 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 903 E = PDecl->protocol_end(); PI != E; ++PI) { 904 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 905 if (Prop) 906 return Prop; 907 } 908 } 909 return 0; 910} 911 912/// DefaultSynthesizeProperties - This routine default synthesizes all 913/// properties which must be synthesized in class's @implementation. 914void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl, 915 ObjCInterfaceDecl *IDecl) { 916 917 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 918 CollectClassPropertyImplementations(IDecl, PropMap); 919 if (PropMap.empty()) 920 return; 921 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; 922 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 923 924 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 925 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 926 ObjCPropertyDecl *Prop = P->second; 927 // If property to be implemented in the super class, ignore. 928 if (SuperPropMap[Prop->getIdentifier()]) 929 continue; 930 // Is there a matching propery synthesize/dynamic? 931 if (Prop->isInvalidDecl() || 932 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 933 IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) 934 continue; 935 ActOnPropertyImplDecl(S, IMPDecl->getLocation(), IMPDecl->getLocation(), 936 true, DeclPtrTy::make(IMPDecl), 937 Prop->getIdentifier(), Prop->getIdentifier()); 938 } 939} 940 941void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, 942 ObjCContainerDecl *CDecl, 943 const llvm::DenseSet<Selector>& InsMap) { 944 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 945 CollectImmediateProperties(CDecl, PropMap); 946 if (PropMap.empty()) 947 return; 948 949 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap; 950 for (ObjCImplDecl::propimpl_iterator 951 I = IMPDecl->propimpl_begin(), 952 EI = IMPDecl->propimpl_end(); I != EI; ++I) 953 PropImplMap.insert((*I)->getPropertyDecl()); 954 955 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 956 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 957 ObjCPropertyDecl *Prop = P->second; 958 // Is there a matching propery synthesize/dynamic? 959 if (Prop->isInvalidDecl() || 960 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 961 PropImplMap.count(Prop)) 962 continue; 963 if (!InsMap.count(Prop->getGetterName())) { 964 Diag(Prop->getLocation(), 965 isa<ObjCCategoryDecl>(CDecl) ? 966 diag::warn_setter_getter_impl_required_in_category : 967 diag::warn_setter_getter_impl_required) 968 << Prop->getDeclName() << Prop->getGetterName(); 969 Diag(IMPDecl->getLocation(), 970 diag::note_property_impl_required); 971 } 972 973 if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) { 974 Diag(Prop->getLocation(), 975 isa<ObjCCategoryDecl>(CDecl) ? 976 diag::warn_setter_getter_impl_required_in_category : 977 diag::warn_setter_getter_impl_required) 978 << Prop->getDeclName() << Prop->getSetterName(); 979 Diag(IMPDecl->getLocation(), 980 diag::note_property_impl_required); 981 } 982 } 983} 984 985void 986Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, 987 ObjCContainerDecl* IDecl) { 988 // Rules apply in non-GC mode only 989 if (getLangOptions().getGCMode() != LangOptions::NonGC) 990 return; 991 for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(), 992 E = IDecl->prop_end(); 993 I != E; ++I) { 994 ObjCPropertyDecl *Property = (*I); 995 unsigned Attributes = Property->getPropertyAttributes(); 996 // We only care about readwrite atomic property. 997 if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) || 998 !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite)) 999 continue; 1000 if (const ObjCPropertyImplDecl *PIDecl 1001 = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) { 1002 if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 1003 continue; 1004 ObjCMethodDecl *GetterMethod = 1005 IMPDecl->getInstanceMethod(Property->getGetterName()); 1006 ObjCMethodDecl *SetterMethod = 1007 IMPDecl->getInstanceMethod(Property->getSetterName()); 1008 if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { 1009 SourceLocation MethodLoc = 1010 (GetterMethod ? GetterMethod->getLocation() 1011 : SetterMethod->getLocation()); 1012 Diag(MethodLoc, diag::warn_atomic_property_rule) 1013 << Property->getIdentifier(); 1014 Diag(Property->getLocation(), diag::note_property_declare); 1015 } 1016 } 1017 } 1018} 1019 1020/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods 1021/// have the property type and issue diagnostics if they don't. 1022/// Also synthesize a getter/setter method if none exist (and update the 1023/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized 1024/// methods is the "right" thing to do. 1025void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, 1026 ObjCContainerDecl *CD) { 1027 ObjCMethodDecl *GetterMethod, *SetterMethod; 1028 1029 GetterMethod = CD->getInstanceMethod(property->getGetterName()); 1030 SetterMethod = CD->getInstanceMethod(property->getSetterName()); 1031 DiagnosePropertyAccessorMismatch(property, GetterMethod, 1032 property->getLocation()); 1033 1034 if (SetterMethod) { 1035 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1036 property->getPropertyAttributes(); 1037 if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) && 1038 Context.getCanonicalType(SetterMethod->getResultType()) != 1039 Context.VoidTy) 1040 Diag(SetterMethod->getLocation(), diag::err_setter_type_void); 1041 if (SetterMethod->param_size() != 1 || 1042 ((*SetterMethod->param_begin())->getType() != property->getType())) { 1043 Diag(property->getLocation(), 1044 diag::warn_accessor_property_type_mismatch) 1045 << property->getDeclName() 1046 << SetterMethod->getSelector(); 1047 Diag(SetterMethod->getLocation(), diag::note_declared_at); 1048 } 1049 } 1050 1051 // Synthesize getter/setter methods if none exist. 1052 // Find the default getter and if one not found, add one. 1053 // FIXME: The synthesized property we set here is misleading. We almost always 1054 // synthesize these methods unless the user explicitly provided prototypes 1055 // (which is odd, but allowed). Sema should be typechecking that the 1056 // declarations jive in that situation (which it is not currently). 1057 if (!GetterMethod) { 1058 // No instance method of same name as property getter name was found. 1059 // Declare a getter method and add it to the list of methods 1060 // for this class. 1061 GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(), 1062 property->getLocation(), property->getGetterName(), 1063 property->getType(), 0, CD, true, false, true, 1064 (property->getPropertyImplementation() == 1065 ObjCPropertyDecl::Optional) ? 1066 ObjCMethodDecl::Optional : 1067 ObjCMethodDecl::Required); 1068 CD->addDecl(GetterMethod); 1069 } else 1070 // A user declared getter will be synthesize when @synthesize of 1071 // the property with the same name is seen in the @implementation 1072 GetterMethod->setSynthesized(true); 1073 property->setGetterMethodDecl(GetterMethod); 1074 1075 // Skip setter if property is read-only. 1076 if (!property->isReadOnly()) { 1077 // Find the default setter and if one not found, add one. 1078 if (!SetterMethod) { 1079 // No instance method of same name as property setter name was found. 1080 // Declare a setter method and add it to the list of methods 1081 // for this class. 1082 SetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(), 1083 property->getLocation(), 1084 property->getSetterName(), 1085 Context.VoidTy, 0, CD, true, false, true, 1086 (property->getPropertyImplementation() == 1087 ObjCPropertyDecl::Optional) ? 1088 ObjCMethodDecl::Optional : 1089 ObjCMethodDecl::Required); 1090 // Invent the arguments for the setter. We don't bother making a 1091 // nice name for the argument. 1092 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, 1093 property->getLocation(), 1094 property->getIdentifier(), 1095 property->getType(), 1096 /*TInfo=*/0, 1097 VarDecl::None, 1098 VarDecl::None, 1099 0); 1100 SetterMethod->setMethodParams(Context, &Argument, 1, 1); 1101 CD->addDecl(SetterMethod); 1102 } else 1103 // A user declared setter will be synthesize when @synthesize of 1104 // the property with the same name is seen in the @implementation 1105 SetterMethod->setSynthesized(true); 1106 property->setSetterMethodDecl(SetterMethod); 1107 } 1108 // Add any synthesized methods to the global pool. This allows us to 1109 // handle the following, which is supported by GCC (and part of the design). 1110 // 1111 // @interface Foo 1112 // @property double bar; 1113 // @end 1114 // 1115 // void thisIsUnfortunate() { 1116 // id foo; 1117 // double bar = [foo bar]; 1118 // } 1119 // 1120 if (GetterMethod) 1121 AddInstanceMethodToGlobalPool(GetterMethod); 1122 if (SetterMethod) 1123 AddInstanceMethodToGlobalPool(SetterMethod); 1124} 1125 1126void Sema::CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy, 1127 SourceLocation Loc, 1128 unsigned &Attributes) { 1129 // FIXME: Improve the reported location. 1130 Decl *PDecl = PropertyPtrTy.getAs<Decl>(); 1131 if (!PDecl) 1132 return; 1133 1134 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 1135 QualType PropertyTy = PropertyDecl->getType(); 1136 1137 // readonly and readwrite/assign/retain/copy conflict. 1138 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1139 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 1140 ObjCDeclSpec::DQ_PR_assign | 1141 ObjCDeclSpec::DQ_PR_copy | 1142 ObjCDeclSpec::DQ_PR_retain))) { 1143 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ? 1144 "readwrite" : 1145 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 1146 "assign" : 1147 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 1148 "copy" : "retain"; 1149 1150 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 1151 diag::err_objc_property_attr_mutually_exclusive : 1152 diag::warn_objc_property_attr_mutually_exclusive) 1153 << "readonly" << which; 1154 } 1155 1156 // Check for copy or retain on non-object types. 1157 if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) && 1158 !PropertyTy->isObjCObjectPointerType() && 1159 !PropertyTy->isBlockPointerType() && 1160 !Context.isObjCNSObjectType(PropertyTy) && 1161 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { 1162 Diag(Loc, diag::err_objc_property_requires_object) 1163 << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain"); 1164 Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain); 1165 } 1166 1167 // Check for more than one of { assign, copy, retain }. 1168 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 1169 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1170 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1171 << "assign" << "copy"; 1172 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1173 } 1174 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1175 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1176 << "assign" << "retain"; 1177 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1178 } 1179 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1180 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1181 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1182 << "copy" << "retain"; 1183 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1184 } 1185 } 1186 1187 // Warn if user supplied no assignment attribute, property is 1188 // readwrite, and this is an object type. 1189 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | 1190 ObjCDeclSpec::DQ_PR_retain)) && 1191 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1192 PropertyTy->isObjCObjectPointerType()) { 1193 // Skip this warning in gc-only mode. 1194 if (getLangOptions().getGCMode() != LangOptions::GCOnly) 1195 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 1196 1197 // If non-gc code warn that this is likely inappropriate. 1198 if (getLangOptions().getGCMode() == LangOptions::NonGC) 1199 Diag(Loc, diag::warn_objc_property_default_assign_on_object); 1200 1201 // FIXME: Implement warning dependent on NSCopying being 1202 // implemented. See also: 1203 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496> 1204 // (please trim this list while you are at it). 1205 } 1206 1207 if (!(Attributes & ObjCDeclSpec::DQ_PR_copy) 1208 && getLangOptions().getGCMode() == LangOptions::GCOnly 1209 && PropertyTy->isBlockPointerType()) 1210 Diag(Loc, diag::warn_objc_property_copy_missing_on_block); 1211} 1212