SemaObjCProperty.cpp revision f85e193739c953358c865005855253af4f68a497
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 "clang/Sema/SemaInternal.h" 16#include "clang/Sema/Initialization.h" 17#include "clang/AST/DeclObjC.h" 18#include "clang/AST/ExprObjC.h" 19#include "llvm/ADT/DenseSet.h" 20 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// Grammar actions. 25//===----------------------------------------------------------------------===// 26 27/// Check the internal consistency of a property declaration. 28static void checkARCPropertyDecl(Sema &S, ObjCPropertyDecl *property) { 29 if (property->isInvalidDecl()) return; 30 31 ObjCPropertyDecl::PropertyAttributeKind propertyKind 32 = property->getPropertyAttributes(); 33 Qualifiers::ObjCLifetime propertyLifetime 34 = property->getType().getObjCLifetime(); 35 36 // Nothing to do if we don't have a lifetime. 37 if (propertyLifetime == Qualifiers::OCL_None) return; 38 39 Qualifiers::ObjCLifetime expectedLifetime; 40 unsigned selector; 41 42 // Strong properties should have either strong or no lifetime. 43 if (propertyKind & (ObjCPropertyDecl::OBJC_PR_retain | 44 ObjCPropertyDecl::OBJC_PR_strong | 45 ObjCPropertyDecl::OBJC_PR_copy)) { 46 expectedLifetime = Qualifiers::OCL_Strong; 47 selector = 0; 48 } else if (propertyKind & ObjCPropertyDecl::OBJC_PR_weak) { 49 expectedLifetime = Qualifiers::OCL_Weak; 50 selector = 1; 51 } else if (propertyKind & (ObjCPropertyDecl::OBJC_PR_assign | 52 ObjCPropertyDecl::OBJC_PR_unsafe_unretained) && 53 property->getType()->isObjCRetainableType()) { 54 expectedLifetime = Qualifiers::OCL_ExplicitNone; 55 selector = 2; 56 } else { 57 // We have a lifetime qualifier but no dominating property 58 // attribute. That's okay. 59 return; 60 } 61 62 if (propertyLifetime == expectedLifetime) return; 63 64 property->setInvalidDecl(); 65 S.Diag(property->getLocation(), 66 diag::err_arc_inconsistent_property_lifetime) 67 << property->getDeclName() 68 << selector 69 << propertyLifetime; 70} 71 72Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, 73 FieldDeclarator &FD, 74 ObjCDeclSpec &ODS, 75 Selector GetterSel, 76 Selector SetterSel, 77 Decl *ClassCategory, 78 bool *isOverridingProperty, 79 tok::ObjCKeywordKind MethodImplKind, 80 DeclContext *lexicalDC) { 81 unsigned Attributes = ODS.getPropertyAttributes(); 82 TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S); 83 QualType T = TSI->getType(); 84 if ((getLangOptions().getGCMode() != LangOptions::NonGC && 85 T.isObjCGCWeak()) || 86 (getLangOptions().ObjCAutoRefCount && 87 T.getObjCLifetime() == Qualifiers::OCL_Weak)) 88 Attributes |= ObjCDeclSpec::DQ_PR_weak; 89 90 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) || 91 // default is readwrite! 92 !(Attributes & ObjCDeclSpec::DQ_PR_readonly)); 93 // property is defaulted to 'assign' if it is readwrite and is 94 // not retain or copy 95 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) || 96 (isReadWrite && 97 !(Attributes & ObjCDeclSpec::DQ_PR_retain) && 98 !(Attributes & ObjCDeclSpec::DQ_PR_strong) && 99 !(Attributes & ObjCDeclSpec::DQ_PR_copy) && 100 !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) && 101 !(Attributes & ObjCDeclSpec::DQ_PR_weak))); 102 103 // Proceed with constructing the ObjCPropertDecls. 104 ObjCContainerDecl *ClassDecl = 105 cast<ObjCContainerDecl>(ClassCategory); 106 107 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) 108 if (CDecl->IsClassExtension()) { 109 Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc, 110 FD, GetterSel, SetterSel, 111 isAssign, isReadWrite, 112 Attributes, 113 isOverridingProperty, TSI, 114 MethodImplKind); 115 if (Res) { 116 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); 117 if (getLangOptions().ObjCAutoRefCount) 118 checkARCPropertyDecl(*this, cast<ObjCPropertyDecl>(Res)); 119 } 120 return Res; 121 } 122 123 ObjCPropertyDecl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, FD, 124 GetterSel, SetterSel, 125 isAssign, isReadWrite, 126 Attributes, TSI, MethodImplKind); 127 if (lexicalDC) 128 Res->setLexicalDeclContext(lexicalDC); 129 130 // Validate the attributes on the @property. 131 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); 132 133 if (getLangOptions().ObjCAutoRefCount) 134 checkARCPropertyDecl(*this, Res); 135 136 return Res; 137} 138 139Decl * 140Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl, 141 SourceLocation AtLoc, FieldDeclarator &FD, 142 Selector GetterSel, Selector SetterSel, 143 const bool isAssign, 144 const bool isReadWrite, 145 const unsigned Attributes, 146 bool *isOverridingProperty, 147 TypeSourceInfo *T, 148 tok::ObjCKeywordKind MethodImplKind) { 149 150 // Diagnose if this property is already in continuation class. 151 DeclContext *DC = cast<DeclContext>(CDecl); 152 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 153 ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface(); 154 155 if (CCPrimary) 156 // Check for duplicate declaration of this property in current and 157 // other class extensions. 158 for (const ObjCCategoryDecl *ClsExtDecl = 159 CCPrimary->getFirstClassExtension(); 160 ClsExtDecl; ClsExtDecl = ClsExtDecl->getNextClassExtension()) { 161 if (ObjCPropertyDecl *prevDecl = 162 ObjCPropertyDecl::findPropertyDecl(ClsExtDecl, PropertyId)) { 163 Diag(AtLoc, diag::err_duplicate_property); 164 Diag(prevDecl->getLocation(), diag::note_property_declare); 165 return 0; 166 } 167 } 168 169 // Create a new ObjCPropertyDecl with the DeclContext being 170 // the class extension. 171 // FIXME. We should really be using CreatePropertyDecl for this. 172 ObjCPropertyDecl *PDecl = 173 ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(), 174 PropertyId, AtLoc, T); 175 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 176 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 177 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 178 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 179 // Set setter/getter selector name. Needed later. 180 PDecl->setGetterName(GetterSel); 181 PDecl->setSetterName(SetterSel); 182 DC->addDecl(PDecl); 183 184 // We need to look in the @interface to see if the @property was 185 // already declared. 186 if (!CCPrimary) { 187 Diag(CDecl->getLocation(), diag::err_continuation_class); 188 *isOverridingProperty = true; 189 return 0; 190 } 191 192 // Find the property in continuation class's primary class only. 193 ObjCPropertyDecl *PIDecl = 194 CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId); 195 196 if (!PIDecl) { 197 // No matching property found in the primary class. Just fall thru 198 // and add property to continuation class's primary class. 199 ObjCPropertyDecl *PDecl = 200 CreatePropertyDecl(S, CCPrimary, AtLoc, 201 FD, GetterSel, SetterSel, isAssign, isReadWrite, 202 Attributes, T, MethodImplKind, DC); 203 // Mark written attribute as having no attribute because 204 // this is not a user-written property declaration in primary 205 // class. 206 PDecl->setPropertyAttributesAsWritten(ObjCPropertyDecl::OBJC_PR_noattr); 207 208 // A case of continuation class adding a new property in the class. This 209 // is not what it was meant for. However, gcc supports it and so should we. 210 // Make sure setter/getters are declared here. 211 ProcessPropertyDecl(PDecl, CCPrimary, /* redeclaredProperty = */ 0, 212 /* lexicalDC = */ CDecl); 213 return PDecl; 214 } 215 216 // The property 'PIDecl's readonly attribute will be over-ridden 217 // with continuation class's readwrite property attribute! 218 unsigned PIkind = PIDecl->getPropertyAttributesAsWritten(); 219 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { 220 unsigned retainCopyNonatomic = 221 (ObjCPropertyDecl::OBJC_PR_retain | 222 ObjCPropertyDecl::OBJC_PR_strong | 223 ObjCPropertyDecl::OBJC_PR_copy | 224 ObjCPropertyDecl::OBJC_PR_nonatomic); 225 if ((Attributes & retainCopyNonatomic) != 226 (PIkind & retainCopyNonatomic)) { 227 Diag(AtLoc, diag::warn_property_attr_mismatch); 228 Diag(PIDecl->getLocation(), diag::note_property_declare); 229 } 230 DeclContext *DC = cast<DeclContext>(CCPrimary); 231 if (!ObjCPropertyDecl::findPropertyDecl(DC, 232 PIDecl->getDeclName().getAsIdentifierInfo())) { 233 // Protocol is not in the primary class. Must build one for it. 234 ObjCDeclSpec ProtocolPropertyODS; 235 // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind 236 // and ObjCPropertyDecl::PropertyAttributeKind have identical 237 // values. Should consolidate both into one enum type. 238 ProtocolPropertyODS. 239 setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind) 240 PIkind); 241 242 Decl *ProtocolPtrTy = 243 ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS, 244 PIDecl->getGetterName(), 245 PIDecl->getSetterName(), 246 CCPrimary, isOverridingProperty, 247 MethodImplKind, 248 /* lexicalDC = */ CDecl); 249 PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy); 250 } 251 PIDecl->makeitReadWriteAttribute(); 252 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 253 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 254 if (Attributes & ObjCDeclSpec::DQ_PR_strong) 255 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 256 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 257 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 258 PIDecl->setSetterName(SetterSel); 259 } else { 260 // Tailor the diagnostics for the common case where a readwrite 261 // property is declared both in the @interface and the continuation. 262 // This is a common error where the user often intended the original 263 // declaration to be readonly. 264 unsigned diag = 265 (Attributes & ObjCDeclSpec::DQ_PR_readwrite) && 266 (PIkind & ObjCPropertyDecl::OBJC_PR_readwrite) 267 ? diag::err_use_continuation_class_redeclaration_readwrite 268 : diag::err_use_continuation_class; 269 Diag(AtLoc, diag) 270 << CCPrimary->getDeclName(); 271 Diag(PIDecl->getLocation(), diag::note_property_declare); 272 } 273 *isOverridingProperty = true; 274 // Make sure setter decl is synthesized, and added to primary class's list. 275 ProcessPropertyDecl(PIDecl, CCPrimary, PDecl, CDecl); 276 return 0; 277} 278 279ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, 280 ObjCContainerDecl *CDecl, 281 SourceLocation AtLoc, 282 FieldDeclarator &FD, 283 Selector GetterSel, 284 Selector SetterSel, 285 const bool isAssign, 286 const bool isReadWrite, 287 const unsigned Attributes, 288 TypeSourceInfo *TInfo, 289 tok::ObjCKeywordKind MethodImplKind, 290 DeclContext *lexicalDC){ 291 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 292 QualType T = TInfo->getType(); 293 294 // Issue a warning if property is 'assign' as default and its object, which is 295 // gc'able conforms to NSCopying protocol 296 if (getLangOptions().getGCMode() != LangOptions::NonGC && 297 isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign)) 298 if (const ObjCObjectPointerType *ObjPtrTy = 299 T->getAs<ObjCObjectPointerType>()) { 300 ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface(); 301 if (IDecl) 302 if (ObjCProtocolDecl* PNSCopying = 303 LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc)) 304 if (IDecl->ClassImplementsProtocol(PNSCopying, true)) 305 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId; 306 } 307 if (T->isObjCObjectType()) 308 Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object); 309 310 DeclContext *DC = cast<DeclContext>(CDecl); 311 ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC, 312 FD.D.getIdentifierLoc(), 313 PropertyId, AtLoc, TInfo); 314 315 if (ObjCPropertyDecl *prevDecl = 316 ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) { 317 Diag(PDecl->getLocation(), diag::err_duplicate_property); 318 Diag(prevDecl->getLocation(), diag::note_property_declare); 319 PDecl->setInvalidDecl(); 320 } 321 else { 322 DC->addDecl(PDecl); 323 if (lexicalDC) 324 PDecl->setLexicalDeclContext(lexicalDC); 325 } 326 327 if (T->isArrayType() || T->isFunctionType()) { 328 Diag(AtLoc, diag::err_property_type) << T; 329 PDecl->setInvalidDecl(); 330 } 331 332 ProcessDeclAttributes(S, PDecl, FD.D); 333 334 // Regardless of setter/getter attribute, we save the default getter/setter 335 // selector names in anticipation of declaration of setter/getter methods. 336 PDecl->setGetterName(GetterSel); 337 PDecl->setSetterName(SetterSel); 338 339 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 340 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 341 342 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 343 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter); 344 345 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 346 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter); 347 348 if (isReadWrite) 349 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 350 351 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 352 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 353 354 if (Attributes & ObjCDeclSpec::DQ_PR_strong) 355 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 356 357 if (Attributes & ObjCDeclSpec::DQ_PR_weak) 358 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak); 359 360 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 361 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 362 363 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) 364 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained); 365 366 if (isAssign) 367 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 368 369 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 370 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); 371 else if (Attributes & ObjCDeclSpec::DQ_PR_atomic) 372 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic); 373 374 // FIXME: Why do PropertyAttributesAsWritten get set from PropertyAttributes, 375 // shouldn't PropertyAttributesAsWritten get set *only* through the attributes 376 // of the ObjCDeclSpec ? 377 PDecl->setPropertyAttributesAsWritten(PDecl->getPropertyAttributes()); 378 379 // 'unsafe_unretained' is alias for 'assign'. 380 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) 381 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 382 if (isAssign) 383 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained); 384 385 if (MethodImplKind == tok::objc_required) 386 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required); 387 else if (MethodImplKind == tok::objc_optional) 388 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional); 389 390 return PDecl; 391} 392 393static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc, 394 ObjCPropertyDecl *property, 395 ObjCIvarDecl *ivar) { 396 if (property->isInvalidDecl() || ivar->isInvalidDecl()) return; 397 398 QualType propertyType = property->getType(); 399 Qualifiers::ObjCLifetime propertyLifetime = propertyType.getObjCLifetime(); 400 ObjCPropertyDecl::PropertyAttributeKind propertyKind 401 = property->getPropertyAttributes(); 402 403 QualType ivarType = ivar->getType(); 404 Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime(); 405 406 // Case 1: strong properties. 407 if (propertyLifetime == Qualifiers::OCL_Strong || 408 (propertyKind & (ObjCPropertyDecl::OBJC_PR_retain | 409 ObjCPropertyDecl::OBJC_PR_strong | 410 ObjCPropertyDecl::OBJC_PR_copy))) { 411 switch (ivarLifetime) { 412 case Qualifiers::OCL_Strong: 413 // Okay. 414 return; 415 416 case Qualifiers::OCL_None: 417 case Qualifiers::OCL_Autoreleasing: 418 // These aren't valid lifetimes for object ivars; don't diagnose twice. 419 return; 420 421 case Qualifiers::OCL_ExplicitNone: 422 case Qualifiers::OCL_Weak: 423 S.Diag(propertyImplLoc, diag::err_arc_strong_property_lifetime) 424 << property->getDeclName() 425 << ivar->getDeclName() 426 << ivarLifetime; 427 break; 428 } 429 430 // Case 2: weak properties. 431 } else if (propertyLifetime == Qualifiers::OCL_Weak || 432 (propertyKind & ObjCPropertyDecl::OBJC_PR_weak)) { 433 switch (ivarLifetime) { 434 case Qualifiers::OCL_Weak: 435 // Okay. 436 return; 437 438 case Qualifiers::OCL_None: 439 case Qualifiers::OCL_Autoreleasing: 440 // These aren't valid lifetimes for object ivars; don't diagnose twice. 441 return; 442 443 case Qualifiers::OCL_ExplicitNone: 444 case Qualifiers::OCL_Strong: 445 S.Diag(propertyImplLoc, diag::error_weak_property) 446 << property->getDeclName() 447 << ivar->getDeclName(); 448 break; 449 } 450 451 // Case 3: assign properties. 452 } else if ((propertyKind & ObjCPropertyDecl::OBJC_PR_assign) && 453 propertyType->isObjCRetainableType()) { 454 switch (ivarLifetime) { 455 case Qualifiers::OCL_ExplicitNone: 456 // Okay. 457 return; 458 459 case Qualifiers::OCL_None: 460 case Qualifiers::OCL_Autoreleasing: 461 // These aren't valid lifetimes for object ivars; don't diagnose twice. 462 return; 463 464 case Qualifiers::OCL_Weak: 465 case Qualifiers::OCL_Strong: 466 S.Diag(propertyImplLoc, diag::err_arc_assign_property_lifetime) 467 << property->getDeclName() 468 << ivar->getDeclName(); 469 break; 470 } 471 472 // Any other property should be ignored. 473 } else { 474 return; 475 } 476 477 S.Diag(property->getLocation(), diag::note_property_declare); 478} 479 480 481/// ActOnPropertyImplDecl - This routine performs semantic checks and 482/// builds the AST node for a property implementation declaration; declared 483/// as @synthesize or @dynamic. 484/// 485Decl *Sema::ActOnPropertyImplDecl(Scope *S, 486 SourceLocation AtLoc, 487 SourceLocation PropertyLoc, 488 bool Synthesize, 489 Decl *ClassCatImpDecl, 490 IdentifierInfo *PropertyId, 491 IdentifierInfo *PropertyIvar, 492 SourceLocation PropertyIvarLoc) { 493 ObjCContainerDecl *ClassImpDecl = 494 cast_or_null<ObjCContainerDecl>(ClassCatImpDecl); 495 // Make sure we have a context for the property implementation declaration. 496 if (!ClassImpDecl) { 497 Diag(AtLoc, diag::error_missing_property_context); 498 return 0; 499 } 500 ObjCPropertyDecl *property = 0; 501 ObjCInterfaceDecl* IDecl = 0; 502 // Find the class or category class where this property must have 503 // a declaration. 504 ObjCImplementationDecl *IC = 0; 505 ObjCCategoryImplDecl* CatImplClass = 0; 506 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) { 507 IDecl = IC->getClassInterface(); 508 // We always synthesize an interface for an implementation 509 // without an interface decl. So, IDecl is always non-zero. 510 assert(IDecl && 511 "ActOnPropertyImplDecl - @implementation without @interface"); 512 513 // Look for this property declaration in the @implementation's @interface 514 property = IDecl->FindPropertyDeclaration(PropertyId); 515 if (!property) { 516 Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName(); 517 return 0; 518 } 519 unsigned PIkind = property->getPropertyAttributesAsWritten(); 520 if ((PIkind & (ObjCPropertyDecl::OBJC_PR_atomic | 521 ObjCPropertyDecl::OBJC_PR_nonatomic) ) == 0) { 522 if (AtLoc.isValid()) 523 Diag(AtLoc, diag::warn_implicit_atomic_property); 524 else 525 Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property); 526 Diag(property->getLocation(), diag::note_property_declare); 527 } 528 529 if (const ObjCCategoryDecl *CD = 530 dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) { 531 if (!CD->IsClassExtension()) { 532 Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName(); 533 Diag(property->getLocation(), diag::note_property_declare); 534 return 0; 535 } 536 } 537 } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) { 538 if (Synthesize) { 539 Diag(AtLoc, diag::error_synthesize_category_decl); 540 return 0; 541 } 542 IDecl = CatImplClass->getClassInterface(); 543 if (!IDecl) { 544 Diag(AtLoc, diag::error_missing_property_interface); 545 return 0; 546 } 547 ObjCCategoryDecl *Category = 548 IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier()); 549 550 // If category for this implementation not found, it is an error which 551 // has already been reported eralier. 552 if (!Category) 553 return 0; 554 // Look for this property declaration in @implementation's category 555 property = Category->FindPropertyDeclaration(PropertyId); 556 if (!property) { 557 Diag(PropertyLoc, diag::error_bad_category_property_decl) 558 << Category->getDeclName(); 559 return 0; 560 } 561 } else { 562 Diag(AtLoc, diag::error_bad_property_context); 563 return 0; 564 } 565 ObjCIvarDecl *Ivar = 0; 566 // Check that we have a valid, previously declared ivar for @synthesize 567 if (Synthesize) { 568 // @synthesize 569 if (!PropertyIvar) 570 PropertyIvar = PropertyId; 571 ObjCPropertyDecl::PropertyAttributeKind kind 572 = property->getPropertyAttributes(); 573 QualType PropType = Context.getCanonicalType(property->getType()); 574 QualType PropertyIvarType = PropType; 575 if (PropType->isReferenceType()) 576 PropertyIvarType = cast<ReferenceType>(PropType)->getPointeeType(); 577 // Check that this is a previously declared 'ivar' in 'IDecl' interface 578 ObjCInterfaceDecl *ClassDeclared; 579 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared); 580 if (!Ivar) { 581 // In ARC, give the ivar a lifetime qualifier based on its 582 // property attributes. 583 if (getLangOptions().ObjCAutoRefCount && 584 !PropertyIvarType.getObjCLifetime()) { 585 586 // retain/copy have retaining lifetime. 587 if (kind & (ObjCPropertyDecl::OBJC_PR_retain | 588 ObjCPropertyDecl::OBJC_PR_strong | 589 ObjCPropertyDecl::OBJC_PR_copy)) { 590 Qualifiers qs; 591 qs.addObjCLifetime(Qualifiers::OCL_Strong); 592 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs); 593 } 594 else if (kind & ObjCPropertyDecl::OBJC_PR_weak) { 595 if (getLangOptions().ObjCNoAutoRefCountRuntime) { 596 Diag(PropertyLoc, diag::err_arc_weak_no_runtime); 597 Diag(property->getLocation(), diag::note_property_declare); 598 } 599 Qualifiers qs; 600 qs.addObjCLifetime(Qualifiers::OCL_Weak); 601 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs); 602 } 603 else if (kind & ObjCPropertyDecl::OBJC_PR_assign && 604 PropertyIvarType->isObjCRetainableType()) { 605 // assume that an 'assign' property synthesizes __unsafe_unretained 606 // ivar 607 Qualifiers qs; 608 qs.addObjCLifetime(Qualifiers::OCL_ExplicitNone); 609 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs); 610 } 611 } 612 613 if (kind & ObjCPropertyDecl::OBJC_PR_weak && 614 !getLangOptions().ObjCAutoRefCount && 615 getLangOptions().getGCMode() == LangOptions::NonGC) { 616 Diag(PropertyLoc, diag::error_synthesize_weak_non_arc_or_gc); 617 Diag(property->getLocation(), diag::note_property_declare); 618 } 619 620 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, 621 PropertyLoc, PropertyLoc, PropertyIvar, 622 PropertyIvarType, /*Dinfo=*/0, 623 ObjCIvarDecl::Private, 624 (Expr *)0, true); 625 ClassImpDecl->addDecl(Ivar); 626 IDecl->makeDeclVisibleInContext(Ivar, false); 627 property->setPropertyIvarDecl(Ivar); 628 629 if (!getLangOptions().ObjCNonFragileABI) 630 Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId; 631 // Note! I deliberately want it to fall thru so, we have a 632 // a property implementation and to avoid future warnings. 633 } else if (getLangOptions().ObjCNonFragileABI && 634 ClassDeclared != IDecl) { 635 Diag(PropertyLoc, diag::error_ivar_in_superclass_use) 636 << property->getDeclName() << Ivar->getDeclName() 637 << ClassDeclared->getDeclName(); 638 Diag(Ivar->getLocation(), diag::note_previous_access_declaration) 639 << Ivar << Ivar->getName(); 640 // Note! I deliberately want it to fall thru so more errors are caught. 641 } 642 QualType IvarType = Context.getCanonicalType(Ivar->getType()); 643 644 // Check that type of property and its ivar are type compatible. 645 if (PropertyIvarType != IvarType) { 646 bool compat = false; 647 if (isa<ObjCObjectPointerType>(PropertyIvarType) 648 && isa<ObjCObjectPointerType>(IvarType)) 649 compat = 650 Context.canAssignObjCInterfaces( 651 PropertyIvarType->getAs<ObjCObjectPointerType>(), 652 IvarType->getAs<ObjCObjectPointerType>()); 653 else { 654 SourceLocation Loc = PropertyIvarLoc; 655 if (Loc.isInvalid()) 656 Loc = PropertyLoc; 657 compat = (CheckAssignmentConstraints(Loc, PropertyIvarType, IvarType) 658 == Compatible); 659 } 660 if (!compat) { 661 Diag(PropertyLoc, diag::error_property_ivar_type) 662 << property->getDeclName() << PropType 663 << Ivar->getDeclName() << IvarType; 664 Diag(Ivar->getLocation(), diag::note_ivar_decl); 665 // Note! I deliberately want it to fall thru so, we have a 666 // a property implementation and to avoid future warnings. 667 } 668 669 // FIXME! Rules for properties are somewhat different that those 670 // for assignments. Use a new routine to consolidate all cases; 671 // specifically for property redeclarations as well as for ivars. 672 QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType(); 673 QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType(); 674 if (lhsType != rhsType && 675 lhsType->isArithmeticType()) { 676 Diag(PropertyLoc, diag::error_property_ivar_type) 677 << property->getDeclName() << PropType 678 << Ivar->getDeclName() << IvarType; 679 Diag(Ivar->getLocation(), diag::note_ivar_decl); 680 // Fall thru - see previous comment 681 } 682 // __weak is explicit. So it works on Canonical type. 683 if ((PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() && 684 getLangOptions().getGCMode() != LangOptions::NonGC)) { 685 Diag(PropertyLoc, diag::error_weak_property) 686 << property->getDeclName() << Ivar->getDeclName(); 687 // Fall thru - see previous comment 688 } 689 // Fall thru - see previous comment 690 if ((property->getType()->isObjCObjectPointerType() || 691 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() && 692 getLangOptions().getGCMode() != LangOptions::NonGC) { 693 Diag(PropertyLoc, diag::error_strong_property) 694 << property->getDeclName() << Ivar->getDeclName(); 695 // Fall thru - see previous comment 696 } 697 } 698 if (getLangOptions().ObjCAutoRefCount) 699 checkARCPropertyImpl(*this, PropertyLoc, property, Ivar); 700 } else if (PropertyIvar) 701 // @dynamic 702 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl); 703 704 assert (property && "ActOnPropertyImplDecl - property declaration missing"); 705 ObjCPropertyImplDecl *PIDecl = 706 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, 707 property, 708 (Synthesize ? 709 ObjCPropertyImplDecl::Synthesize 710 : ObjCPropertyImplDecl::Dynamic), 711 Ivar, PropertyIvarLoc); 712 if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) { 713 getterMethod->createImplicitParams(Context, IDecl); 714 if (getLangOptions().CPlusPlus && Synthesize && 715 Ivar->getType()->isRecordType()) { 716 // For Objective-C++, need to synthesize the AST for the IVAR object to be 717 // returned by the getter as it must conform to C++'s copy-return rules. 718 // FIXME. Eventually we want to do this for Objective-C as well. 719 ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); 720 DeclRefExpr *SelfExpr = 721 new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), 722 VK_RValue, SourceLocation()); 723 Expr *IvarRefExpr = 724 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 725 SelfExpr, true, true); 726 ExprResult Res = 727 PerformCopyInitialization(InitializedEntity::InitializeResult( 728 SourceLocation(), 729 getterMethod->getResultType(), 730 /*NRVO=*/false), 731 SourceLocation(), 732 Owned(IvarRefExpr)); 733 if (!Res.isInvalid()) { 734 Expr *ResExpr = Res.takeAs<Expr>(); 735 if (ResExpr) 736 ResExpr = MaybeCreateExprWithCleanups(ResExpr); 737 PIDecl->setGetterCXXConstructor(ResExpr); 738 } 739 } 740 } 741 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) { 742 setterMethod->createImplicitParams(Context, IDecl); 743 if (getLangOptions().CPlusPlus && Synthesize 744 && Ivar->getType()->isRecordType()) { 745 // FIXME. Eventually we want to do this for Objective-C as well. 746 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); 747 DeclRefExpr *SelfExpr = 748 new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), 749 VK_RValue, SourceLocation()); 750 Expr *lhs = 751 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 752 SelfExpr, true, true); 753 ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); 754 ParmVarDecl *Param = (*P); 755 QualType T = Param->getType(); 756 if (T->isReferenceType()) 757 T = T->getAs<ReferenceType>()->getPointeeType(); 758 Expr *rhs = new (Context) DeclRefExpr(Param, T, 759 VK_LValue, SourceLocation()); 760 ExprResult Res = BuildBinOp(S, lhs->getLocEnd(), 761 BO_Assign, lhs, rhs); 762 PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>()); 763 } 764 } 765 766 if (IC) { 767 if (Synthesize) 768 if (ObjCPropertyImplDecl *PPIDecl = 769 IC->FindPropertyImplIvarDecl(PropertyIvar)) { 770 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 771 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 772 << PropertyIvar; 773 Diag(PPIDecl->getLocation(), diag::note_previous_use); 774 } 775 776 if (ObjCPropertyImplDecl *PPIDecl 777 = IC->FindPropertyImplDecl(PropertyId)) { 778 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 779 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 780 return 0; 781 } 782 IC->addPropertyImplementation(PIDecl); 783 if (getLangOptions().ObjCDefaultSynthProperties && 784 getLangOptions().ObjCNonFragileABI2) { 785 // Diagnose if an ivar was lazily synthesdized due to a previous 786 // use and if 1) property is @dynamic or 2) property is synthesized 787 // but it requires an ivar of different name. 788 ObjCInterfaceDecl *ClassDeclared=0; 789 ObjCIvarDecl *Ivar = 0; 790 if (!Synthesize) 791 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 792 else { 793 if (PropertyIvar && PropertyIvar != PropertyId) 794 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 795 } 796 // Issue diagnostics only if Ivar belongs to current class. 797 if (Ivar && Ivar->getSynthesize() && 798 IC->getClassInterface() == ClassDeclared) { 799 Diag(Ivar->getLocation(), diag::err_undeclared_var_use) 800 << PropertyId; 801 Ivar->setInvalidDecl(); 802 } 803 } 804 } else { 805 if (Synthesize) 806 if (ObjCPropertyImplDecl *PPIDecl = 807 CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) { 808 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 809 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 810 << PropertyIvar; 811 Diag(PPIDecl->getLocation(), diag::note_previous_use); 812 } 813 814 if (ObjCPropertyImplDecl *PPIDecl = 815 CatImplClass->FindPropertyImplDecl(PropertyId)) { 816 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 817 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 818 return 0; 819 } 820 CatImplClass->addPropertyImplementation(PIDecl); 821 } 822 823 return PIDecl; 824} 825 826//===----------------------------------------------------------------------===// 827// Helper methods. 828//===----------------------------------------------------------------------===// 829 830/// DiagnosePropertyMismatch - Compares two properties for their 831/// attributes and types and warns on a variety of inconsistencies. 832/// 833void 834Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, 835 ObjCPropertyDecl *SuperProperty, 836 const IdentifierInfo *inheritedName) { 837 ObjCPropertyDecl::PropertyAttributeKind CAttr = 838 Property->getPropertyAttributes(); 839 ObjCPropertyDecl::PropertyAttributeKind SAttr = 840 SuperProperty->getPropertyAttributes(); 841 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) 842 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) 843 Diag(Property->getLocation(), diag::warn_readonly_property) 844 << Property->getDeclName() << inheritedName; 845 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) 846 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) 847 Diag(Property->getLocation(), diag::warn_property_attribute) 848 << Property->getDeclName() << "copy" << inheritedName; 849 else { 850 unsigned CAttrRetain = 851 (CAttr & 852 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 853 unsigned SAttrRetain = 854 (SAttr & 855 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 856 bool CStrong = (CAttrRetain != 0); 857 bool SStrong = (SAttrRetain != 0); 858 if (CStrong != SStrong) 859 Diag(Property->getLocation(), diag::warn_property_attribute) 860 << Property->getDeclName() << "retain (or strong)" << inheritedName; 861 } 862 863 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) 864 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) 865 Diag(Property->getLocation(), diag::warn_property_attribute) 866 << Property->getDeclName() << "atomic" << inheritedName; 867 if (Property->getSetterName() != SuperProperty->getSetterName()) 868 Diag(Property->getLocation(), diag::warn_property_attribute) 869 << Property->getDeclName() << "setter" << inheritedName; 870 if (Property->getGetterName() != SuperProperty->getGetterName()) 871 Diag(Property->getLocation(), diag::warn_property_attribute) 872 << Property->getDeclName() << "getter" << inheritedName; 873 874 QualType LHSType = 875 Context.getCanonicalType(SuperProperty->getType()); 876 QualType RHSType = 877 Context.getCanonicalType(Property->getType()); 878 879 if (!Context.typesAreCompatible(LHSType, RHSType)) { 880 // FIXME: Incorporate this test with typesAreCompatible. 881 if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType()) 882 if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false)) 883 return; 884 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) 885 << Property->getType() << SuperProperty->getType() << inheritedName; 886 } 887} 888 889bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, 890 ObjCMethodDecl *GetterMethod, 891 SourceLocation Loc) { 892 if (GetterMethod && 893 GetterMethod->getResultType() != property->getType()) { 894 AssignConvertType result = Incompatible; 895 if (property->getType()->isObjCObjectPointerType()) 896 result = CheckAssignmentConstraints(Loc, GetterMethod->getResultType(), 897 property->getType()); 898 if (result != Compatible) { 899 Diag(Loc, diag::warn_accessor_property_type_mismatch) 900 << property->getDeclName() 901 << GetterMethod->getSelector(); 902 Diag(GetterMethod->getLocation(), diag::note_declared_at); 903 return true; 904 } 905 } 906 return false; 907} 908 909/// ComparePropertiesInBaseAndSuper - This routine compares property 910/// declarations in base and its super class, if any, and issues 911/// diagnostics in a variety of inconsistent situations. 912/// 913void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) { 914 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); 915 if (!SDecl) 916 return; 917 // FIXME: O(N^2) 918 for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(), 919 E = SDecl->prop_end(); S != E; ++S) { 920 ObjCPropertyDecl *SuperPDecl = (*S); 921 // Does property in super class has declaration in current class? 922 for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(), 923 E = IDecl->prop_end(); I != E; ++I) { 924 ObjCPropertyDecl *PDecl = (*I); 925 if (SuperPDecl->getIdentifier() == PDecl->getIdentifier()) 926 DiagnosePropertyMismatch(PDecl, SuperPDecl, 927 SDecl->getIdentifier()); 928 } 929 } 930} 931 932/// MatchOneProtocolPropertiesInClass - This routine goes thru the list 933/// of properties declared in a protocol and compares their attribute against 934/// the same property declared in the class or category. 935void 936Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl, 937 ObjCProtocolDecl *PDecl) { 938 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 939 if (!IDecl) { 940 // Category 941 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 942 assert (CatDecl && "MatchOneProtocolPropertiesInClass"); 943 if (!CatDecl->IsClassExtension()) 944 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 945 E = PDecl->prop_end(); P != E; ++P) { 946 ObjCPropertyDecl *Pr = (*P); 947 ObjCCategoryDecl::prop_iterator CP, CE; 948 // Is this property already in category's list of properties? 949 for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP!=CE; ++CP) 950 if ((*CP)->getIdentifier() == Pr->getIdentifier()) 951 break; 952 if (CP != CE) 953 // Property protocol already exist in class. Diagnose any mismatch. 954 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier()); 955 } 956 return; 957 } 958 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 959 E = PDecl->prop_end(); P != E; ++P) { 960 ObjCPropertyDecl *Pr = (*P); 961 ObjCInterfaceDecl::prop_iterator CP, CE; 962 // Is this property already in class's list of properties? 963 for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP) 964 if ((*CP)->getIdentifier() == Pr->getIdentifier()) 965 break; 966 if (CP != CE) 967 // Property protocol already exist in class. Diagnose any mismatch. 968 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier()); 969 } 970} 971 972/// CompareProperties - This routine compares properties 973/// declared in 'ClassOrProtocol' objects (which can be a class or an 974/// inherited protocol with the list of properties for class/category 'CDecl' 975/// 976void Sema::CompareProperties(Decl *CDecl, Decl *ClassOrProtocol) { 977 Decl *ClassDecl = ClassOrProtocol; 978 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 979 980 if (!IDecl) { 981 // Category 982 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 983 assert (CatDecl && "CompareProperties"); 984 if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 985 for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(), 986 E = MDecl->protocol_end(); P != E; ++P) 987 // Match properties of category with those of protocol (*P) 988 MatchOneProtocolPropertiesInClass(CatDecl, *P); 989 990 // Go thru the list of protocols for this category and recursively match 991 // their properties with those in the category. 992 for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(), 993 E = CatDecl->protocol_end(); P != E; ++P) 994 CompareProperties(CatDecl, *P); 995 } else { 996 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 997 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 998 E = MD->protocol_end(); P != E; ++P) 999 MatchOneProtocolPropertiesInClass(CatDecl, *P); 1000 } 1001 return; 1002 } 1003 1004 if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { 1005 for (ObjCInterfaceDecl::all_protocol_iterator 1006 P = MDecl->all_referenced_protocol_begin(), 1007 E = MDecl->all_referenced_protocol_end(); P != E; ++P) 1008 // Match properties of class IDecl with those of protocol (*P). 1009 MatchOneProtocolPropertiesInClass(IDecl, *P); 1010 1011 // Go thru the list of protocols for this class and recursively match 1012 // their properties with those declared in the class. 1013 for (ObjCInterfaceDecl::all_protocol_iterator 1014 P = IDecl->all_referenced_protocol_begin(), 1015 E = IDecl->all_referenced_protocol_end(); P != E; ++P) 1016 CompareProperties(IDecl, *P); 1017 } else { 1018 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 1019 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 1020 E = MD->protocol_end(); P != E; ++P) 1021 MatchOneProtocolPropertiesInClass(IDecl, *P); 1022 } 1023} 1024 1025/// isPropertyReadonly - Return true if property is readonly, by searching 1026/// for the property in the class and in its categories and implementations 1027/// 1028bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl, 1029 ObjCInterfaceDecl *IDecl) { 1030 // by far the most common case. 1031 if (!PDecl->isReadOnly()) 1032 return false; 1033 // Even if property is ready only, if interface has a user defined setter, 1034 // it is not considered read only. 1035 if (IDecl->getInstanceMethod(PDecl->getSetterName())) 1036 return false; 1037 1038 // Main class has the property as 'readonly'. Must search 1039 // through the category list to see if the property's 1040 // attribute has been over-ridden to 'readwrite'. 1041 for (ObjCCategoryDecl *Category = IDecl->getCategoryList(); 1042 Category; Category = Category->getNextClassCategory()) { 1043 // Even if property is ready only, if a category has a user defined setter, 1044 // it is not considered read only. 1045 if (Category->getInstanceMethod(PDecl->getSetterName())) 1046 return false; 1047 ObjCPropertyDecl *P = 1048 Category->FindPropertyDeclaration(PDecl->getIdentifier()); 1049 if (P && !P->isReadOnly()) 1050 return false; 1051 } 1052 1053 // Also, check for definition of a setter method in the implementation if 1054 // all else failed. 1055 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) { 1056 if (ObjCImplementationDecl *IMD = 1057 dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) { 1058 if (IMD->getInstanceMethod(PDecl->getSetterName())) 1059 return false; 1060 } else if (ObjCCategoryImplDecl *CIMD = 1061 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 1062 if (CIMD->getInstanceMethod(PDecl->getSetterName())) 1063 return false; 1064 } 1065 } 1066 // Lastly, look through the implementation (if one is in scope). 1067 if (ObjCImplementationDecl *ImpDecl = IDecl->getImplementation()) 1068 if (ImpDecl->getInstanceMethod(PDecl->getSetterName())) 1069 return false; 1070 // If all fails, look at the super class. 1071 if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass()) 1072 return isPropertyReadonly(PDecl, SIDecl); 1073 return true; 1074} 1075 1076/// CollectImmediateProperties - This routine collects all properties in 1077/// the class and its conforming protocols; but not those it its super class. 1078void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, 1079 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap, 1080 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap) { 1081 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1082 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 1083 E = IDecl->prop_end(); P != E; ++P) { 1084 ObjCPropertyDecl *Prop = (*P); 1085 PropMap[Prop->getIdentifier()] = Prop; 1086 } 1087 // scan through class's protocols. 1088 for (ObjCInterfaceDecl::all_protocol_iterator 1089 PI = IDecl->all_referenced_protocol_begin(), 1090 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) 1091 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 1092 } 1093 if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) { 1094 if (!CATDecl->IsClassExtension()) 1095 for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(), 1096 E = CATDecl->prop_end(); P != E; ++P) { 1097 ObjCPropertyDecl *Prop = (*P); 1098 PropMap[Prop->getIdentifier()] = Prop; 1099 } 1100 // scan through class's protocols. 1101 for (ObjCCategoryDecl::protocol_iterator PI = CATDecl->protocol_begin(), 1102 E = CATDecl->protocol_end(); PI != E; ++PI) 1103 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 1104 } 1105 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 1106 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1107 E = PDecl->prop_end(); P != E; ++P) { 1108 ObjCPropertyDecl *Prop = (*P); 1109 ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()]; 1110 // Exclude property for protocols which conform to class's super-class, 1111 // as super-class has to implement the property. 1112 if (!PropertyFromSuper || PropertyFromSuper != Prop) { 1113 ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()]; 1114 if (!PropEntry) 1115 PropEntry = Prop; 1116 } 1117 } 1118 // scan through protocol's protocols. 1119 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 1120 E = PDecl->protocol_end(); PI != E; ++PI) 1121 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 1122 } 1123} 1124 1125/// CollectClassPropertyImplementations - This routine collects list of 1126/// properties to be implemented in the class. This includes, class's 1127/// and its conforming protocols' properties. 1128static void CollectClassPropertyImplementations(ObjCContainerDecl *CDecl, 1129 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 1130 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1131 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 1132 E = IDecl->prop_end(); P != E; ++P) { 1133 ObjCPropertyDecl *Prop = (*P); 1134 PropMap[Prop->getIdentifier()] = Prop; 1135 } 1136 for (ObjCInterfaceDecl::all_protocol_iterator 1137 PI = IDecl->all_referenced_protocol_begin(), 1138 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) 1139 CollectClassPropertyImplementations((*PI), PropMap); 1140 } 1141 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 1142 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1143 E = PDecl->prop_end(); P != E; ++P) { 1144 ObjCPropertyDecl *Prop = (*P); 1145 PropMap[Prop->getIdentifier()] = Prop; 1146 } 1147 // scan through protocol's protocols. 1148 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 1149 E = PDecl->protocol_end(); PI != E; ++PI) 1150 CollectClassPropertyImplementations((*PI), PropMap); 1151 } 1152} 1153 1154/// CollectSuperClassPropertyImplementations - This routine collects list of 1155/// properties to be implemented in super class(s) and also coming from their 1156/// conforming protocols. 1157static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, 1158 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 1159 if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) { 1160 while (SDecl) { 1161 CollectClassPropertyImplementations(SDecl, PropMap); 1162 SDecl = SDecl->getSuperClass(); 1163 } 1164 } 1165} 1166 1167/// LookupPropertyDecl - Looks up a property in the current class and all 1168/// its protocols. 1169ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, 1170 IdentifierInfo *II) { 1171 if (const ObjCInterfaceDecl *IDecl = 1172 dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1173 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 1174 E = IDecl->prop_end(); P != E; ++P) { 1175 ObjCPropertyDecl *Prop = (*P); 1176 if (Prop->getIdentifier() == II) 1177 return Prop; 1178 } 1179 // scan through class's protocols. 1180 for (ObjCInterfaceDecl::all_protocol_iterator 1181 PI = IDecl->all_referenced_protocol_begin(), 1182 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) { 1183 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 1184 if (Prop) 1185 return Prop; 1186 } 1187 } 1188 else if (const ObjCProtocolDecl *PDecl = 1189 dyn_cast<ObjCProtocolDecl>(CDecl)) { 1190 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1191 E = PDecl->prop_end(); P != E; ++P) { 1192 ObjCPropertyDecl *Prop = (*P); 1193 if (Prop->getIdentifier() == II) 1194 return Prop; 1195 } 1196 // scan through protocol's protocols. 1197 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 1198 E = PDecl->protocol_end(); PI != E; ++PI) { 1199 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 1200 if (Prop) 1201 return Prop; 1202 } 1203 } 1204 return 0; 1205} 1206 1207/// DefaultSynthesizeProperties - This routine default synthesizes all 1208/// properties which must be synthesized in class's @implementation. 1209void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl, 1210 ObjCInterfaceDecl *IDecl) { 1211 1212 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 1213 CollectClassPropertyImplementations(IDecl, PropMap); 1214 if (PropMap.empty()) 1215 return; 1216 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; 1217 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 1218 1219 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 1220 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1221 ObjCPropertyDecl *Prop = P->second; 1222 // If property to be implemented in the super class, ignore. 1223 if (SuperPropMap[Prop->getIdentifier()]) 1224 continue; 1225 // Is there a matching propery synthesize/dynamic? 1226 if (Prop->isInvalidDecl() || 1227 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 1228 IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) 1229 continue; 1230 // Property may have been synthesized by user. 1231 if (IMPDecl->FindPropertyImplDecl(Prop->getIdentifier())) 1232 continue; 1233 if (IMPDecl->getInstanceMethod(Prop->getGetterName())) { 1234 if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly) 1235 continue; 1236 if (IMPDecl->getInstanceMethod(Prop->getSetterName())) 1237 continue; 1238 } 1239 1240 1241 // We use invalid SourceLocations for the synthesized ivars since they 1242 // aren't really synthesized at a particular location; they just exist. 1243 // Saying that they are located at the @implementation isn't really going 1244 // to help users. 1245 ActOnPropertyImplDecl(S, SourceLocation(), SourceLocation(), 1246 true,IMPDecl, 1247 Prop->getIdentifier(), Prop->getIdentifier(), 1248 SourceLocation()); 1249 } 1250} 1251 1252void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, 1253 ObjCContainerDecl *CDecl, 1254 const llvm::DenseSet<Selector>& InsMap) { 1255 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; 1256 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) 1257 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 1258 1259 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 1260 CollectImmediateProperties(CDecl, PropMap, SuperPropMap); 1261 if (PropMap.empty()) 1262 return; 1263 1264 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap; 1265 for (ObjCImplDecl::propimpl_iterator 1266 I = IMPDecl->propimpl_begin(), 1267 EI = IMPDecl->propimpl_end(); I != EI; ++I) 1268 PropImplMap.insert((*I)->getPropertyDecl()); 1269 1270 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 1271 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1272 ObjCPropertyDecl *Prop = P->second; 1273 // Is there a matching propery synthesize/dynamic? 1274 if (Prop->isInvalidDecl() || 1275 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 1276 PropImplMap.count(Prop)) 1277 continue; 1278 if (!InsMap.count(Prop->getGetterName())) { 1279 Diag(Prop->getLocation(), 1280 isa<ObjCCategoryDecl>(CDecl) ? 1281 diag::warn_setter_getter_impl_required_in_category : 1282 diag::warn_setter_getter_impl_required) 1283 << Prop->getDeclName() << Prop->getGetterName(); 1284 Diag(IMPDecl->getLocation(), 1285 diag::note_property_impl_required); 1286 } 1287 1288 if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) { 1289 Diag(Prop->getLocation(), 1290 isa<ObjCCategoryDecl>(CDecl) ? 1291 diag::warn_setter_getter_impl_required_in_category : 1292 diag::warn_setter_getter_impl_required) 1293 << Prop->getDeclName() << Prop->getSetterName(); 1294 Diag(IMPDecl->getLocation(), 1295 diag::note_property_impl_required); 1296 } 1297 } 1298} 1299 1300void 1301Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, 1302 ObjCContainerDecl* IDecl) { 1303 // Rules apply in non-GC mode only 1304 if (getLangOptions().getGCMode() != LangOptions::NonGC) 1305 return; 1306 for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(), 1307 E = IDecl->prop_end(); 1308 I != E; ++I) { 1309 ObjCPropertyDecl *Property = (*I); 1310 ObjCMethodDecl *GetterMethod = 0; 1311 ObjCMethodDecl *SetterMethod = 0; 1312 bool LookedUpGetterSetter = false; 1313 1314 unsigned Attributes = Property->getPropertyAttributes(); 1315 unsigned AttributesAsWrittern = Property->getPropertyAttributesAsWritten(); 1316 1317 if (!(AttributesAsWrittern & ObjCPropertyDecl::OBJC_PR_atomic) && 1318 !(AttributesAsWrittern & ObjCPropertyDecl::OBJC_PR_nonatomic)) { 1319 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1320 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1321 LookedUpGetterSetter = true; 1322 if (GetterMethod) { 1323 Diag(GetterMethod->getLocation(), 1324 diag::warn_default_atomic_custom_getter_setter) 1325 << Property->getIdentifier() << 0; 1326 Diag(Property->getLocation(), diag::note_property_declare); 1327 } 1328 if (SetterMethod) { 1329 Diag(SetterMethod->getLocation(), 1330 diag::warn_default_atomic_custom_getter_setter) 1331 << Property->getIdentifier() << 1; 1332 Diag(Property->getLocation(), diag::note_property_declare); 1333 } 1334 } 1335 1336 // We only care about readwrite atomic property. 1337 if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) || 1338 !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite)) 1339 continue; 1340 if (const ObjCPropertyImplDecl *PIDecl 1341 = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) { 1342 if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 1343 continue; 1344 if (!LookedUpGetterSetter) { 1345 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1346 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1347 LookedUpGetterSetter = true; 1348 } 1349 if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { 1350 SourceLocation MethodLoc = 1351 (GetterMethod ? GetterMethod->getLocation() 1352 : SetterMethod->getLocation()); 1353 Diag(MethodLoc, diag::warn_atomic_property_rule) 1354 << Property->getIdentifier(); 1355 Diag(Property->getLocation(), diag::note_property_declare); 1356 } 1357 } 1358 } 1359} 1360 1361void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) { 1362 if (getLangOptions().getGCMode() == LangOptions::GCOnly) 1363 return; 1364 1365 for (ObjCImplementationDecl::propimpl_iterator 1366 i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) { 1367 ObjCPropertyImplDecl *PID = *i; 1368 if (PID->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) 1369 continue; 1370 1371 const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 1372 if (PD && !D->getInstanceMethod(PD->getGetterName())) { 1373 ObjCMethodDecl *method = PD->getGetterMethodDecl(); 1374 if (!method) 1375 continue; 1376 ObjCMethodFamily family = method->getMethodFamily(); 1377 if (family == OMF_alloc || family == OMF_copy || 1378 family == OMF_mutableCopy || family == OMF_new) { 1379 if (getLangOptions().ObjCAutoRefCount) 1380 Diag(PID->getLocation(), diag::err_ownin_getter_rule); 1381 else 1382 Diag(PID->getLocation(), diag::warn_ownin_getter_rule); 1383 Diag(PD->getLocation(), diag::note_property_declare); 1384 } 1385 } 1386 } 1387} 1388 1389/// AddPropertyAttrs - Propagates attributes from a property to the 1390/// implicitly-declared getter or setter for that property. 1391static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, 1392 ObjCPropertyDecl *Property) { 1393 // Should we just clone all attributes over? 1394 for (Decl::attr_iterator A = Property->attr_begin(), 1395 AEnd = Property->attr_end(); 1396 A != AEnd; ++A) { 1397 if (isa<DeprecatedAttr>(*A) || 1398 isa<UnavailableAttr>(*A) || 1399 isa<AvailabilityAttr>(*A)) 1400 PropertyMethod->addAttr((*A)->clone(S.Context)); 1401 } 1402} 1403 1404/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods 1405/// have the property type and issue diagnostics if they don't. 1406/// Also synthesize a getter/setter method if none exist (and update the 1407/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized 1408/// methods is the "right" thing to do. 1409void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, 1410 ObjCContainerDecl *CD, 1411 ObjCPropertyDecl *redeclaredProperty, 1412 ObjCContainerDecl *lexicalDC) { 1413 1414 ObjCMethodDecl *GetterMethod, *SetterMethod; 1415 1416 GetterMethod = CD->getInstanceMethod(property->getGetterName()); 1417 SetterMethod = CD->getInstanceMethod(property->getSetterName()); 1418 DiagnosePropertyAccessorMismatch(property, GetterMethod, 1419 property->getLocation()); 1420 1421 if (SetterMethod) { 1422 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1423 property->getPropertyAttributes(); 1424 if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) && 1425 Context.getCanonicalType(SetterMethod->getResultType()) != 1426 Context.VoidTy) 1427 Diag(SetterMethod->getLocation(), diag::err_setter_type_void); 1428 if (SetterMethod->param_size() != 1 || 1429 ((*SetterMethod->param_begin())->getType() != property->getType())) { 1430 Diag(property->getLocation(), 1431 diag::warn_accessor_property_type_mismatch) 1432 << property->getDeclName() 1433 << SetterMethod->getSelector(); 1434 Diag(SetterMethod->getLocation(), diag::note_declared_at); 1435 } 1436 } 1437 1438 // Synthesize getter/setter methods if none exist. 1439 // Find the default getter and if one not found, add one. 1440 // FIXME: The synthesized property we set here is misleading. We almost always 1441 // synthesize these methods unless the user explicitly provided prototypes 1442 // (which is odd, but allowed). Sema should be typechecking that the 1443 // declarations jive in that situation (which it is not currently). 1444 if (!GetterMethod) { 1445 // No instance method of same name as property getter name was found. 1446 // Declare a getter method and add it to the list of methods 1447 // for this class. 1448 SourceLocation Loc = redeclaredProperty ? 1449 redeclaredProperty->getLocation() : 1450 property->getLocation(); 1451 1452 GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc, 1453 property->getGetterName(), 1454 property->getType(), 0, CD, true, false, true, 1455 false, 1456 (property->getPropertyImplementation() == 1457 ObjCPropertyDecl::Optional) ? 1458 ObjCMethodDecl::Optional : 1459 ObjCMethodDecl::Required); 1460 CD->addDecl(GetterMethod); 1461 1462 AddPropertyAttrs(*this, GetterMethod, property); 1463 1464 // FIXME: Eventually this shouldn't be needed, as the lexical context 1465 // and the real context should be the same. 1466 if (lexicalDC) 1467 GetterMethod->setLexicalDeclContext(lexicalDC); 1468 } else 1469 // A user declared getter will be synthesize when @synthesize of 1470 // the property with the same name is seen in the @implementation 1471 GetterMethod->setSynthesized(true); 1472 property->setGetterMethodDecl(GetterMethod); 1473 1474 // Skip setter if property is read-only. 1475 if (!property->isReadOnly()) { 1476 // Find the default setter and if one not found, add one. 1477 if (!SetterMethod) { 1478 // No instance method of same name as property setter name was found. 1479 // Declare a setter method and add it to the list of methods 1480 // for this class. 1481 SourceLocation Loc = redeclaredProperty ? 1482 redeclaredProperty->getLocation() : 1483 property->getLocation(); 1484 1485 SetterMethod = 1486 ObjCMethodDecl::Create(Context, Loc, Loc, 1487 property->getSetterName(), Context.VoidTy, 0, 1488 CD, true, false, true, false, 1489 (property->getPropertyImplementation() == 1490 ObjCPropertyDecl::Optional) ? 1491 ObjCMethodDecl::Optional : 1492 ObjCMethodDecl::Required); 1493 1494 // Invent the arguments for the setter. We don't bother making a 1495 // nice name for the argument. 1496 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, 1497 Loc, Loc, 1498 property->getIdentifier(), 1499 property->getType().getUnqualifiedType(), 1500 /*TInfo=*/0, 1501 SC_None, 1502 SC_None, 1503 0); 1504 SetterMethod->setMethodParams(Context, &Argument, 1, 1); 1505 1506 AddPropertyAttrs(*this, SetterMethod, property); 1507 1508 CD->addDecl(SetterMethod); 1509 // FIXME: Eventually this shouldn't be needed, as the lexical context 1510 // and the real context should be the same. 1511 if (lexicalDC) 1512 SetterMethod->setLexicalDeclContext(lexicalDC); 1513 } else 1514 // A user declared setter will be synthesize when @synthesize of 1515 // the property with the same name is seen in the @implementation 1516 SetterMethod->setSynthesized(true); 1517 property->setSetterMethodDecl(SetterMethod); 1518 } 1519 // Add any synthesized methods to the global pool. This allows us to 1520 // handle the following, which is supported by GCC (and part of the design). 1521 // 1522 // @interface Foo 1523 // @property double bar; 1524 // @end 1525 // 1526 // void thisIsUnfortunate() { 1527 // id foo; 1528 // double bar = [foo bar]; 1529 // } 1530 // 1531 if (GetterMethod) 1532 AddInstanceMethodToGlobalPool(GetterMethod); 1533 if (SetterMethod) 1534 AddInstanceMethodToGlobalPool(SetterMethod); 1535} 1536 1537void Sema::CheckObjCPropertyAttributes(Decl *PDecl, 1538 SourceLocation Loc, 1539 unsigned &Attributes) { 1540 // FIXME: Improve the reported location. 1541 if (!PDecl || PDecl->isInvalidDecl()) 1542 return; 1543 1544 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 1545 QualType PropertyTy = PropertyDecl->getType(); 1546 1547 // readonly and readwrite/assign/retain/copy conflict. 1548 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1549 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 1550 ObjCDeclSpec::DQ_PR_assign | 1551 ObjCDeclSpec::DQ_PR_unsafe_unretained | 1552 ObjCDeclSpec::DQ_PR_copy | 1553 ObjCDeclSpec::DQ_PR_retain | 1554 ObjCDeclSpec::DQ_PR_strong))) { 1555 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ? 1556 "readwrite" : 1557 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 1558 "assign" : 1559 (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) ? 1560 "unsafe_unretained" : 1561 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 1562 "copy" : "retain"; 1563 1564 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 1565 diag::err_objc_property_attr_mutually_exclusive : 1566 diag::warn_objc_property_attr_mutually_exclusive) 1567 << "readonly" << which; 1568 } 1569 1570 // Check for copy or retain on non-object types. 1571 if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 1572 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) && 1573 !PropertyTy->isObjCRetainableType() && 1574 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { 1575 Diag(Loc, diag::err_objc_property_requires_object) 1576 << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" : 1577 Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)"); 1578 Attributes &= ~(ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 1579 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong); 1580 } 1581 1582 // Check for more than one of { assign, copy, retain }. 1583 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 1584 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1585 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1586 << "assign" << "copy"; 1587 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1588 } 1589 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1590 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1591 << "assign" << "retain"; 1592 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1593 } 1594 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 1595 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1596 << "assign" << "strong"; 1597 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 1598 } 1599 if (getLangOptions().ObjCAutoRefCount && 1600 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1601 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1602 << "assign" << "weak"; 1603 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1604 } 1605 } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) { 1606 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1607 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1608 << "unsafe_unretained" << "copy"; 1609 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1610 } 1611 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1612 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1613 << "unsafe_unretained" << "retain"; 1614 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1615 } 1616 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 1617 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1618 << "unsafe_unretained" << "strong"; 1619 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 1620 } 1621 if (getLangOptions().ObjCAutoRefCount && 1622 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1623 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1624 << "unsafe_unretained" << "weak"; 1625 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1626 } 1627 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1628 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1629 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1630 << "copy" << "retain"; 1631 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1632 } 1633 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 1634 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1635 << "copy" << "strong"; 1636 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 1637 } 1638 if (Attributes & ObjCDeclSpec::DQ_PR_weak) { 1639 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1640 << "copy" << "weak"; 1641 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1642 } 1643 } 1644 else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) && 1645 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1646 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1647 << "retain" << "weak"; 1648 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1649 } 1650 else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) && 1651 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1652 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1653 << "strong" << "weak"; 1654 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1655 } 1656 1657 // Warn if user supplied no assignment attribute, property is 1658 // readwrite, and this is an object type. 1659 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | 1660 ObjCDeclSpec::DQ_PR_unsafe_unretained | 1661 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong | 1662 ObjCDeclSpec::DQ_PR_weak)) && 1663 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1664 PropertyTy->isObjCObjectPointerType()) { 1665 if (getLangOptions().ObjCAutoRefCount) 1666 Diag(Loc, diag::err_arc_objc_property_default_assign_on_object); 1667 else { 1668 // Skip this warning in gc-only mode. 1669 if (getLangOptions().getGCMode() != LangOptions::GCOnly) 1670 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 1671 1672 // If non-gc code warn that this is likely inappropriate. 1673 if (getLangOptions().getGCMode() == LangOptions::NonGC) 1674 Diag(Loc, diag::warn_objc_property_default_assign_on_object); 1675 } 1676 1677 // FIXME: Implement warning dependent on NSCopying being 1678 // implemented. See also: 1679 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496> 1680 // (please trim this list while you are at it). 1681 } 1682 1683 if (!(Attributes & ObjCDeclSpec::DQ_PR_copy) 1684 &&!(Attributes & ObjCDeclSpec::DQ_PR_readonly) 1685 && getLangOptions().getGCMode() == LangOptions::GCOnly 1686 && PropertyTy->isBlockPointerType()) 1687 Diag(Loc, diag::warn_objc_property_copy_missing_on_block); 1688} 1689