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