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