SemaObjCProperty.cpp revision b92003b3d8d6128be3daa0b3f40a042a08545644
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 49 // Proceed with constructing the ObjCPropertDecls. 50 ObjCContainerDecl *ClassDecl = 51 cast<ObjCContainerDecl>(ClassCategory); 52 53 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) 54 if (CDecl->IsClassExtension()) { 55 Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc, 56 FD, GetterSel, SetterSel, 57 isAssign, isReadWrite, 58 Attributes, 59 isOverridingProperty, TSI, 60 MethodImplKind); 61 if (Res) 62 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); 63 return Res; 64 } 65 66 Decl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, FD, 67 GetterSel, SetterSel, 68 isAssign, isReadWrite, 69 Attributes, TSI, MethodImplKind); 70 if (lexicalDC) 71 Res->setLexicalDeclContext(lexicalDC); 72 73 // Validate the attributes on the @property. 74 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); 75 return Res; 76} 77 78Decl * 79Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl, 80 SourceLocation AtLoc, FieldDeclarator &FD, 81 Selector GetterSel, Selector SetterSel, 82 const bool isAssign, 83 const bool isReadWrite, 84 const unsigned Attributes, 85 bool *isOverridingProperty, 86 TypeSourceInfo *T, 87 tok::ObjCKeywordKind MethodImplKind) { 88 89 // Diagnose if this property is already in continuation class. 90 DeclContext *DC = cast<DeclContext>(CDecl); 91 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 92 ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface(); 93 94 if (CCPrimary) 95 // Check for duplicate declaration of this property in current and 96 // other class extensions. 97 for (const ObjCCategoryDecl *ClsExtDecl = 98 CCPrimary->getFirstClassExtension(); 99 ClsExtDecl; ClsExtDecl = ClsExtDecl->getNextClassExtension()) { 100 if (ObjCPropertyDecl *prevDecl = 101 ObjCPropertyDecl::findPropertyDecl(ClsExtDecl, PropertyId)) { 102 Diag(AtLoc, diag::err_duplicate_property); 103 Diag(prevDecl->getLocation(), diag::note_property_declare); 104 return 0; 105 } 106 } 107 108 // Create a new ObjCPropertyDecl with the DeclContext being 109 // the class extension. 110 // FIXME. We should really be using CreatePropertyDecl for this. 111 ObjCPropertyDecl *PDecl = 112 ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(), 113 PropertyId, AtLoc, T); 114 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 115 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 116 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 117 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 118 // Set setter/getter selector name. Needed later. 119 PDecl->setGetterName(GetterSel); 120 PDecl->setSetterName(SetterSel); 121 DC->addDecl(PDecl); 122 123 // We need to look in the @interface to see if the @property was 124 // already declared. 125 if (!CCPrimary) { 126 Diag(CDecl->getLocation(), diag::err_continuation_class); 127 *isOverridingProperty = true; 128 return 0; 129 } 130 131 // Find the property in continuation class's primary class only. 132 ObjCPropertyDecl *PIDecl = 133 CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId); 134 135 if (!PIDecl) { 136 // No matching property found in the primary class. Just fall thru 137 // and add property to continuation class's primary class. 138 ObjCPropertyDecl *PDecl = 139 CreatePropertyDecl(S, CCPrimary, AtLoc, 140 FD, GetterSel, SetterSel, isAssign, isReadWrite, 141 Attributes, T, MethodImplKind, DC); 142 // Mark written attribute as having no attribute because 143 // this is not a user-written property declaration in primary 144 // class. 145 PDecl->setPropertyAttributesAsWritten(ObjCPropertyDecl::OBJC_PR_noattr); 146 147 // A case of continuation class adding a new property in the class. This 148 // is not what it was meant for. However, gcc supports it and so should we. 149 // Make sure setter/getters are declared here. 150 ProcessPropertyDecl(PDecl, CCPrimary, /* redeclaredProperty = */ 0, 151 /* lexicalDC = */ CDecl); 152 return PDecl; 153 } 154 155 // The property 'PIDecl's readonly attribute will be over-ridden 156 // with continuation class's readwrite property attribute! 157 unsigned PIkind = PIDecl->getPropertyAttributesAsWritten(); 158 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { 159 unsigned retainCopyNonatomic = 160 (ObjCPropertyDecl::OBJC_PR_retain | 161 ObjCPropertyDecl::OBJC_PR_copy | 162 ObjCPropertyDecl::OBJC_PR_nonatomic); 163 if ((Attributes & retainCopyNonatomic) != 164 (PIkind & retainCopyNonatomic)) { 165 Diag(AtLoc, diag::warn_property_attr_mismatch); 166 Diag(PIDecl->getLocation(), diag::note_property_declare); 167 } 168 DeclContext *DC = cast<DeclContext>(CCPrimary); 169 if (!ObjCPropertyDecl::findPropertyDecl(DC, 170 PIDecl->getDeclName().getAsIdentifierInfo())) { 171 // Protocol is not in the primary class. Must build one for it. 172 ObjCDeclSpec ProtocolPropertyODS; 173 // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind 174 // and ObjCPropertyDecl::PropertyAttributeKind have identical 175 // values. Should consolidate both into one enum type. 176 ProtocolPropertyODS. 177 setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind) 178 PIkind); 179 180 Decl *ProtocolPtrTy = 181 ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS, 182 PIDecl->getGetterName(), 183 PIDecl->getSetterName(), 184 CCPrimary, isOverridingProperty, 185 MethodImplKind, 186 /* lexicalDC = */ CDecl); 187 PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy); 188 } 189 PIDecl->makeitReadWriteAttribute(); 190 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 191 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 192 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 193 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 194 PIDecl->setSetterName(SetterSel); 195 } else { 196 // Tailor the diagnostics for the common case where a readwrite 197 // property is declared both in the @interface and the continuation. 198 // This is a common error where the user often intended the original 199 // declaration to be readonly. 200 unsigned diag = 201 (Attributes & ObjCDeclSpec::DQ_PR_readwrite) && 202 (PIkind & ObjCPropertyDecl::OBJC_PR_readwrite) 203 ? diag::err_use_continuation_class_redeclaration_readwrite 204 : diag::err_use_continuation_class; 205 Diag(AtLoc, diag) 206 << CCPrimary->getDeclName(); 207 Diag(PIDecl->getLocation(), diag::note_property_declare); 208 } 209 *isOverridingProperty = true; 210 // Make sure setter decl is synthesized, and added to primary class's list. 211 ProcessPropertyDecl(PIDecl, CCPrimary, PDecl, CDecl); 212 return 0; 213} 214 215ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, 216 ObjCContainerDecl *CDecl, 217 SourceLocation AtLoc, 218 FieldDeclarator &FD, 219 Selector GetterSel, 220 Selector SetterSel, 221 const bool isAssign, 222 const bool isReadWrite, 223 const unsigned Attributes, 224 TypeSourceInfo *TInfo, 225 tok::ObjCKeywordKind MethodImplKind, 226 DeclContext *lexicalDC){ 227 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 228 QualType T = TInfo->getType(); 229 230 // Issue a warning if property is 'assign' as default and its object, which is 231 // gc'able conforms to NSCopying protocol 232 if (getLangOptions().getGCMode() != LangOptions::NonGC && 233 isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign)) 234 if (const ObjCObjectPointerType *ObjPtrTy = 235 T->getAs<ObjCObjectPointerType>()) { 236 ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface(); 237 if (IDecl) 238 if (ObjCProtocolDecl* PNSCopying = 239 LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc)) 240 if (IDecl->ClassImplementsProtocol(PNSCopying, true)) 241 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId; 242 } 243 if (T->isObjCObjectType()) 244 Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object); 245 246 DeclContext *DC = cast<DeclContext>(CDecl); 247 ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC, 248 FD.D.getIdentifierLoc(), 249 PropertyId, AtLoc, TInfo); 250 251 if (ObjCPropertyDecl *prevDecl = 252 ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) { 253 Diag(PDecl->getLocation(), diag::err_duplicate_property); 254 Diag(prevDecl->getLocation(), diag::note_property_declare); 255 PDecl->setInvalidDecl(); 256 } 257 else { 258 DC->addDecl(PDecl); 259 if (lexicalDC) 260 PDecl->setLexicalDeclContext(lexicalDC); 261 } 262 263 if (T->isArrayType() || T->isFunctionType()) { 264 Diag(AtLoc, diag::err_property_type) << T; 265 PDecl->setInvalidDecl(); 266 } 267 268 ProcessDeclAttributes(S, PDecl, FD.D); 269 270 // Regardless of setter/getter attribute, we save the default getter/setter 271 // selector names in anticipation of declaration of setter/getter methods. 272 PDecl->setGetterName(GetterSel); 273 PDecl->setSetterName(SetterSel); 274 275 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 276 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 277 278 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 279 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter); 280 281 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 282 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter); 283 284 if (isReadWrite) 285 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 286 287 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 288 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 289 290 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 291 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 292 293 if (isAssign) 294 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 295 296 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 297 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); 298 299 PDecl->setPropertyAttributesAsWritten(PDecl->getPropertyAttributes()); 300 301 if (MethodImplKind == tok::objc_required) 302 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required); 303 else if (MethodImplKind == tok::objc_optional) 304 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional); 305 306 return PDecl; 307} 308 309 310/// ActOnPropertyImplDecl - This routine performs semantic checks and 311/// builds the AST node for a property implementation declaration; declared 312/// as @synthesize or @dynamic. 313/// 314Decl *Sema::ActOnPropertyImplDecl(Scope *S, 315 SourceLocation AtLoc, 316 SourceLocation PropertyLoc, 317 bool Synthesize, 318 Decl *ClassCatImpDecl, 319 IdentifierInfo *PropertyId, 320 IdentifierInfo *PropertyIvar, 321 SourceLocation PropertyIvarLoc) { 322 ObjCContainerDecl *ClassImpDecl = 323 cast_or_null<ObjCContainerDecl>(ClassCatImpDecl); 324 // Make sure we have a context for the property implementation declaration. 325 if (!ClassImpDecl) { 326 Diag(AtLoc, diag::error_missing_property_context); 327 return 0; 328 } 329 ObjCPropertyDecl *property = 0; 330 ObjCInterfaceDecl* IDecl = 0; 331 // Find the class or category class where this property must have 332 // a declaration. 333 ObjCImplementationDecl *IC = 0; 334 ObjCCategoryImplDecl* CatImplClass = 0; 335 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) { 336 IDecl = IC->getClassInterface(); 337 // We always synthesize an interface for an implementation 338 // without an interface decl. So, IDecl is always non-zero. 339 assert(IDecl && 340 "ActOnPropertyImplDecl - @implementation without @interface"); 341 342 // Look for this property declaration in the @implementation's @interface 343 property = IDecl->FindPropertyDeclaration(PropertyId); 344 if (!property) { 345 Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName(); 346 return 0; 347 } 348 unsigned PIkind = property->getPropertyAttributesAsWritten(); 349 if ((PIkind & ObjCPropertyDecl::OBJC_PR_nonatomic) == 0) { 350 if (AtLoc.isValid()) 351 Diag(AtLoc, diag::warn_implicit_atomic_property); 352 else 353 Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property); 354 Diag(property->getLocation(), diag::note_property_declare); 355 } 356 357 if (const ObjCCategoryDecl *CD = 358 dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) { 359 if (!CD->IsClassExtension()) { 360 Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName(); 361 Diag(property->getLocation(), diag::note_property_declare); 362 return 0; 363 } 364 } 365 } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) { 366 if (Synthesize) { 367 Diag(AtLoc, diag::error_synthesize_category_decl); 368 return 0; 369 } 370 IDecl = CatImplClass->getClassInterface(); 371 if (!IDecl) { 372 Diag(AtLoc, diag::error_missing_property_interface); 373 return 0; 374 } 375 ObjCCategoryDecl *Category = 376 IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier()); 377 378 // If category for this implementation not found, it is an error which 379 // has already been reported eralier. 380 if (!Category) 381 return 0; 382 // Look for this property declaration in @implementation's category 383 property = Category->FindPropertyDeclaration(PropertyId); 384 if (!property) { 385 Diag(PropertyLoc, diag::error_bad_category_property_decl) 386 << Category->getDeclName(); 387 return 0; 388 } 389 } else { 390 Diag(AtLoc, diag::error_bad_property_context); 391 return 0; 392 } 393 ObjCIvarDecl *Ivar = 0; 394 // Check that we have a valid, previously declared ivar for @synthesize 395 if (Synthesize) { 396 // @synthesize 397 if (!PropertyIvar) 398 PropertyIvar = PropertyId; 399 QualType PropType = Context.getCanonicalType(property->getType()); 400 QualType PropertyIvarType = PropType; 401 if (PropType->isReferenceType()) 402 PropertyIvarType = cast<ReferenceType>(PropType)->getPointeeType(); 403 // Check that this is a previously declared 'ivar' in 'IDecl' interface 404 ObjCInterfaceDecl *ClassDeclared; 405 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared); 406 if (!Ivar) { 407 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, 408 PropertyLoc, PropertyLoc, PropertyIvar, 409 PropertyIvarType, /*Dinfo=*/0, 410 ObjCIvarDecl::Private, 411 (Expr *)0, true); 412 ClassImpDecl->addDecl(Ivar); 413 IDecl->makeDeclVisibleInContext(Ivar, false); 414 property->setPropertyIvarDecl(Ivar); 415 416 if (!getLangOptions().ObjCNonFragileABI) 417 Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId; 418 // Note! I deliberately want it to fall thru so, we have a 419 // a property implementation and to avoid future warnings. 420 } else if (getLangOptions().ObjCNonFragileABI && 421 ClassDeclared != IDecl) { 422 Diag(PropertyLoc, diag::error_ivar_in_superclass_use) 423 << property->getDeclName() << Ivar->getDeclName() 424 << ClassDeclared->getDeclName(); 425 Diag(Ivar->getLocation(), diag::note_previous_access_declaration) 426 << Ivar << Ivar->getName(); 427 // Note! I deliberately want it to fall thru so more errors are caught. 428 } 429 QualType IvarType = Context.getCanonicalType(Ivar->getType()); 430 431 // Check that type of property and its ivar are type compatible. 432 if (PropertyIvarType != IvarType) { 433 bool compat = false; 434 if (isa<ObjCObjectPointerType>(PropertyIvarType) 435 && isa<ObjCObjectPointerType>(IvarType)) 436 compat = 437 Context.canAssignObjCInterfaces( 438 PropertyIvarType->getAs<ObjCObjectPointerType>(), 439 IvarType->getAs<ObjCObjectPointerType>()); 440 else { 441 SourceLocation Loc = PropertyIvarLoc; 442 if (Loc.isInvalid()) 443 Loc = PropertyLoc; 444 compat = (CheckAssignmentConstraints(Loc, PropertyIvarType, IvarType) 445 == Compatible); 446 } 447 if (!compat) { 448 Diag(PropertyLoc, diag::error_property_ivar_type) 449 << property->getDeclName() << PropType 450 << Ivar->getDeclName() << IvarType; 451 Diag(Ivar->getLocation(), diag::note_ivar_decl); 452 // Note! I deliberately want it to fall thru so, we have a 453 // a property implementation and to avoid future warnings. 454 } 455 456 // FIXME! Rules for properties are somewhat different that those 457 // for assignments. Use a new routine to consolidate all cases; 458 // specifically for property redeclarations as well as for ivars. 459 QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType(); 460 QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType(); 461 if (lhsType != rhsType && 462 lhsType->isArithmeticType()) { 463 Diag(PropertyLoc, diag::error_property_ivar_type) 464 << property->getDeclName() << PropType 465 << Ivar->getDeclName() << IvarType; 466 Diag(Ivar->getLocation(), diag::note_ivar_decl); 467 // Fall thru - see previous comment 468 } 469 // __weak is explicit. So it works on Canonical type. 470 if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() && 471 getLangOptions().getGCMode() != LangOptions::NonGC) { 472 Diag(PropertyLoc, diag::error_weak_property) 473 << property->getDeclName() << Ivar->getDeclName(); 474 // Fall thru - see previous comment 475 } 476 if ((property->getType()->isObjCObjectPointerType() || 477 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() && 478 getLangOptions().getGCMode() != LangOptions::NonGC) { 479 Diag(PropertyLoc, diag::error_strong_property) 480 << property->getDeclName() << Ivar->getDeclName(); 481 // Fall thru - see previous comment 482 } 483 } 484 } else if (PropertyIvar) 485 // @dynamic 486 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl); 487 assert (property && "ActOnPropertyImplDecl - property declaration missing"); 488 ObjCPropertyImplDecl *PIDecl = 489 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, 490 property, 491 (Synthesize ? 492 ObjCPropertyImplDecl::Synthesize 493 : ObjCPropertyImplDecl::Dynamic), 494 Ivar, PropertyIvarLoc); 495 if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) { 496 getterMethod->createImplicitParams(Context, IDecl); 497 if (getLangOptions().CPlusPlus && Synthesize && 498 Ivar->getType()->isRecordType()) { 499 // For Objective-C++, need to synthesize the AST for the IVAR object to be 500 // returned by the getter as it must conform to C++'s copy-return rules. 501 // FIXME. Eventually we want to do this for Objective-C as well. 502 ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); 503 DeclRefExpr *SelfExpr = 504 new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), 505 VK_RValue, SourceLocation()); 506 Expr *IvarRefExpr = 507 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 508 SelfExpr, true, true); 509 ExprResult Res = 510 PerformCopyInitialization(InitializedEntity::InitializeResult( 511 SourceLocation(), 512 getterMethod->getResultType(), 513 /*NRVO=*/false), 514 SourceLocation(), 515 Owned(IvarRefExpr)); 516 if (!Res.isInvalid()) { 517 Expr *ResExpr = Res.takeAs<Expr>(); 518 if (ResExpr) 519 ResExpr = MaybeCreateExprWithCleanups(ResExpr); 520 PIDecl->setGetterCXXConstructor(ResExpr); 521 } 522 } 523 } 524 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) { 525 setterMethod->createImplicitParams(Context, IDecl); 526 if (getLangOptions().CPlusPlus && Synthesize 527 && Ivar->getType()->isRecordType()) { 528 // FIXME. Eventually we want to do this for Objective-C as well. 529 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); 530 DeclRefExpr *SelfExpr = 531 new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), 532 VK_RValue, SourceLocation()); 533 Expr *lhs = 534 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 535 SelfExpr, true, true); 536 ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); 537 ParmVarDecl *Param = (*P); 538 QualType T = Param->getType(); 539 if (T->isReferenceType()) 540 T = T->getAs<ReferenceType>()->getPointeeType(); 541 Expr *rhs = new (Context) DeclRefExpr(Param, T, 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 inconsistent 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_nonatomic)) { 1092 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1093 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1094 LookedUpGetterSetter = true; 1095 if (GetterMethod) { 1096 Diag(GetterMethod->getLocation(), 1097 diag::warn_default_atomic_custom_getter_setter) 1098 << Property->getIdentifier() << 0; 1099 Diag(Property->getLocation(), diag::note_property_declare); 1100 } 1101 if (SetterMethod) { 1102 Diag(SetterMethod->getLocation(), 1103 diag::warn_default_atomic_custom_getter_setter) 1104 << Property->getIdentifier() << 1; 1105 Diag(Property->getLocation(), diag::note_property_declare); 1106 } 1107 } 1108 1109 // We only care about readwrite atomic property. 1110 if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) || 1111 !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite)) 1112 continue; 1113 if (const ObjCPropertyImplDecl *PIDecl 1114 = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) { 1115 if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 1116 continue; 1117 if (!LookedUpGetterSetter) { 1118 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1119 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1120 LookedUpGetterSetter = true; 1121 } 1122 if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { 1123 SourceLocation MethodLoc = 1124 (GetterMethod ? GetterMethod->getLocation() 1125 : SetterMethod->getLocation()); 1126 Diag(MethodLoc, diag::warn_atomic_property_rule) 1127 << Property->getIdentifier(); 1128 Diag(Property->getLocation(), diag::note_property_declare); 1129 } 1130 } 1131 } 1132} 1133 1134/// AddPropertyAttrs - Propagates attributes from a property to the 1135/// implicitly-declared getter or setter for that property. 1136static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, 1137 ObjCPropertyDecl *Property) { 1138 // Should we just clone all attributes over? 1139 for (Decl::attr_iterator A = Property->attr_begin(), 1140 AEnd = Property->attr_end(); 1141 A != AEnd; ++A) { 1142 if (isa<DeprecatedAttr>(*A) || 1143 isa<UnavailableAttr>(*A) || 1144 isa<AvailabilityAttr>(*A)) 1145 PropertyMethod->addAttr((*A)->clone(S.Context)); 1146 } 1147} 1148 1149/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods 1150/// have the property type and issue diagnostics if they don't. 1151/// Also synthesize a getter/setter method if none exist (and update the 1152/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized 1153/// methods is the "right" thing to do. 1154void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, 1155 ObjCContainerDecl *CD, 1156 ObjCPropertyDecl *redeclaredProperty, 1157 ObjCContainerDecl *lexicalDC) { 1158 1159 ObjCMethodDecl *GetterMethod, *SetterMethod; 1160 1161 GetterMethod = CD->getInstanceMethod(property->getGetterName()); 1162 SetterMethod = CD->getInstanceMethod(property->getSetterName()); 1163 DiagnosePropertyAccessorMismatch(property, GetterMethod, 1164 property->getLocation()); 1165 1166 if (SetterMethod) { 1167 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1168 property->getPropertyAttributes(); 1169 if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) && 1170 Context.getCanonicalType(SetterMethod->getResultType()) != 1171 Context.VoidTy) 1172 Diag(SetterMethod->getLocation(), diag::err_setter_type_void); 1173 if (SetterMethod->param_size() != 1 || 1174 ((*SetterMethod->param_begin())->getType() != property->getType())) { 1175 Diag(property->getLocation(), 1176 diag::warn_accessor_property_type_mismatch) 1177 << property->getDeclName() 1178 << SetterMethod->getSelector(); 1179 Diag(SetterMethod->getLocation(), diag::note_declared_at); 1180 } 1181 } 1182 1183 // Synthesize getter/setter methods if none exist. 1184 // Find the default getter and if one not found, add one. 1185 // FIXME: The synthesized property we set here is misleading. We almost always 1186 // synthesize these methods unless the user explicitly provided prototypes 1187 // (which is odd, but allowed). Sema should be typechecking that the 1188 // declarations jive in that situation (which it is not currently). 1189 if (!GetterMethod) { 1190 // No instance method of same name as property getter name was found. 1191 // Declare a getter 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 GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc, 1198 property->getGetterName(), 1199 property->getType(), 0, CD, true, false, true, 1200 false, 1201 (property->getPropertyImplementation() == 1202 ObjCPropertyDecl::Optional) ? 1203 ObjCMethodDecl::Optional : 1204 ObjCMethodDecl::Required); 1205 CD->addDecl(GetterMethod); 1206 1207 AddPropertyAttrs(*this, GetterMethod, property); 1208 1209 // FIXME: Eventually this shouldn't be needed, as the lexical context 1210 // and the real context should be the same. 1211 if (lexicalDC) 1212 GetterMethod->setLexicalDeclContext(lexicalDC); 1213 } else 1214 // A user declared getter will be synthesize when @synthesize of 1215 // the property with the same name is seen in the @implementation 1216 GetterMethod->setSynthesized(true); 1217 property->setGetterMethodDecl(GetterMethod); 1218 1219 // Skip setter if property is read-only. 1220 if (!property->isReadOnly()) { 1221 // Find the default setter and if one not found, add one. 1222 if (!SetterMethod) { 1223 // No instance method of same name as property setter name was found. 1224 // Declare a setter method and add it to the list of methods 1225 // for this class. 1226 SourceLocation Loc = redeclaredProperty ? 1227 redeclaredProperty->getLocation() : 1228 property->getLocation(); 1229 1230 SetterMethod = 1231 ObjCMethodDecl::Create(Context, Loc, Loc, 1232 property->getSetterName(), Context.VoidTy, 0, 1233 CD, true, false, true, false, 1234 (property->getPropertyImplementation() == 1235 ObjCPropertyDecl::Optional) ? 1236 ObjCMethodDecl::Optional : 1237 ObjCMethodDecl::Required); 1238 1239 // Invent the arguments for the setter. We don't bother making a 1240 // nice name for the argument. 1241 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, 1242 Loc, Loc, 1243 property->getIdentifier(), 1244 property->getType(), 1245 /*TInfo=*/0, 1246 SC_None, 1247 SC_None, 1248 0); 1249 SetterMethod->setMethodParams(Context, &Argument, 1, 1); 1250 1251 AddPropertyAttrs(*this, SetterMethod, property); 1252 1253 CD->addDecl(SetterMethod); 1254 // FIXME: Eventually this shouldn't be needed, as the lexical context 1255 // and the real context should be the same. 1256 if (lexicalDC) 1257 SetterMethod->setLexicalDeclContext(lexicalDC); 1258 } else 1259 // A user declared setter will be synthesize when @synthesize of 1260 // the property with the same name is seen in the @implementation 1261 SetterMethod->setSynthesized(true); 1262 property->setSetterMethodDecl(SetterMethod); 1263 } 1264 // Add any synthesized methods to the global pool. This allows us to 1265 // handle the following, which is supported by GCC (and part of the design). 1266 // 1267 // @interface Foo 1268 // @property double bar; 1269 // @end 1270 // 1271 // void thisIsUnfortunate() { 1272 // id foo; 1273 // double bar = [foo bar]; 1274 // } 1275 // 1276 if (GetterMethod) 1277 AddInstanceMethodToGlobalPool(GetterMethod); 1278 if (SetterMethod) 1279 AddInstanceMethodToGlobalPool(SetterMethod); 1280} 1281 1282void Sema::CheckObjCPropertyAttributes(Decl *PDecl, 1283 SourceLocation Loc, 1284 unsigned &Attributes) { 1285 // FIXME: Improve the reported location. 1286 if (!PDecl) 1287 return; 1288 1289 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 1290 QualType PropertyTy = PropertyDecl->getType(); 1291 1292 // readonly and readwrite/assign/retain/copy conflict. 1293 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1294 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 1295 ObjCDeclSpec::DQ_PR_assign | 1296 ObjCDeclSpec::DQ_PR_copy | 1297 ObjCDeclSpec::DQ_PR_retain))) { 1298 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ? 1299 "readwrite" : 1300 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 1301 "assign" : 1302 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 1303 "copy" : "retain"; 1304 1305 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 1306 diag::err_objc_property_attr_mutually_exclusive : 1307 diag::warn_objc_property_attr_mutually_exclusive) 1308 << "readonly" << which; 1309 } 1310 1311 // Check for copy or retain on non-object types. 1312 if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) && 1313 !PropertyTy->isObjCObjectPointerType() && 1314 !PropertyTy->isBlockPointerType() && 1315 !Context.isObjCNSObjectType(PropertyTy) && 1316 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { 1317 Diag(Loc, diag::err_objc_property_requires_object) 1318 << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain"); 1319 Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain); 1320 } 1321 1322 // Check for more than one of { assign, copy, retain }. 1323 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 1324 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1325 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1326 << "assign" << "copy"; 1327 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1328 } 1329 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1330 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1331 << "assign" << "retain"; 1332 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1333 } 1334 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1335 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1336 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1337 << "copy" << "retain"; 1338 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1339 } 1340 } 1341 1342 // Warn if user supplied no assignment attribute, property is 1343 // readwrite, and this is an object type. 1344 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | 1345 ObjCDeclSpec::DQ_PR_retain)) && 1346 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1347 PropertyTy->isObjCObjectPointerType()) { 1348 // Skip this warning in gc-only mode. 1349 if (getLangOptions().getGCMode() != LangOptions::GCOnly) 1350 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 1351 1352 // If non-gc code warn that this is likely inappropriate. 1353 if (getLangOptions().getGCMode() == LangOptions::NonGC) 1354 Diag(Loc, diag::warn_objc_property_default_assign_on_object); 1355 1356 // FIXME: Implement warning dependent on NSCopying being 1357 // implemented. See also: 1358 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496> 1359 // (please trim this list while you are at it). 1360 } 1361 1362 if (!(Attributes & ObjCDeclSpec::DQ_PR_copy) 1363 &&!(Attributes & ObjCDeclSpec::DQ_PR_readonly) 1364 && getLangOptions().getGCMode() == LangOptions::GCOnly 1365 && PropertyTy->isBlockPointerType()) 1366 Diag(Loc, diag::warn_objc_property_copy_missing_on_block); 1367} 1368