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