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