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