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