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