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