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