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