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