SemaObjCProperty.cpp revision 293a45e724a15fb58b8805a5791f9f3aee769cf6
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 SourceLocation Loc = PropertyIvarLoc; 445 if (Loc.isInvalid()) 446 Loc = PropertyLoc; 447 compat = (CheckAssignmentConstraints(Loc, PropType, IvarType) 448 == Compatible); 449 } 450 if (!compat) { 451 Diag(PropertyLoc, diag::error_property_ivar_type) 452 << property->getDeclName() << PropType 453 << Ivar->getDeclName() << IvarType; 454 Diag(Ivar->getLocation(), diag::note_ivar_decl); 455 // Note! I deliberately want it to fall thru so, we have a 456 // a property implementation and to avoid future warnings. 457 } 458 459 // FIXME! Rules for properties are somewhat different that those 460 // for assignments. Use a new routine to consolidate all cases; 461 // specifically for property redeclarations as well as for ivars. 462 QualType lhsType =Context.getCanonicalType(PropType).getUnqualifiedType(); 463 QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType(); 464 if (lhsType != rhsType && 465 lhsType->isArithmeticType()) { 466 Diag(PropertyLoc, diag::error_property_ivar_type) 467 << property->getDeclName() << PropType 468 << Ivar->getDeclName() << IvarType; 469 Diag(Ivar->getLocation(), diag::note_ivar_decl); 470 // Fall thru - see previous comment 471 } 472 // __weak is explicit. So it works on Canonical type. 473 if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() && 474 getLangOptions().getGCMode() != LangOptions::NonGC) { 475 Diag(PropertyLoc, diag::error_weak_property) 476 << property->getDeclName() << Ivar->getDeclName(); 477 // Fall thru - see previous comment 478 } 479 if ((property->getType()->isObjCObjectPointerType() || 480 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() && 481 getLangOptions().getGCMode() != LangOptions::NonGC) { 482 Diag(PropertyLoc, diag::error_strong_property) 483 << property->getDeclName() << Ivar->getDeclName(); 484 // Fall thru - see previous comment 485 } 486 } 487 } else if (PropertyIvar) 488 // @dynamic 489 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl); 490 assert (property && "ActOnPropertyImplDecl - property declaration missing"); 491 ObjCPropertyImplDecl *PIDecl = 492 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, 493 property, 494 (Synthesize ? 495 ObjCPropertyImplDecl::Synthesize 496 : ObjCPropertyImplDecl::Dynamic), 497 Ivar, PropertyIvarLoc); 498 if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) { 499 getterMethod->createImplicitParams(Context, IDecl); 500 if (getLangOptions().CPlusPlus && Synthesize && 501 Ivar->getType()->isRecordType()) { 502 // For Objective-C++, need to synthesize the AST for the IVAR object to be 503 // returned by the getter as it must conform to C++'s copy-return rules. 504 // FIXME. Eventually we want to do this for Objective-C as well. 505 ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); 506 DeclRefExpr *SelfExpr = 507 new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), 508 VK_RValue, SourceLocation()); 509 Expr *IvarRefExpr = 510 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 511 SelfExpr, true, true); 512 ExprResult Res = 513 PerformCopyInitialization(InitializedEntity::InitializeResult( 514 SourceLocation(), 515 getterMethod->getResultType(), 516 /*NRVO=*/false), 517 SourceLocation(), 518 Owned(IvarRefExpr)); 519 if (!Res.isInvalid()) { 520 Expr *ResExpr = Res.takeAs<Expr>(); 521 if (ResExpr) 522 ResExpr = MaybeCreateExprWithCleanups(ResExpr); 523 PIDecl->setGetterCXXConstructor(ResExpr); 524 } 525 } 526 } 527 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) { 528 setterMethod->createImplicitParams(Context, IDecl); 529 if (getLangOptions().CPlusPlus && Synthesize 530 && Ivar->getType()->isRecordType()) { 531 // FIXME. Eventually we want to do this for Objective-C as well. 532 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); 533 DeclRefExpr *SelfExpr = 534 new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), 535 VK_RValue, SourceLocation()); 536 Expr *lhs = 537 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 538 SelfExpr, true, true); 539 ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); 540 ParmVarDecl *Param = (*P); 541 Expr *rhs = new (Context) DeclRefExpr(Param, Param->getType(), 542 VK_LValue, SourceLocation()); 543 ExprResult Res = BuildBinOp(S, lhs->getLocEnd(), 544 BO_Assign, lhs, rhs); 545 PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>()); 546 } 547 } 548 549 if (IC) { 550 if (Synthesize) 551 if (ObjCPropertyImplDecl *PPIDecl = 552 IC->FindPropertyImplIvarDecl(PropertyIvar)) { 553 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 554 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 555 << PropertyIvar; 556 Diag(PPIDecl->getLocation(), diag::note_previous_use); 557 } 558 559 if (ObjCPropertyImplDecl *PPIDecl 560 = IC->FindPropertyImplDecl(PropertyId)) { 561 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 562 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 563 return 0; 564 } 565 IC->addPropertyImplementation(PIDecl); 566 if (getLangOptions().ObjCDefaultSynthProperties && 567 getLangOptions().ObjCNonFragileABI2) { 568 // Diagnose if an ivar was lazily synthesdized due to a previous 569 // use and if 1) property is @dynamic or 2) property is synthesized 570 // but it requires an ivar of different name. 571 ObjCInterfaceDecl *ClassDeclared=0; 572 ObjCIvarDecl *Ivar = 0; 573 if (!Synthesize) 574 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 575 else { 576 if (PropertyIvar && PropertyIvar != PropertyId) 577 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 578 } 579 // Issue diagnostics only if Ivar belongs to current class. 580 if (Ivar && Ivar->getSynthesize() && 581 IC->getClassInterface() == ClassDeclared) { 582 Diag(Ivar->getLocation(), diag::err_undeclared_var_use) 583 << PropertyId; 584 Ivar->setInvalidDecl(); 585 } 586 } 587 } else { 588 if (Synthesize) 589 if (ObjCPropertyImplDecl *PPIDecl = 590 CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) { 591 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 592 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 593 << PropertyIvar; 594 Diag(PPIDecl->getLocation(), diag::note_previous_use); 595 } 596 597 if (ObjCPropertyImplDecl *PPIDecl = 598 CatImplClass->FindPropertyImplDecl(PropertyId)) { 599 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 600 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 601 return 0; 602 } 603 CatImplClass->addPropertyImplementation(PIDecl); 604 } 605 606 return PIDecl; 607} 608 609//===----------------------------------------------------------------------===// 610// Helper methods. 611//===----------------------------------------------------------------------===// 612 613/// DiagnosePropertyMismatch - Compares two properties for their 614/// attributes and types and warns on a variety of inconsistencies. 615/// 616void 617Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, 618 ObjCPropertyDecl *SuperProperty, 619 const IdentifierInfo *inheritedName) { 620 ObjCPropertyDecl::PropertyAttributeKind CAttr = 621 Property->getPropertyAttributes(); 622 ObjCPropertyDecl::PropertyAttributeKind SAttr = 623 SuperProperty->getPropertyAttributes(); 624 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) 625 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) 626 Diag(Property->getLocation(), diag::warn_readonly_property) 627 << Property->getDeclName() << inheritedName; 628 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) 629 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) 630 Diag(Property->getLocation(), diag::warn_property_attribute) 631 << Property->getDeclName() << "copy" << inheritedName; 632 else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain) 633 != (SAttr & ObjCPropertyDecl::OBJC_PR_retain)) 634 Diag(Property->getLocation(), diag::warn_property_attribute) 635 << Property->getDeclName() << "retain" << inheritedName; 636 637 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) 638 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) 639 Diag(Property->getLocation(), diag::warn_property_attribute) 640 << Property->getDeclName() << "atomic" << inheritedName; 641 if (Property->getSetterName() != SuperProperty->getSetterName()) 642 Diag(Property->getLocation(), diag::warn_property_attribute) 643 << Property->getDeclName() << "setter" << inheritedName; 644 if (Property->getGetterName() != SuperProperty->getGetterName()) 645 Diag(Property->getLocation(), diag::warn_property_attribute) 646 << Property->getDeclName() << "getter" << inheritedName; 647 648 QualType LHSType = 649 Context.getCanonicalType(SuperProperty->getType()); 650 QualType RHSType = 651 Context.getCanonicalType(Property->getType()); 652 653 if (!Context.typesAreCompatible(LHSType, RHSType)) { 654 // FIXME: Incorporate this test with typesAreCompatible. 655 if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType()) 656 if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false)) 657 return; 658 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) 659 << Property->getType() << SuperProperty->getType() << inheritedName; 660 } 661} 662 663bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, 664 ObjCMethodDecl *GetterMethod, 665 SourceLocation Loc) { 666 if (GetterMethod && 667 GetterMethod->getResultType() != property->getType()) { 668 AssignConvertType result = Incompatible; 669 if (property->getType()->isObjCObjectPointerType()) 670 result = CheckAssignmentConstraints(Loc, GetterMethod->getResultType(), 671 property->getType()); 672 if (result != Compatible) { 673 Diag(Loc, diag::warn_accessor_property_type_mismatch) 674 << property->getDeclName() 675 << GetterMethod->getSelector(); 676 Diag(GetterMethod->getLocation(), diag::note_declared_at); 677 return true; 678 } 679 } 680 return false; 681} 682 683/// ComparePropertiesInBaseAndSuper - This routine compares property 684/// declarations in base and its super class, if any, and issues 685/// diagnostics in a variety of inconsistant situations. 686/// 687void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) { 688 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); 689 if (!SDecl) 690 return; 691 // FIXME: O(N^2) 692 for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(), 693 E = SDecl->prop_end(); S != E; ++S) { 694 ObjCPropertyDecl *SuperPDecl = (*S); 695 // Does property in super class has declaration in current class? 696 for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(), 697 E = IDecl->prop_end(); I != E; ++I) { 698 ObjCPropertyDecl *PDecl = (*I); 699 if (SuperPDecl->getIdentifier() == PDecl->getIdentifier()) 700 DiagnosePropertyMismatch(PDecl, SuperPDecl, 701 SDecl->getIdentifier()); 702 } 703 } 704} 705 706/// MatchOneProtocolPropertiesInClass - This routine goes thru the list 707/// of properties declared in a protocol and compares their attribute against 708/// the same property declared in the class or category. 709void 710Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl, 711 ObjCProtocolDecl *PDecl) { 712 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 713 if (!IDecl) { 714 // Category 715 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 716 assert (CatDecl && "MatchOneProtocolPropertiesInClass"); 717 if (!CatDecl->IsClassExtension()) 718 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 719 E = PDecl->prop_end(); P != E; ++P) { 720 ObjCPropertyDecl *Pr = (*P); 721 ObjCCategoryDecl::prop_iterator CP, CE; 722 // Is this property already in category's list of properties? 723 for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP!=CE; ++CP) 724 if ((*CP)->getIdentifier() == Pr->getIdentifier()) 725 break; 726 if (CP != CE) 727 // Property protocol already exist in class. Diagnose any mismatch. 728 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier()); 729 } 730 return; 731 } 732 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 733 E = PDecl->prop_end(); P != E; ++P) { 734 ObjCPropertyDecl *Pr = (*P); 735 ObjCInterfaceDecl::prop_iterator CP, CE; 736 // Is this property already in class's list of properties? 737 for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP) 738 if ((*CP)->getIdentifier() == Pr->getIdentifier()) 739 break; 740 if (CP != CE) 741 // Property protocol already exist in class. Diagnose any mismatch. 742 DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier()); 743 } 744} 745 746/// CompareProperties - This routine compares properties 747/// declared in 'ClassOrProtocol' objects (which can be a class or an 748/// inherited protocol with the list of properties for class/category 'CDecl' 749/// 750void Sema::CompareProperties(Decl *CDecl, Decl *ClassOrProtocol) { 751 Decl *ClassDecl = ClassOrProtocol; 752 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 753 754 if (!IDecl) { 755 // Category 756 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 757 assert (CatDecl && "CompareProperties"); 758 if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 759 for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(), 760 E = MDecl->protocol_end(); P != E; ++P) 761 // Match properties of category with those of protocol (*P) 762 MatchOneProtocolPropertiesInClass(CatDecl, *P); 763 764 // Go thru the list of protocols for this category and recursively match 765 // their properties with those in the category. 766 for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(), 767 E = CatDecl->protocol_end(); P != E; ++P) 768 CompareProperties(CatDecl, *P); 769 } else { 770 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 771 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 772 E = MD->protocol_end(); P != E; ++P) 773 MatchOneProtocolPropertiesInClass(CatDecl, *P); 774 } 775 return; 776 } 777 778 if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { 779 for (ObjCInterfaceDecl::all_protocol_iterator 780 P = MDecl->all_referenced_protocol_begin(), 781 E = MDecl->all_referenced_protocol_end(); P != E; ++P) 782 // Match properties of class IDecl with those of protocol (*P). 783 MatchOneProtocolPropertiesInClass(IDecl, *P); 784 785 // Go thru the list of protocols for this class and recursively match 786 // their properties with those declared in the class. 787 for (ObjCInterfaceDecl::all_protocol_iterator 788 P = IDecl->all_referenced_protocol_begin(), 789 E = IDecl->all_referenced_protocol_end(); P != E; ++P) 790 CompareProperties(IDecl, *P); 791 } else { 792 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 793 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 794 E = MD->protocol_end(); P != E; ++P) 795 MatchOneProtocolPropertiesInClass(IDecl, *P); 796 } 797} 798 799/// isPropertyReadonly - Return true if property is readonly, by searching 800/// for the property in the class and in its categories and implementations 801/// 802bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl, 803 ObjCInterfaceDecl *IDecl) { 804 // by far the most common case. 805 if (!PDecl->isReadOnly()) 806 return false; 807 // Even if property is ready only, if interface has a user defined setter, 808 // it is not considered read only. 809 if (IDecl->getInstanceMethod(PDecl->getSetterName())) 810 return false; 811 812 // Main class has the property as 'readonly'. Must search 813 // through the category list to see if the property's 814 // attribute has been over-ridden to 'readwrite'. 815 for (ObjCCategoryDecl *Category = IDecl->getCategoryList(); 816 Category; Category = Category->getNextClassCategory()) { 817 // Even if property is ready only, if a category has a user defined setter, 818 // it is not considered read only. 819 if (Category->getInstanceMethod(PDecl->getSetterName())) 820 return false; 821 ObjCPropertyDecl *P = 822 Category->FindPropertyDeclaration(PDecl->getIdentifier()); 823 if (P && !P->isReadOnly()) 824 return false; 825 } 826 827 // Also, check for definition of a setter method in the implementation if 828 // all else failed. 829 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) { 830 if (ObjCImplementationDecl *IMD = 831 dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) { 832 if (IMD->getInstanceMethod(PDecl->getSetterName())) 833 return false; 834 } else if (ObjCCategoryImplDecl *CIMD = 835 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 836 if (CIMD->getInstanceMethod(PDecl->getSetterName())) 837 return false; 838 } 839 } 840 // Lastly, look through the implementation (if one is in scope). 841 if (ObjCImplementationDecl *ImpDecl = IDecl->getImplementation()) 842 if (ImpDecl->getInstanceMethod(PDecl->getSetterName())) 843 return false; 844 // If all fails, look at the super class. 845 if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass()) 846 return isPropertyReadonly(PDecl, SIDecl); 847 return true; 848} 849 850/// CollectImmediateProperties - This routine collects all properties in 851/// the class and its conforming protocols; but not those it its super class. 852void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, 853 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap, 854 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap) { 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 // scan through class's protocols. 862 for (ObjCInterfaceDecl::all_protocol_iterator 863 PI = IDecl->all_referenced_protocol_begin(), 864 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) 865 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 866 } 867 if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) { 868 if (!CATDecl->IsClassExtension()) 869 for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(), 870 E = CATDecl->prop_end(); P != E; ++P) { 871 ObjCPropertyDecl *Prop = (*P); 872 PropMap[Prop->getIdentifier()] = Prop; 873 } 874 // scan through class's protocols. 875 for (ObjCCategoryDecl::protocol_iterator PI = CATDecl->protocol_begin(), 876 E = CATDecl->protocol_end(); PI != E; ++PI) 877 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 878 } 879 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 880 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 881 E = PDecl->prop_end(); P != E; ++P) { 882 ObjCPropertyDecl *Prop = (*P); 883 ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()]; 884 // Exclude property for protocols which conform to class's super-class, 885 // as super-class has to implement the property. 886 if (!PropertyFromSuper || PropertyFromSuper != Prop) { 887 ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()]; 888 if (!PropEntry) 889 PropEntry = Prop; 890 } 891 } 892 // scan through protocol's protocols. 893 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 894 E = PDecl->protocol_end(); PI != E; ++PI) 895 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 896 } 897} 898 899/// CollectClassPropertyImplementations - This routine collects list of 900/// properties to be implemented in the class. This includes, class's 901/// and its conforming protocols' properties. 902static void CollectClassPropertyImplementations(ObjCContainerDecl *CDecl, 903 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 904 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 905 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 906 E = IDecl->prop_end(); P != E; ++P) { 907 ObjCPropertyDecl *Prop = (*P); 908 PropMap[Prop->getIdentifier()] = Prop; 909 } 910 for (ObjCInterfaceDecl::all_protocol_iterator 911 PI = IDecl->all_referenced_protocol_begin(), 912 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) 913 CollectClassPropertyImplementations((*PI), PropMap); 914 } 915 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 916 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 917 E = PDecl->prop_end(); P != E; ++P) { 918 ObjCPropertyDecl *Prop = (*P); 919 PropMap[Prop->getIdentifier()] = Prop; 920 } 921 // scan through protocol's protocols. 922 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 923 E = PDecl->protocol_end(); PI != E; ++PI) 924 CollectClassPropertyImplementations((*PI), PropMap); 925 } 926} 927 928/// CollectSuperClassPropertyImplementations - This routine collects list of 929/// properties to be implemented in super class(s) and also coming from their 930/// conforming protocols. 931static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, 932 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 933 if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) { 934 while (SDecl) { 935 CollectClassPropertyImplementations(SDecl, PropMap); 936 SDecl = SDecl->getSuperClass(); 937 } 938 } 939} 940 941/// LookupPropertyDecl - Looks up a property in the current class and all 942/// its protocols. 943ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, 944 IdentifierInfo *II) { 945 if (const ObjCInterfaceDecl *IDecl = 946 dyn_cast<ObjCInterfaceDecl>(CDecl)) { 947 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 948 E = IDecl->prop_end(); P != E; ++P) { 949 ObjCPropertyDecl *Prop = (*P); 950 if (Prop->getIdentifier() == II) 951 return Prop; 952 } 953 // scan through class's protocols. 954 for (ObjCInterfaceDecl::all_protocol_iterator 955 PI = IDecl->all_referenced_protocol_begin(), 956 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) { 957 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 958 if (Prop) 959 return Prop; 960 } 961 } 962 else if (const ObjCProtocolDecl *PDecl = 963 dyn_cast<ObjCProtocolDecl>(CDecl)) { 964 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 965 E = PDecl->prop_end(); P != E; ++P) { 966 ObjCPropertyDecl *Prop = (*P); 967 if (Prop->getIdentifier() == II) 968 return Prop; 969 } 970 // scan through protocol's protocols. 971 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 972 E = PDecl->protocol_end(); PI != E; ++PI) { 973 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 974 if (Prop) 975 return Prop; 976 } 977 } 978 return 0; 979} 980 981/// DefaultSynthesizeProperties - This routine default synthesizes all 982/// properties which must be synthesized in class's @implementation. 983void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl, 984 ObjCInterfaceDecl *IDecl) { 985 986 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 987 CollectClassPropertyImplementations(IDecl, PropMap); 988 if (PropMap.empty()) 989 return; 990 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; 991 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 992 993 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 994 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 995 ObjCPropertyDecl *Prop = P->second; 996 // If property to be implemented in the super class, ignore. 997 if (SuperPropMap[Prop->getIdentifier()]) 998 continue; 999 // Is there a matching propery synthesize/dynamic? 1000 if (Prop->isInvalidDecl() || 1001 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 1002 IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) 1003 continue; 1004 // Property may have been synthesized by user. 1005 if (IMPDecl->FindPropertyImplDecl(Prop->getIdentifier())) 1006 continue; 1007 if (IMPDecl->getInstanceMethod(Prop->getGetterName())) { 1008 if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly) 1009 continue; 1010 if (IMPDecl->getInstanceMethod(Prop->getSetterName())) 1011 continue; 1012 } 1013 1014 1015 // We use invalid SourceLocations for the synthesized ivars since they 1016 // aren't really synthesized at a particular location; they just exist. 1017 // Saying that they are located at the @implementation isn't really going 1018 // to help users. 1019 ActOnPropertyImplDecl(S, SourceLocation(), SourceLocation(), 1020 true,IMPDecl, 1021 Prop->getIdentifier(), Prop->getIdentifier(), 1022 SourceLocation()); 1023 } 1024} 1025 1026void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, 1027 ObjCContainerDecl *CDecl, 1028 const llvm::DenseSet<Selector>& InsMap) { 1029 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; 1030 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) 1031 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 1032 1033 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 1034 CollectImmediateProperties(CDecl, PropMap, SuperPropMap); 1035 if (PropMap.empty()) 1036 return; 1037 1038 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap; 1039 for (ObjCImplDecl::propimpl_iterator 1040 I = IMPDecl->propimpl_begin(), 1041 EI = IMPDecl->propimpl_end(); I != EI; ++I) 1042 PropImplMap.insert((*I)->getPropertyDecl()); 1043 1044 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 1045 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1046 ObjCPropertyDecl *Prop = P->second; 1047 // Is there a matching propery synthesize/dynamic? 1048 if (Prop->isInvalidDecl() || 1049 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 1050 PropImplMap.count(Prop)) 1051 continue; 1052 if (!InsMap.count(Prop->getGetterName())) { 1053 Diag(Prop->getLocation(), 1054 isa<ObjCCategoryDecl>(CDecl) ? 1055 diag::warn_setter_getter_impl_required_in_category : 1056 diag::warn_setter_getter_impl_required) 1057 << Prop->getDeclName() << Prop->getGetterName(); 1058 Diag(IMPDecl->getLocation(), 1059 diag::note_property_impl_required); 1060 } 1061 1062 if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) { 1063 Diag(Prop->getLocation(), 1064 isa<ObjCCategoryDecl>(CDecl) ? 1065 diag::warn_setter_getter_impl_required_in_category : 1066 diag::warn_setter_getter_impl_required) 1067 << Prop->getDeclName() << Prop->getSetterName(); 1068 Diag(IMPDecl->getLocation(), 1069 diag::note_property_impl_required); 1070 } 1071 } 1072} 1073 1074void 1075Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, 1076 ObjCContainerDecl* IDecl) { 1077 // Rules apply in non-GC mode only 1078 if (getLangOptions().getGCMode() != LangOptions::NonGC) 1079 return; 1080 for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(), 1081 E = IDecl->prop_end(); 1082 I != E; ++I) { 1083 ObjCPropertyDecl *Property = (*I); 1084 ObjCMethodDecl *GetterMethod = 0; 1085 ObjCMethodDecl *SetterMethod = 0; 1086 bool LookedUpGetterSetter = false; 1087 1088 unsigned Attributes = Property->getPropertyAttributes(); 1089 unsigned AttributesAsWrittern = Property->getPropertyAttributesAsWritten(); 1090 1091 if (!(AttributesAsWrittern & ObjCPropertyDecl::OBJC_PR_atomic) && 1092 !(AttributesAsWrittern & ObjCPropertyDecl::OBJC_PR_nonatomic)) { 1093 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1094 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1095 LookedUpGetterSetter = true; 1096 if (GetterMethod) { 1097 Diag(GetterMethod->getLocation(), 1098 diag::warn_default_atomic_custom_getter_setter) 1099 << Property->getIdentifier() << 0; 1100 Diag(Property->getLocation(), diag::note_property_declare); 1101 } 1102 if (SetterMethod) { 1103 Diag(SetterMethod->getLocation(), 1104 diag::warn_default_atomic_custom_getter_setter) 1105 << Property->getIdentifier() << 1; 1106 Diag(Property->getLocation(), diag::note_property_declare); 1107 } 1108 } 1109 1110 // We only care about readwrite atomic property. 1111 if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) || 1112 !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite)) 1113 continue; 1114 if (const ObjCPropertyImplDecl *PIDecl 1115 = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) { 1116 if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 1117 continue; 1118 if (!LookedUpGetterSetter) { 1119 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1120 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1121 LookedUpGetterSetter = true; 1122 } 1123 if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { 1124 SourceLocation MethodLoc = 1125 (GetterMethod ? GetterMethod->getLocation() 1126 : SetterMethod->getLocation()); 1127 Diag(MethodLoc, diag::warn_atomic_property_rule) 1128 << Property->getIdentifier(); 1129 Diag(Property->getLocation(), diag::note_property_declare); 1130 } 1131 } 1132 } 1133} 1134 1135/// AddPropertyAttrs - Propagates attributes from a property to the 1136/// implicitly-declared getter or setter for that property. 1137static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, 1138 ObjCPropertyDecl *Property) { 1139 // Should we just clone all attributes over? 1140 if (DeprecatedAttr *A = Property->getAttr<DeprecatedAttr>()) 1141 PropertyMethod->addAttr(A->clone(S.Context)); 1142 if (UnavailableAttr *A = Property->getAttr<UnavailableAttr>()) 1143 PropertyMethod->addAttr(A->clone(S.Context)); 1144} 1145 1146/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods 1147/// have the property type and issue diagnostics if they don't. 1148/// Also synthesize a getter/setter method if none exist (and update the 1149/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized 1150/// methods is the "right" thing to do. 1151void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, 1152 ObjCContainerDecl *CD, 1153 ObjCPropertyDecl *redeclaredProperty, 1154 ObjCContainerDecl *lexicalDC) { 1155 1156 ObjCMethodDecl *GetterMethod, *SetterMethod; 1157 1158 GetterMethod = CD->getInstanceMethod(property->getGetterName()); 1159 SetterMethod = CD->getInstanceMethod(property->getSetterName()); 1160 DiagnosePropertyAccessorMismatch(property, GetterMethod, 1161 property->getLocation()); 1162 1163 if (SetterMethod) { 1164 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1165 property->getPropertyAttributes(); 1166 if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) && 1167 Context.getCanonicalType(SetterMethod->getResultType()) != 1168 Context.VoidTy) 1169 Diag(SetterMethod->getLocation(), diag::err_setter_type_void); 1170 if (SetterMethod->param_size() != 1 || 1171 ((*SetterMethod->param_begin())->getType() != property->getType())) { 1172 Diag(property->getLocation(), 1173 diag::warn_accessor_property_type_mismatch) 1174 << property->getDeclName() 1175 << SetterMethod->getSelector(); 1176 Diag(SetterMethod->getLocation(), diag::note_declared_at); 1177 } 1178 } 1179 1180 // Synthesize getter/setter methods if none exist. 1181 // Find the default getter and if one not found, add one. 1182 // FIXME: The synthesized property we set here is misleading. We almost always 1183 // synthesize these methods unless the user explicitly provided prototypes 1184 // (which is odd, but allowed). Sema should be typechecking that the 1185 // declarations jive in that situation (which it is not currently). 1186 if (!GetterMethod) { 1187 // No instance method of same name as property getter name was found. 1188 // Declare a getter method and add it to the list of methods 1189 // for this class. 1190 SourceLocation Loc = redeclaredProperty ? 1191 redeclaredProperty->getLocation() : 1192 property->getLocation(); 1193 1194 GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc, 1195 property->getGetterName(), 1196 property->getType(), 0, CD, true, false, true, 1197 false, 1198 (property->getPropertyImplementation() == 1199 ObjCPropertyDecl::Optional) ? 1200 ObjCMethodDecl::Optional : 1201 ObjCMethodDecl::Required); 1202 CD->addDecl(GetterMethod); 1203 1204 AddPropertyAttrs(*this, GetterMethod, property); 1205 1206 // FIXME: Eventually this shouldn't be needed, as the lexical context 1207 // and the real context should be the same. 1208 if (lexicalDC) 1209 GetterMethod->setLexicalDeclContext(lexicalDC); 1210 } else 1211 // A user declared getter will be synthesize when @synthesize of 1212 // the property with the same name is seen in the @implementation 1213 GetterMethod->setSynthesized(true); 1214 property->setGetterMethodDecl(GetterMethod); 1215 1216 // Skip setter if property is read-only. 1217 if (!property->isReadOnly()) { 1218 // Find the default setter and if one not found, add one. 1219 if (!SetterMethod) { 1220 // No instance method of same name as property setter name was found. 1221 // Declare a setter method and add it to the list of methods 1222 // for this class. 1223 SourceLocation Loc = redeclaredProperty ? 1224 redeclaredProperty->getLocation() : 1225 property->getLocation(); 1226 1227 SetterMethod = 1228 ObjCMethodDecl::Create(Context, Loc, Loc, 1229 property->getSetterName(), Context.VoidTy, 0, 1230 CD, true, false, true, false, 1231 (property->getPropertyImplementation() == 1232 ObjCPropertyDecl::Optional) ? 1233 ObjCMethodDecl::Optional : 1234 ObjCMethodDecl::Required); 1235 1236 // Invent the arguments for the setter. We don't bother making a 1237 // nice name for the argument. 1238 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, Loc, 1239 property->getIdentifier(), 1240 property->getType(), 1241 /*TInfo=*/0, 1242 SC_None, 1243 SC_None, 1244 0); 1245 SetterMethod->setMethodParams(Context, &Argument, 1, 1); 1246 1247 AddPropertyAttrs(*this, SetterMethod, property); 1248 1249 CD->addDecl(SetterMethod); 1250 // FIXME: Eventually this shouldn't be needed, as the lexical context 1251 // and the real context should be the same. 1252 if (lexicalDC) 1253 SetterMethod->setLexicalDeclContext(lexicalDC); 1254 } else 1255 // A user declared setter will be synthesize when @synthesize of 1256 // the property with the same name is seen in the @implementation 1257 SetterMethod->setSynthesized(true); 1258 property->setSetterMethodDecl(SetterMethod); 1259 } 1260 // Add any synthesized methods to the global pool. This allows us to 1261 // handle the following, which is supported by GCC (and part of the design). 1262 // 1263 // @interface Foo 1264 // @property double bar; 1265 // @end 1266 // 1267 // void thisIsUnfortunate() { 1268 // id foo; 1269 // double bar = [foo bar]; 1270 // } 1271 // 1272 if (GetterMethod) 1273 AddInstanceMethodToGlobalPool(GetterMethod); 1274 if (SetterMethod) 1275 AddInstanceMethodToGlobalPool(SetterMethod); 1276} 1277 1278void Sema::CheckObjCPropertyAttributes(Decl *PDecl, 1279 SourceLocation Loc, 1280 unsigned &Attributes) { 1281 // FIXME: Improve the reported location. 1282 if (!PDecl) 1283 return; 1284 1285 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 1286 QualType PropertyTy = PropertyDecl->getType(); 1287 1288 // readonly and readwrite/assign/retain/copy conflict. 1289 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1290 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 1291 ObjCDeclSpec::DQ_PR_assign | 1292 ObjCDeclSpec::DQ_PR_copy | 1293 ObjCDeclSpec::DQ_PR_retain))) { 1294 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ? 1295 "readwrite" : 1296 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 1297 "assign" : 1298 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 1299 "copy" : "retain"; 1300 1301 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 1302 diag::err_objc_property_attr_mutually_exclusive : 1303 diag::warn_objc_property_attr_mutually_exclusive) 1304 << "readonly" << which; 1305 } 1306 1307 // Check for copy or retain on non-object types. 1308 if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) && 1309 !PropertyTy->isObjCObjectPointerType() && 1310 !PropertyTy->isBlockPointerType() && 1311 !Context.isObjCNSObjectType(PropertyTy) && 1312 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { 1313 Diag(Loc, diag::err_objc_property_requires_object) 1314 << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain"); 1315 Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain); 1316 } 1317 1318 // Check for more than one of { assign, copy, retain }. 1319 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 1320 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1321 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1322 << "assign" << "copy"; 1323 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1324 } 1325 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1326 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1327 << "assign" << "retain"; 1328 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1329 } 1330 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1331 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1332 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1333 << "copy" << "retain"; 1334 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1335 } 1336 } 1337 1338 // Warn if user supplied no assignment attribute, property is 1339 // readwrite, and this is an object type. 1340 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | 1341 ObjCDeclSpec::DQ_PR_retain)) && 1342 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1343 PropertyTy->isObjCObjectPointerType()) { 1344 // Skip this warning in gc-only mode. 1345 if (getLangOptions().getGCMode() != LangOptions::GCOnly) 1346 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 1347 1348 // If non-gc code warn that this is likely inappropriate. 1349 if (getLangOptions().getGCMode() == LangOptions::NonGC) 1350 Diag(Loc, diag::warn_objc_property_default_assign_on_object); 1351 1352 // FIXME: Implement warning dependent on NSCopying being 1353 // implemented. See also: 1354 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496> 1355 // (please trim this list while you are at it). 1356 } 1357 1358 if (!(Attributes & ObjCDeclSpec::DQ_PR_copy) 1359 &&!(Attributes & ObjCDeclSpec::DQ_PR_readonly) 1360 && getLangOptions().getGCMode() == LangOptions::GCOnly 1361 && PropertyTy->isBlockPointerType()) 1362 Diag(Loc, diag::warn_objc_property_copy_missing_on_block); 1363} 1364