SemaObjCProperty.cpp revision 5fcd52a6c94c7f93bd80062248353c45330da23a
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 "Sema.h" 16 17using namespace clang; 18 19//===----------------------------------------------------------------------===// 20// Grammar actions. 21//===----------------------------------------------------------------------===// 22 23Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, 24 FieldDeclarator &FD, 25 ObjCDeclSpec &ODS, 26 Selector GetterSel, 27 Selector SetterSel, 28 DeclPtrTy ClassCategory, 29 bool *isOverridingProperty, 30 tok::ObjCKeywordKind MethodImplKind) { 31 unsigned Attributes = ODS.getPropertyAttributes(); 32 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) || 33 // default is readwrite! 34 !(Attributes & ObjCDeclSpec::DQ_PR_readonly)); 35 // property is defaulted to 'assign' if it is readwrite and is 36 // not retain or copy 37 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) || 38 (isReadWrite && 39 !(Attributes & ObjCDeclSpec::DQ_PR_retain) && 40 !(Attributes & ObjCDeclSpec::DQ_PR_copy))); 41 42 QualType T = GetTypeForDeclarator(FD.D, S); 43 if (T->isReferenceType()) { 44 Diag(AtLoc, diag::error_reference_property); 45 return DeclPtrTy(); 46 } 47 // Proceed with constructing the ObjCPropertDecls. 48 ObjCContainerDecl *ClassDecl = 49 cast<ObjCContainerDecl>(ClassCategory.getAs<Decl>()); 50 51 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) 52 if (CDecl->IsClassExtension()) 53 return HandlePropertyInClassExtension(S, CDecl, AtLoc, 54 FD, GetterSel, SetterSel, 55 isAssign, isReadWrite, 56 Attributes, 57 isOverridingProperty, T, 58 MethodImplKind); 59 60 DeclPtrTy Res = DeclPtrTy::make(CreatePropertyDecl(S, ClassDecl, AtLoc, FD, 61 GetterSel, SetterSel, 62 isAssign, isReadWrite, 63 Attributes, T, MethodImplKind)); 64 // Validate the attributes on the @property. 65 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); 66 return Res; 67} 68 69Sema::DeclPtrTy 70Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl, 71 SourceLocation AtLoc, FieldDeclarator &FD, 72 Selector GetterSel, Selector SetterSel, 73 const bool isAssign, 74 const bool isReadWrite, 75 const unsigned Attributes, 76 bool *isOverridingProperty, 77 QualType T, 78 tok::ObjCKeywordKind MethodImplKind) { 79 80 // Diagnose if this property is already in continuation class. 81 DeclContext *DC = cast<DeclContext>(CDecl); 82 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 83 84 if (ObjCPropertyDecl *prevDecl = 85 ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) { 86 Diag(AtLoc, diag::err_duplicate_property); 87 Diag(prevDecl->getLocation(), diag::note_property_declare); 88 return DeclPtrTy(); 89 } 90 91 // Create a new ObjCPropertyDecl with the DeclContext being 92 // the class extension. 93 ObjCPropertyDecl *PDecl = 94 ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(), 95 PropertyId, AtLoc, T); 96 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 97 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 98 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 99 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 100 101 DC->addDecl(PDecl); 102 103 // We need to look in the @interface to see if the @property was 104 // already declared. 105 ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface(); 106 if (!CCPrimary) { 107 Diag(CDecl->getLocation(), diag::err_continuation_class); 108 *isOverridingProperty = true; 109 return DeclPtrTy(); 110 } 111 112 // Find the property in continuation class's primary class only. 113 ObjCPropertyDecl *PIDecl = 114 CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId); 115 116 if (!PIDecl) { 117 // No matching property found in the primary class. Just fall thru 118 // and add property to continuation class's primary class. 119 ObjCPropertyDecl *PDecl = 120 CreatePropertyDecl(S, CCPrimary, AtLoc, 121 FD, GetterSel, SetterSel, isAssign, isReadWrite, 122 Attributes, T, MethodImplKind); 123 124 // A case of continuation class adding a new property in the class. This 125 // is not what it was meant for. However, gcc supports it and so should we. 126 // Make sure setter/getters are declared here. 127 ProcessPropertyDecl(PDecl, CCPrimary); 128 return DeclPtrTy::make(PDecl); 129 130 } 131 132 // The property 'PIDecl's readonly attribute will be over-ridden 133 // with continuation class's readwrite property attribute! 134 unsigned PIkind = PIDecl->getPropertyAttributes(); 135 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { 136 unsigned retainCopyNonatomic = 137 (ObjCPropertyDecl::OBJC_PR_retain | 138 ObjCPropertyDecl::OBJC_PR_copy | 139 ObjCPropertyDecl::OBJC_PR_nonatomic); 140 if ((Attributes & retainCopyNonatomic) != 141 (PIkind & retainCopyNonatomic)) { 142 Diag(AtLoc, diag::warn_property_attr_mismatch); 143 Diag(PIDecl->getLocation(), diag::note_property_declare); 144 } 145 DeclContext *DC = cast<DeclContext>(CCPrimary); 146 if (!ObjCPropertyDecl::findPropertyDecl(DC, 147 PIDecl->getDeclName().getAsIdentifierInfo())) { 148 // Protocol is not in the primary class. Must build one for it. 149 ObjCDeclSpec ProtocolPropertyODS; 150 // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind 151 // and ObjCPropertyDecl::PropertyAttributeKind have identical 152 // values. Should consolidate both into one enum type. 153 ProtocolPropertyODS. 154 setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind) 155 PIkind); 156 157 DeclPtrTy ProtocolPtrTy = 158 ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS, 159 PIDecl->getGetterName(), 160 PIDecl->getSetterName(), 161 DeclPtrTy::make(CCPrimary), isOverridingProperty, 162 MethodImplKind); 163 PIDecl = ProtocolPtrTy.getAs<ObjCPropertyDecl>(); 164 } 165 PIDecl->makeitReadWriteAttribute(); 166 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 167 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 168 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 169 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 170 PIDecl->setSetterName(SetterSel); 171 } else { 172 Diag(AtLoc, diag::err_use_continuation_class) 173 << CCPrimary->getDeclName(); 174 Diag(PIDecl->getLocation(), diag::note_property_declare); 175 } 176 *isOverridingProperty = true; 177 // Make sure setter decl is synthesized, and added to primary class's list. 178 ProcessPropertyDecl(PIDecl, CCPrimary); 179 return DeclPtrTy(); 180} 181 182ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, 183 ObjCContainerDecl *CDecl, 184 SourceLocation AtLoc, 185 FieldDeclarator &FD, 186 Selector GetterSel, 187 Selector SetterSel, 188 const bool isAssign, 189 const bool isReadWrite, 190 const unsigned Attributes, 191 QualType T, 192 tok::ObjCKeywordKind MethodImplKind){ 193 194 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 195 196 // Issue a warning if property is 'assign' as default and its object, which is 197 // gc'able conforms to NSCopying protocol 198 if (getLangOptions().getGCMode() != LangOptions::NonGC && 199 isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign)) 200 if (T->isObjCObjectPointerType()) { 201 QualType InterfaceTy = T->getPointeeType(); 202 if (const ObjCInterfaceType *OIT = 203 InterfaceTy->getAs<ObjCInterfaceType>()) { 204 ObjCInterfaceDecl *IDecl = OIT->getDecl(); 205 if (IDecl) 206 if (ObjCProtocolDecl* PNSCopying = 207 LookupProtocol(&Context.Idents.get("NSCopying"))) 208 if (IDecl->ClassImplementsProtocol(PNSCopying, true)) 209 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId; 210 } 211 } 212 if (T->isObjCInterfaceType()) 213 Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object); 214 215 DeclContext *DC = cast<DeclContext>(CDecl); 216 ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC, 217 FD.D.getIdentifierLoc(), 218 PropertyId, AtLoc, T); 219 220 if (ObjCPropertyDecl *prevDecl = 221 ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) { 222 Diag(PDecl->getLocation(), diag::err_duplicate_property); 223 Diag(prevDecl->getLocation(), diag::note_property_declare); 224 PDecl->setInvalidDecl(); 225 } 226 else 227 DC->addDecl(PDecl); 228 229 if (T->isArrayType() || T->isFunctionType()) { 230 Diag(AtLoc, diag::err_property_type) << T; 231 PDecl->setInvalidDecl(); 232 } 233 234 ProcessDeclAttributes(S, PDecl, FD.D); 235 236 // Regardless of setter/getter attribute, we save the default getter/setter 237 // selector names in anticipation of declaration of setter/getter methods. 238 PDecl->setGetterName(GetterSel); 239 PDecl->setSetterName(SetterSel); 240 241 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 242 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 243 244 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 245 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter); 246 247 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 248 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter); 249 250 if (isReadWrite) 251 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 252 253 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 254 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 255 256 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 257 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 258 259 if (isAssign) 260 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 261 262 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 263 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); 264 265 if (MethodImplKind == tok::objc_required) 266 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required); 267 else if (MethodImplKind == tok::objc_optional) 268 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional); 269 270 return PDecl; 271} 272 273 274/// ActOnPropertyImplDecl - This routine performs semantic checks and 275/// builds the AST node for a property implementation declaration; declared 276/// as @synthesize or @dynamic. 277/// 278Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, 279 SourceLocation PropertyLoc, 280 bool Synthesize, 281 DeclPtrTy ClassCatImpDecl, 282 IdentifierInfo *PropertyId, 283 IdentifierInfo *PropertyIvar) { 284 ObjCContainerDecl *ClassImpDecl = ClassCatImpDecl.getAs<ObjCContainerDecl>(); 285 // Make sure we have a context for the property implementation declaration. 286 if (!ClassImpDecl) { 287 Diag(AtLoc, diag::error_missing_property_context); 288 return DeclPtrTy(); 289 } 290 ObjCPropertyDecl *property = 0; 291 ObjCInterfaceDecl* IDecl = 0; 292 // Find the class or category class where this property must have 293 // a declaration. 294 ObjCImplementationDecl *IC = 0; 295 ObjCCategoryImplDecl* CatImplClass = 0; 296 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) { 297 IDecl = IC->getClassInterface(); 298 // We always synthesize an interface for an implementation 299 // without an interface decl. So, IDecl is always non-zero. 300 assert(IDecl && 301 "ActOnPropertyImplDecl - @implementation without @interface"); 302 303 // Look for this property declaration in the @implementation's @interface 304 property = IDecl->FindPropertyDeclaration(PropertyId); 305 if (!property) { 306 Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName(); 307 return DeclPtrTy(); 308 } 309 if (const ObjCCategoryDecl *CD = 310 dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) { 311 if (!CD->IsClassExtension()) { 312 Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName(); 313 Diag(property->getLocation(), diag::note_property_declare); 314 return DeclPtrTy(); 315 } 316 } 317 } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) { 318 if (Synthesize) { 319 Diag(AtLoc, diag::error_synthesize_category_decl); 320 return DeclPtrTy(); 321 } 322 IDecl = CatImplClass->getClassInterface(); 323 if (!IDecl) { 324 Diag(AtLoc, diag::error_missing_property_interface); 325 return DeclPtrTy(); 326 } 327 ObjCCategoryDecl *Category = 328 IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier()); 329 330 // If category for this implementation not found, it is an error which 331 // has already been reported eralier. 332 if (!Category) 333 return DeclPtrTy(); 334 // Look for this property declaration in @implementation's category 335 property = Category->FindPropertyDeclaration(PropertyId); 336 if (!property) { 337 Diag(PropertyLoc, diag::error_bad_category_property_decl) 338 << Category->getDeclName(); 339 return DeclPtrTy(); 340 } 341 } else { 342 Diag(AtLoc, diag::error_bad_property_context); 343 return DeclPtrTy(); 344 } 345 ObjCIvarDecl *Ivar = 0; 346 // Check that we have a valid, previously declared ivar for @synthesize 347 if (Synthesize) { 348 // @synthesize 349 if (!PropertyIvar) 350 PropertyIvar = PropertyId; 351 QualType PropType = Context.getCanonicalType(property->getType()); 352 // Check that this is a previously declared 'ivar' in 'IDecl' interface 353 ObjCInterfaceDecl *ClassDeclared; 354 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared); 355 if (!Ivar) { 356 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc, 357 PropertyIvar, PropType, /*Dinfo=*/0, 358 ObjCIvarDecl::Public, 359 (Expr *)0); 360 ClassImpDecl->addDecl(Ivar); 361 IDecl->makeDeclVisibleInContext(Ivar, false); 362 property->setPropertyIvarDecl(Ivar); 363 364 if (!getLangOptions().ObjCNonFragileABI) 365 Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId; 366 // Note! I deliberately want it to fall thru so, we have a 367 // a property implementation and to avoid future warnings. 368 } else if (getLangOptions().ObjCNonFragileABI && 369 ClassDeclared != IDecl) { 370 Diag(PropertyLoc, diag::error_ivar_in_superclass_use) 371 << property->getDeclName() << Ivar->getDeclName() 372 << ClassDeclared->getDeclName(); 373 Diag(Ivar->getLocation(), diag::note_previous_access_declaration) 374 << Ivar << Ivar->getNameAsCString(); 375 // Note! I deliberately want it to fall thru so more errors are caught. 376 } 377 QualType IvarType = Context.getCanonicalType(Ivar->getType()); 378 379 // Check that type of property and its ivar are type compatible. 380 if (PropType != IvarType) { 381 if (CheckAssignmentConstraints(PropType, IvarType) != Compatible) { 382 Diag(PropertyLoc, diag::error_property_ivar_type) 383 << property->getDeclName() << PropType 384 << Ivar->getDeclName() << IvarType; 385 Diag(Ivar->getLocation(), diag::note_ivar_decl); 386 // Note! I deliberately want it to fall thru so, we have a 387 // a property implementation and to avoid future warnings. 388 } 389 390 // FIXME! Rules for properties are somewhat different that those 391 // for assignments. Use a new routine to consolidate all cases; 392 // specifically for property redeclarations as well as for ivars. 393 QualType lhsType =Context.getCanonicalType(PropType).getUnqualifiedType(); 394 QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType(); 395 if (lhsType != rhsType && 396 lhsType->isArithmeticType()) { 397 Diag(PropertyLoc, diag::error_property_ivar_type) 398 << property->getDeclName() << PropType 399 << Ivar->getDeclName() << IvarType; 400 Diag(Ivar->getLocation(), diag::note_ivar_decl); 401 // Fall thru - see previous comment 402 } 403 // __weak is explicit. So it works on Canonical type. 404 if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() && 405 getLangOptions().getGCMode() != LangOptions::NonGC) { 406 Diag(PropertyLoc, diag::error_weak_property) 407 << property->getDeclName() << Ivar->getDeclName(); 408 // Fall thru - see previous comment 409 } 410 if ((property->getType()->isObjCObjectPointerType() || 411 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() && 412 getLangOptions().getGCMode() != LangOptions::NonGC) { 413 Diag(PropertyLoc, diag::error_strong_property) 414 << property->getDeclName() << Ivar->getDeclName(); 415 // Fall thru - see previous comment 416 } 417 } 418 } else if (PropertyIvar) 419 // @dynamic 420 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl); 421 assert (property && "ActOnPropertyImplDecl - property declaration missing"); 422 ObjCPropertyImplDecl *PIDecl = 423 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, 424 property, 425 (Synthesize ? 426 ObjCPropertyImplDecl::Synthesize 427 : ObjCPropertyImplDecl::Dynamic), 428 Ivar); 429 if (IC) { 430 if (Synthesize) 431 if (ObjCPropertyImplDecl *PPIDecl = 432 IC->FindPropertyImplIvarDecl(PropertyIvar)) { 433 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 434 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 435 << PropertyIvar; 436 Diag(PPIDecl->getLocation(), diag::note_previous_use); 437 } 438 439 if (ObjCPropertyImplDecl *PPIDecl 440 = IC->FindPropertyImplDecl(PropertyId)) { 441 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 442 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 443 return DeclPtrTy(); 444 } 445 IC->addPropertyImplementation(PIDecl); 446 } else { 447 if (Synthesize) 448 if (ObjCPropertyImplDecl *PPIDecl = 449 CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) { 450 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 451 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 452 << PropertyIvar; 453 Diag(PPIDecl->getLocation(), diag::note_previous_use); 454 } 455 456 if (ObjCPropertyImplDecl *PPIDecl = 457 CatImplClass->FindPropertyImplDecl(PropertyId)) { 458 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 459 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 460 return DeclPtrTy(); 461 } 462 CatImplClass->addPropertyImplementation(PIDecl); 463 } 464 465 return DeclPtrTy::make(PIDecl); 466} 467 468//===----------------------------------------------------------------------===// 469// Helper methods. 470//===----------------------------------------------------------------------===// 471 472/// DiagnosePropertyMismatch - Compares two properties for their 473/// attributes and types and warns on a variety of inconsistencies. 474/// 475void 476Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, 477 ObjCPropertyDecl *SuperProperty, 478 const IdentifierInfo *inheritedName) { 479 ObjCPropertyDecl::PropertyAttributeKind CAttr = 480 Property->getPropertyAttributes(); 481 ObjCPropertyDecl::PropertyAttributeKind SAttr = 482 SuperProperty->getPropertyAttributes(); 483 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) 484 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) 485 Diag(Property->getLocation(), diag::warn_readonly_property) 486 << Property->getDeclName() << inheritedName; 487 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) 488 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) 489 Diag(Property->getLocation(), diag::warn_property_attribute) 490 << Property->getDeclName() << "copy" << inheritedName; 491 else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain) 492 != (SAttr & ObjCPropertyDecl::OBJC_PR_retain)) 493 Diag(Property->getLocation(), diag::warn_property_attribute) 494 << Property->getDeclName() << "retain" << inheritedName; 495 496 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) 497 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) 498 Diag(Property->getLocation(), diag::warn_property_attribute) 499 << Property->getDeclName() << "atomic" << inheritedName; 500 if (Property->getSetterName() != SuperProperty->getSetterName()) 501 Diag(Property->getLocation(), diag::warn_property_attribute) 502 << Property->getDeclName() << "setter" << inheritedName; 503 if (Property->getGetterName() != SuperProperty->getGetterName()) 504 Diag(Property->getLocation(), diag::warn_property_attribute) 505 << Property->getDeclName() << "getter" << inheritedName; 506 507 QualType LHSType = 508 Context.getCanonicalType(SuperProperty->getType()); 509 QualType RHSType = 510 Context.getCanonicalType(Property->getType()); 511 512 if (!Context.typesAreCompatible(LHSType, RHSType)) { 513 // FIXME: Incorporate this test with typesAreCompatible. 514 if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType()) 515 if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false)) 516 return; 517 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) 518 << Property->getType() << SuperProperty->getType() << inheritedName; 519 } 520} 521 522bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, 523 ObjCMethodDecl *GetterMethod, 524 SourceLocation Loc) { 525 if (GetterMethod && 526 GetterMethod->getResultType() != property->getType()) { 527 AssignConvertType result = Incompatible; 528 if (property->getType()->isObjCObjectPointerType()) 529 result = CheckAssignmentConstraints(GetterMethod->getResultType(), 530 property->getType()); 531 if (result != Compatible) { 532 Diag(Loc, diag::warn_accessor_property_type_mismatch) 533 << property->getDeclName() 534 << GetterMethod->getSelector(); 535 Diag(GetterMethod->getLocation(), diag::note_declared_at); 536 return true; 537 } 538 } 539 return false; 540} 541 542/// ComparePropertiesInBaseAndSuper - This routine compares property 543/// declarations in base and its super class, if any, and issues 544/// diagnostics in a variety of inconsistant situations. 545/// 546void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) { 547 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); 548 if (!SDecl) 549 return; 550 // FIXME: O(N^2) 551 for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(), 552 E = SDecl->prop_end(); S != E; ++S) { 553 ObjCPropertyDecl *SuperPDecl = (*S); 554 // Does property in super class has declaration in current class? 555 for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(), 556 E = IDecl->prop_end(); I != E; ++I) { 557 ObjCPropertyDecl *PDecl = (*I); 558 if (SuperPDecl->getIdentifier() == PDecl->getIdentifier()) 559 DiagnosePropertyMismatch(PDecl, SuperPDecl, 560 SDecl->getIdentifier()); 561 } 562 } 563} 564 565/// MatchOneProtocolPropertiesInClass - This routine goes thru the list 566/// of properties declared in a protocol and compares their attribute against 567/// the same property declared in the class or category. 568void 569Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl, 570 ObjCProtocolDecl *PDecl) { 571 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 572 if (!IDecl) { 573 // Category 574 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 575 assert (CatDecl && "MatchOneProtocolPropertiesInClass"); 576 if (!CatDecl->IsClassExtension()) 577 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 578 E = PDecl->prop_end(); P != E; ++P) { 579 ObjCPropertyDecl *Pr = (*P); 580 ObjCCategoryDecl::prop_iterator CP, CE; 581 // Is this property already in category's list of properties? 582 for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP!=CE; ++CP) 583 if ((*CP)->getIdentifier() == Pr->getIdentifier()) 584 break; 585 if (CP != CE) 586 // Property protocol already exist in class. Diagnose any mismatch. 587 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier()); 588 } 589 return; 590 } 591 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 592 E = PDecl->prop_end(); P != E; ++P) { 593 ObjCPropertyDecl *Pr = (*P); 594 ObjCInterfaceDecl::prop_iterator CP, CE; 595 // Is this property already in class's list of properties? 596 for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP) 597 if ((*CP)->getIdentifier() == Pr->getIdentifier()) 598 break; 599 if (CP != CE) 600 // Property protocol already exist in class. Diagnose any mismatch. 601 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier()); 602 } 603} 604 605/// CompareProperties - This routine compares properties 606/// declared in 'ClassOrProtocol' objects (which can be a class or an 607/// inherited protocol with the list of properties for class/category 'CDecl' 608/// 609void Sema::CompareProperties(Decl *CDecl, 610 DeclPtrTy ClassOrProtocol) { 611 Decl *ClassDecl = ClassOrProtocol.getAs<Decl>(); 612 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 613 614 if (!IDecl) { 615 // Category 616 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 617 assert (CatDecl && "CompareProperties"); 618 if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 619 for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(), 620 E = MDecl->protocol_end(); P != E; ++P) 621 // Match properties of category with those of protocol (*P) 622 MatchOneProtocolPropertiesInClass(CatDecl, *P); 623 624 // Go thru the list of protocols for this category and recursively match 625 // their properties with those in the category. 626 for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(), 627 E = CatDecl->protocol_end(); P != E; ++P) 628 CompareProperties(CatDecl, DeclPtrTy::make(*P)); 629 } else { 630 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 631 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 632 E = MD->protocol_end(); P != E; ++P) 633 MatchOneProtocolPropertiesInClass(CatDecl, *P); 634 } 635 return; 636 } 637 638 if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { 639 for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(), 640 E = MDecl->protocol_end(); P != E; ++P) 641 // Match properties of class IDecl with those of protocol (*P). 642 MatchOneProtocolPropertiesInClass(IDecl, *P); 643 644 // Go thru the list of protocols for this class and recursively match 645 // their properties with those declared in the class. 646 for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(), 647 E = IDecl->protocol_end(); P != E; ++P) 648 CompareProperties(IDecl, DeclPtrTy::make(*P)); 649 } else { 650 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 651 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 652 E = MD->protocol_end(); P != E; ++P) 653 MatchOneProtocolPropertiesInClass(IDecl, *P); 654 } 655} 656 657/// isPropertyReadonly - Return true if property is readonly, by searching 658/// for the property in the class and in its categories and implementations 659/// 660bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl, 661 ObjCInterfaceDecl *IDecl) { 662 // by far the most common case. 663 if (!PDecl->isReadOnly()) 664 return false; 665 // Even if property is ready only, if interface has a user defined setter, 666 // it is not considered read only. 667 if (IDecl->getInstanceMethod(PDecl->getSetterName())) 668 return false; 669 670 // Main class has the property as 'readonly'. Must search 671 // through the category list to see if the property's 672 // attribute has been over-ridden to 'readwrite'. 673 for (ObjCCategoryDecl *Category = IDecl->getCategoryList(); 674 Category; Category = Category->getNextClassCategory()) { 675 // Even if property is ready only, if a category has a user defined setter, 676 // it is not considered read only. 677 if (Category->getInstanceMethod(PDecl->getSetterName())) 678 return false; 679 ObjCPropertyDecl *P = 680 Category->FindPropertyDeclaration(PDecl->getIdentifier()); 681 if (P && !P->isReadOnly()) 682 return false; 683 } 684 685 // Also, check for definition of a setter method in the implementation if 686 // all else failed. 687 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) { 688 if (ObjCImplementationDecl *IMD = 689 dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) { 690 if (IMD->getInstanceMethod(PDecl->getSetterName())) 691 return false; 692 } else if (ObjCCategoryImplDecl *CIMD = 693 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 694 if (CIMD->getInstanceMethod(PDecl->getSetterName())) 695 return false; 696 } 697 } 698 // Lastly, look through the implementation (if one is in scope). 699 if (ObjCImplementationDecl *ImpDecl = IDecl->getImplementation()) 700 if (ImpDecl->getInstanceMethod(PDecl->getSetterName())) 701 return false; 702 // If all fails, look at the super class. 703 if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass()) 704 return isPropertyReadonly(PDecl, SIDecl); 705 return true; 706} 707 708/// CollectImmediateProperties - This routine collects all properties in 709/// the class and its conforming protocols; but not those it its super class. 710void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, 711 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 712 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 713 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 714 E = IDecl->prop_end(); P != E; ++P) { 715 ObjCPropertyDecl *Prop = (*P); 716 PropMap[Prop->getIdentifier()] = Prop; 717 } 718 // scan through class's protocols. 719 for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(), 720 E = IDecl->protocol_end(); PI != E; ++PI) 721 CollectImmediateProperties((*PI), PropMap); 722 } 723 if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) { 724 if (!CATDecl->IsClassExtension()) 725 for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(), 726 E = CATDecl->prop_end(); P != E; ++P) { 727 ObjCPropertyDecl *Prop = (*P); 728 PropMap[Prop->getIdentifier()] = Prop; 729 } 730 // scan through class's protocols. 731 for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(), 732 E = CATDecl->protocol_end(); PI != E; ++PI) 733 CollectImmediateProperties((*PI), PropMap); 734 } 735 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 736 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 737 E = PDecl->prop_end(); P != E; ++P) { 738 ObjCPropertyDecl *Prop = (*P); 739 ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()]; 740 if (!PropEntry) 741 PropEntry = Prop; 742 } 743 // scan through protocol's protocols. 744 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 745 E = PDecl->protocol_end(); PI != E; ++PI) 746 CollectImmediateProperties((*PI), PropMap); 747 } 748} 749 750/// LookupPropertyDecl - Looks up a property in the current class and all 751/// its protocols. 752ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, 753 IdentifierInfo *II) { 754 if (const ObjCInterfaceDecl *IDecl = 755 dyn_cast<ObjCInterfaceDecl>(CDecl)) { 756 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 757 E = IDecl->prop_end(); P != E; ++P) { 758 ObjCPropertyDecl *Prop = (*P); 759 if (Prop->getIdentifier() == II) 760 return Prop; 761 } 762 // scan through class's protocols. 763 for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(), 764 E = IDecl->protocol_end(); PI != E; ++PI) { 765 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 766 if (Prop) 767 return Prop; 768 } 769 } 770 else if (const ObjCProtocolDecl *PDecl = 771 dyn_cast<ObjCProtocolDecl>(CDecl)) { 772 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 773 E = PDecl->prop_end(); P != E; ++P) { 774 ObjCPropertyDecl *Prop = (*P); 775 if (Prop->getIdentifier() == II) 776 return Prop; 777 } 778 // scan through protocol's protocols. 779 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 780 E = PDecl->protocol_end(); PI != E; ++PI) { 781 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 782 if (Prop) 783 return Prop; 784 } 785 } 786 return 0; 787} 788 789 790void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl, 791 ObjCContainerDecl *CDecl, 792 const llvm::DenseSet<Selector>& InsMap) { 793 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 794 CollectImmediateProperties(CDecl, PropMap); 795 if (PropMap.empty()) 796 return; 797 798 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap; 799 for (ObjCImplDecl::propimpl_iterator 800 I = IMPDecl->propimpl_begin(), 801 EI = IMPDecl->propimpl_end(); I != EI; ++I) 802 PropImplMap.insert((*I)->getPropertyDecl()); 803 804 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 805 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 806 ObjCPropertyDecl *Prop = P->second; 807 // Is there a matching propery synthesize/dynamic? 808 if (Prop->isInvalidDecl() || 809 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 810 PropImplMap.count(Prop)) 811 continue; 812 if (LangOpts.ObjCNonFragileABI2) { 813 ActOnPropertyImplDecl(IMPDecl->getLocation(), 814 SourceLocation(), 815 true, DeclPtrTy::make(IMPDecl), 816 Prop->getIdentifier(), 817 Prop->getIdentifier()); 818 continue; 819 } 820 if (!InsMap.count(Prop->getGetterName())) { 821 Diag(Prop->getLocation(), 822 isa<ObjCCategoryDecl>(CDecl) ? 823 diag::warn_setter_getter_impl_required_in_category : 824 diag::warn_setter_getter_impl_required) 825 << Prop->getDeclName() << Prop->getGetterName(); 826 Diag(IMPDecl->getLocation(), 827 diag::note_property_impl_required); 828 } 829 830 if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) { 831 Diag(Prop->getLocation(), 832 isa<ObjCCategoryDecl>(CDecl) ? 833 diag::warn_setter_getter_impl_required_in_category : 834 diag::warn_setter_getter_impl_required) 835 << Prop->getDeclName() << Prop->getSetterName(); 836 Diag(IMPDecl->getLocation(), 837 diag::note_property_impl_required); 838 } 839 } 840} 841 842void 843Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, 844 ObjCContainerDecl* IDecl) { 845 // Rules apply in non-GC mode only 846 if (getLangOptions().getGCMode() != LangOptions::NonGC) 847 return; 848 for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(), 849 E = IDecl->prop_end(); 850 I != E; ++I) { 851 ObjCPropertyDecl *Property = (*I); 852 unsigned Attributes = Property->getPropertyAttributes(); 853 // We only care about readwrite atomic property. 854 if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) || 855 !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite)) 856 continue; 857 if (const ObjCPropertyImplDecl *PIDecl 858 = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) { 859 if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 860 continue; 861 ObjCMethodDecl *GetterMethod = 862 IMPDecl->getInstanceMethod(Property->getGetterName()); 863 ObjCMethodDecl *SetterMethod = 864 IMPDecl->getInstanceMethod(Property->getSetterName()); 865 if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { 866 SourceLocation MethodLoc = 867 (GetterMethod ? GetterMethod->getLocation() 868 : SetterMethod->getLocation()); 869 Diag(MethodLoc, diag::warn_atomic_property_rule) 870 << Property->getIdentifier(); 871 Diag(Property->getLocation(), diag::note_property_declare); 872 } 873 } 874 } 875} 876 877/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods 878/// have the property type and issue diagnostics if they don't. 879/// Also synthesize a getter/setter method if none exist (and update the 880/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized 881/// methods is the "right" thing to do. 882void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, 883 ObjCContainerDecl *CD) { 884 ObjCMethodDecl *GetterMethod, *SetterMethod; 885 886 GetterMethod = CD->getInstanceMethod(property->getGetterName()); 887 SetterMethod = CD->getInstanceMethod(property->getSetterName()); 888 DiagnosePropertyAccessorMismatch(property, GetterMethod, 889 property->getLocation()); 890 891 if (SetterMethod) { 892 ObjCPropertyDecl::PropertyAttributeKind CAttr = 893 property->getPropertyAttributes(); 894 if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) && 895 Context.getCanonicalType(SetterMethod->getResultType()) != 896 Context.VoidTy) 897 Diag(SetterMethod->getLocation(), diag::err_setter_type_void); 898 if (SetterMethod->param_size() != 1 || 899 ((*SetterMethod->param_begin())->getType() != property->getType())) { 900 Diag(property->getLocation(), 901 diag::warn_accessor_property_type_mismatch) 902 << property->getDeclName() 903 << SetterMethod->getSelector(); 904 Diag(SetterMethod->getLocation(), diag::note_declared_at); 905 } 906 } 907 908 // Synthesize getter/setter methods if none exist. 909 // Find the default getter and if one not found, add one. 910 // FIXME: The synthesized property we set here is misleading. We almost always 911 // synthesize these methods unless the user explicitly provided prototypes 912 // (which is odd, but allowed). Sema should be typechecking that the 913 // declarations jive in that situation (which it is not currently). 914 if (!GetterMethod) { 915 // No instance method of same name as property getter name was found. 916 // Declare a getter method and add it to the list of methods 917 // for this class. 918 GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(), 919 property->getLocation(), property->getGetterName(), 920 property->getType(), 0, CD, true, false, true, 921 (property->getPropertyImplementation() == 922 ObjCPropertyDecl::Optional) ? 923 ObjCMethodDecl::Optional : 924 ObjCMethodDecl::Required); 925 CD->addDecl(GetterMethod); 926 } else 927 // A user declared getter will be synthesize when @synthesize of 928 // the property with the same name is seen in the @implementation 929 GetterMethod->setSynthesized(true); 930 property->setGetterMethodDecl(GetterMethod); 931 932 // Skip setter if property is read-only. 933 if (!property->isReadOnly()) { 934 // Find the default setter and if one not found, add one. 935 if (!SetterMethod) { 936 // No instance method of same name as property setter name was found. 937 // Declare a setter method and add it to the list of methods 938 // for this class. 939 SetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(), 940 property->getLocation(), 941 property->getSetterName(), 942 Context.VoidTy, 0, CD, true, false, true, 943 (property->getPropertyImplementation() == 944 ObjCPropertyDecl::Optional) ? 945 ObjCMethodDecl::Optional : 946 ObjCMethodDecl::Required); 947 // Invent the arguments for the setter. We don't bother making a 948 // nice name for the argument. 949 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, 950 property->getLocation(), 951 property->getIdentifier(), 952 property->getType(), 953 /*TInfo=*/0, 954 VarDecl::None, 955 0); 956 SetterMethod->setMethodParams(Context, &Argument, 1); 957 CD->addDecl(SetterMethod); 958 } else 959 // A user declared setter will be synthesize when @synthesize of 960 // the property with the same name is seen in the @implementation 961 SetterMethod->setSynthesized(true); 962 property->setSetterMethodDecl(SetterMethod); 963 } 964 // Add any synthesized methods to the global pool. This allows us to 965 // handle the following, which is supported by GCC (and part of the design). 966 // 967 // @interface Foo 968 // @property double bar; 969 // @end 970 // 971 // void thisIsUnfortunate() { 972 // id foo; 973 // double bar = [foo bar]; 974 // } 975 // 976 if (GetterMethod) 977 AddInstanceMethodToGlobalPool(GetterMethod); 978 if (SetterMethod) 979 AddInstanceMethodToGlobalPool(SetterMethod); 980} 981 982void Sema::CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy, 983 SourceLocation Loc, 984 unsigned &Attributes) { 985 // FIXME: Improve the reported location. 986 Decl *PDecl = PropertyPtrTy.getAs<Decl>(); 987 if (!PDecl) 988 return; 989 990 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 991 QualType PropertyTy = PropertyDecl->getType(); 992 993 // readonly and readwrite/assign/retain/copy conflict. 994 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 995 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 996 ObjCDeclSpec::DQ_PR_assign | 997 ObjCDeclSpec::DQ_PR_copy | 998 ObjCDeclSpec::DQ_PR_retain))) { 999 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ? 1000 "readwrite" : 1001 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 1002 "assign" : 1003 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 1004 "copy" : "retain"; 1005 1006 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 1007 diag::err_objc_property_attr_mutually_exclusive : 1008 diag::warn_objc_property_attr_mutually_exclusive) 1009 << "readonly" << which; 1010 } 1011 1012 // Check for copy or retain on non-object types. 1013 if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) && 1014 !PropertyTy->isObjCObjectPointerType() && 1015 !PropertyTy->isBlockPointerType() && 1016 !Context.isObjCNSObjectType(PropertyTy) && 1017 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { 1018 Diag(Loc, diag::err_objc_property_requires_object) 1019 << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain"); 1020 Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain); 1021 } 1022 1023 // Check for more than one of { assign, copy, retain }. 1024 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 1025 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1026 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1027 << "assign" << "copy"; 1028 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1029 } 1030 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1031 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1032 << "assign" << "retain"; 1033 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1034 } 1035 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1036 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1037 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1038 << "copy" << "retain"; 1039 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1040 } 1041 } 1042 1043 // Warn if user supplied no assignment attribute, property is 1044 // readwrite, and this is an object type. 1045 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | 1046 ObjCDeclSpec::DQ_PR_retain)) && 1047 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1048 PropertyTy->isObjCObjectPointerType()) { 1049 // Skip this warning in gc-only mode. 1050 if (getLangOptions().getGCMode() != LangOptions::GCOnly) 1051 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 1052 1053 // If non-gc code warn that this is likely inappropriate. 1054 if (getLangOptions().getGCMode() == LangOptions::NonGC) 1055 Diag(Loc, diag::warn_objc_property_default_assign_on_object); 1056 1057 // FIXME: Implement warning dependent on NSCopying being 1058 // implemented. See also: 1059 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496> 1060 // (please trim this list while you are at it). 1061 } 1062 1063 if (!(Attributes & ObjCDeclSpec::DQ_PR_copy) 1064 && getLangOptions().getGCMode() == LangOptions::GCOnly 1065 && PropertyTy->isBlockPointerType()) 1066 Diag(Loc, diag::warn_objc_property_copy_missing_on_block); 1067} 1068 1069ObjCIvarDecl* 1070Sema::SynthesizeNewPropertyIvar(ObjCInterfaceDecl *IDecl, 1071 IdentifierInfo *NameII) { 1072 ObjCIvarDecl *Ivar = 0; 1073 ObjCPropertyDecl *Prop = LookupPropertyDecl(IDecl, NameII); 1074 if (Prop && !Prop->isInvalidDecl()) { 1075 QualType PropType = Context.getCanonicalType(Prop->getType()); 1076 Ivar = ObjCIvarDecl::Create(Context, IDecl, Prop->getLocation(), NameII, 1077 PropType, /*Dinfo=*/0, 1078 ObjCIvarDecl::Public, (Expr *)0); 1079 Ivar->setLexicalDeclContext(IDecl); 1080 IDecl->addDecl(Ivar); 1081 Prop->setPropertyIvarDecl(Ivar); 1082 } 1083 return Ivar; 1084} 1085 1086