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