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