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