SemaObjCProperty.cpp revision edcc27f6171fd8cc736d057d87b128252fcb7344
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 "clang/AST/ExprCXX.h" 20#include "clang/AST/ASTMutationListener.h" 21#include "clang/Lex/Lexer.h" 22#include "clang/Basic/SourceManager.h" 23#include "llvm/ADT/DenseSet.h" 24#include "llvm/ADT/SmallString.h" 25 26using namespace clang; 27 28//===----------------------------------------------------------------------===// 29// Grammar actions. 30//===----------------------------------------------------------------------===// 31 32/// getImpliedARCOwnership - Given a set of property attributes and a 33/// type, infer an expected lifetime. The type's ownership qualification 34/// is not considered. 35/// 36/// Returns OCL_None if the attributes as stated do not imply an ownership. 37/// Never returns OCL_Autoreleasing. 38static Qualifiers::ObjCLifetime getImpliedARCOwnership( 39 ObjCPropertyDecl::PropertyAttributeKind attrs, 40 QualType type) { 41 // retain, strong, copy, weak, and unsafe_unretained are only legal 42 // on properties of retainable pointer type. 43 if (attrs & (ObjCPropertyDecl::OBJC_PR_retain | 44 ObjCPropertyDecl::OBJC_PR_strong | 45 ObjCPropertyDecl::OBJC_PR_copy)) { 46 return type->getObjCARCImplicitLifetime(); 47 } else if (attrs & ObjCPropertyDecl::OBJC_PR_weak) { 48 return Qualifiers::OCL_Weak; 49 } else if (attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) { 50 return Qualifiers::OCL_ExplicitNone; 51 } 52 53 // assign can appear on other types, so we have to check the 54 // property type. 55 if (attrs & ObjCPropertyDecl::OBJC_PR_assign && 56 type->isObjCRetainableType()) { 57 return Qualifiers::OCL_ExplicitNone; 58 } 59 60 return Qualifiers::OCL_None; 61} 62 63/// Check the internal consistency of a property declaration. 64static void checkARCPropertyDecl(Sema &S, ObjCPropertyDecl *property) { 65 if (property->isInvalidDecl()) return; 66 67 ObjCPropertyDecl::PropertyAttributeKind propertyKind 68 = property->getPropertyAttributes(); 69 Qualifiers::ObjCLifetime propertyLifetime 70 = property->getType().getObjCLifetime(); 71 72 // Nothing to do if we don't have a lifetime. 73 if (propertyLifetime == Qualifiers::OCL_None) return; 74 75 Qualifiers::ObjCLifetime expectedLifetime 76 = getImpliedARCOwnership(propertyKind, property->getType()); 77 if (!expectedLifetime) { 78 // We have a lifetime qualifier but no dominating property 79 // attribute. That's okay, but restore reasonable invariants by 80 // setting the property attribute according to the lifetime 81 // qualifier. 82 ObjCPropertyDecl::PropertyAttributeKind attr; 83 if (propertyLifetime == Qualifiers::OCL_Strong) { 84 attr = ObjCPropertyDecl::OBJC_PR_strong; 85 } else if (propertyLifetime == Qualifiers::OCL_Weak) { 86 attr = ObjCPropertyDecl::OBJC_PR_weak; 87 } else { 88 assert(propertyLifetime == Qualifiers::OCL_ExplicitNone); 89 attr = ObjCPropertyDecl::OBJC_PR_unsafe_unretained; 90 } 91 property->setPropertyAttributes(attr); 92 return; 93 } 94 95 if (propertyLifetime == expectedLifetime) return; 96 97 property->setInvalidDecl(); 98 S.Diag(property->getLocation(), 99 diag::err_arc_inconsistent_property_ownership) 100 << property->getDeclName() 101 << expectedLifetime 102 << propertyLifetime; 103} 104 105Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, 106 SourceLocation LParenLoc, 107 FieldDeclarator &FD, 108 ObjCDeclSpec &ODS, 109 Selector GetterSel, 110 Selector SetterSel, 111 bool *isOverridingProperty, 112 tok::ObjCKeywordKind MethodImplKind, 113 DeclContext *lexicalDC) { 114 unsigned Attributes = ODS.getPropertyAttributes(); 115 TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S); 116 QualType T = TSI->getType(); 117 if ((getLangOpts().getGC() != LangOptions::NonGC && 118 T.isObjCGCWeak()) || 119 (getLangOpts().ObjCAutoRefCount && 120 T.getObjCLifetime() == Qualifiers::OCL_Weak)) 121 Attributes |= ObjCDeclSpec::DQ_PR_weak; 122 123 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) || 124 // default is readwrite! 125 !(Attributes & ObjCDeclSpec::DQ_PR_readonly)); 126 // property is defaulted to 'assign' if it is readwrite and is 127 // not retain or copy 128 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) || 129 (isReadWrite && 130 !(Attributes & ObjCDeclSpec::DQ_PR_retain) && 131 !(Attributes & ObjCDeclSpec::DQ_PR_strong) && 132 !(Attributes & ObjCDeclSpec::DQ_PR_copy) && 133 !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) && 134 !(Attributes & ObjCDeclSpec::DQ_PR_weak))); 135 136 // Proceed with constructing the ObjCPropertDecls. 137 ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext); 138 139 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) 140 if (CDecl->IsClassExtension()) { 141 Decl *Res = HandlePropertyInClassExtension(S, AtLoc, LParenLoc, 142 FD, GetterSel, SetterSel, 143 isAssign, isReadWrite, 144 Attributes, 145 ODS.getPropertyAttributes(), 146 isOverridingProperty, TSI, 147 MethodImplKind); 148 if (Res) { 149 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); 150 if (getLangOpts().ObjCAutoRefCount) 151 checkARCPropertyDecl(*this, cast<ObjCPropertyDecl>(Res)); 152 } 153 return Res; 154 } 155 156 ObjCPropertyDecl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, LParenLoc, FD, 157 GetterSel, SetterSel, 158 isAssign, isReadWrite, 159 Attributes, 160 ODS.getPropertyAttributes(), 161 TSI, MethodImplKind); 162 if (lexicalDC) 163 Res->setLexicalDeclContext(lexicalDC); 164 165 // Validate the attributes on the @property. 166 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); 167 168 if (getLangOpts().ObjCAutoRefCount) 169 checkARCPropertyDecl(*this, Res); 170 171 return Res; 172} 173 174static ObjCPropertyDecl::PropertyAttributeKind 175makePropertyAttributesAsWritten(unsigned Attributes) { 176 unsigned attributesAsWritten = 0; 177 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 178 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readonly; 179 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 180 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readwrite; 181 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 182 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_getter; 183 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 184 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_setter; 185 if (Attributes & ObjCDeclSpec::DQ_PR_assign) 186 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_assign; 187 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 188 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_retain; 189 if (Attributes & ObjCDeclSpec::DQ_PR_strong) 190 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_strong; 191 if (Attributes & ObjCDeclSpec::DQ_PR_weak) 192 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_weak; 193 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 194 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_copy; 195 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) 196 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_unsafe_unretained; 197 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 198 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_nonatomic; 199 if (Attributes & ObjCDeclSpec::DQ_PR_atomic) 200 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_atomic; 201 202 return (ObjCPropertyDecl::PropertyAttributeKind)attributesAsWritten; 203} 204 205static bool LocPropertyAttribute(const Sema &sema, 206 ASTContext &Context, const char *attrName, 207 SourceLocation LParenLoc, SourceLocation &Loc) { 208 if (LParenLoc.isMacroID()) 209 return false; 210 211 SourceManager &SM = Context.getSourceManager(); 212 std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(LParenLoc); 213 // Try to load the file buffer. 214 bool invalidTemp = false; 215 StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 216 if (invalidTemp) 217 return false; 218 const char *tokenBegin = file.data() + locInfo.second; 219 220 // Lex from the start of the given location. 221 Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 222 Context.getLangOpts(), 223 file.begin(), tokenBegin, file.end()); 224 Token Tok; 225 do { 226 lexer.LexFromRawLexer(Tok); 227 if (Tok.is(tok::raw_identifier) && 228 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == attrName) { 229 Loc = Tok.getLocation(); 230 return true; 231 } 232 } while (Tok.isNot(tok::r_paren)); 233 return false; 234 235} 236 237Decl * 238Sema::HandlePropertyInClassExtension(Scope *S, 239 SourceLocation AtLoc, 240 SourceLocation LParenLoc, 241 FieldDeclarator &FD, 242 Selector GetterSel, Selector SetterSel, 243 const bool isAssign, 244 const bool isReadWrite, 245 const unsigned Attributes, 246 const unsigned AttributesAsWritten, 247 bool *isOverridingProperty, 248 TypeSourceInfo *T, 249 tok::ObjCKeywordKind MethodImplKind) { 250 ObjCCategoryDecl *CDecl = cast<ObjCCategoryDecl>(CurContext); 251 // Diagnose if this property is already in continuation class. 252 DeclContext *DC = CurContext; 253 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 254 ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface(); 255 256 if (CCPrimary) 257 // Check for duplicate declaration of this property in current and 258 // other class extensions. 259 for (const ObjCCategoryDecl *ClsExtDecl = 260 CCPrimary->getFirstClassExtension(); 261 ClsExtDecl; ClsExtDecl = ClsExtDecl->getNextClassExtension()) { 262 if (ObjCPropertyDecl *prevDecl = 263 ObjCPropertyDecl::findPropertyDecl(ClsExtDecl, PropertyId)) { 264 Diag(AtLoc, diag::err_duplicate_property); 265 Diag(prevDecl->getLocation(), diag::note_property_declare); 266 return 0; 267 } 268 } 269 270 // Create a new ObjCPropertyDecl with the DeclContext being 271 // the class extension. 272 // FIXME. We should really be using CreatePropertyDecl for this. 273 ObjCPropertyDecl *PDecl = 274 ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(), 275 PropertyId, AtLoc, LParenLoc, T); 276 PDecl->setPropertyAttributesAsWritten( 277 makePropertyAttributesAsWritten(AttributesAsWritten)); 278 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 279 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 280 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 281 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 282 // Set setter/getter selector name. Needed later. 283 PDecl->setGetterName(GetterSel); 284 PDecl->setSetterName(SetterSel); 285 ProcessDeclAttributes(S, PDecl, FD.D); 286 DC->addDecl(PDecl); 287 288 // We need to look in the @interface to see if the @property was 289 // already declared. 290 if (!CCPrimary) { 291 Diag(CDecl->getLocation(), diag::err_continuation_class); 292 *isOverridingProperty = true; 293 return 0; 294 } 295 296 // Find the property in continuation class's primary class only. 297 ObjCPropertyDecl *PIDecl = 298 CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId); 299 300 if (!PIDecl) { 301 // No matching property found in the primary class. Just fall thru 302 // and add property to continuation class's primary class. 303 ObjCPropertyDecl *PrimaryPDecl = 304 CreatePropertyDecl(S, CCPrimary, AtLoc, LParenLoc, 305 FD, GetterSel, SetterSel, isAssign, isReadWrite, 306 Attributes,AttributesAsWritten, T, MethodImplKind, DC); 307 308 // A case of continuation class adding a new property in the class. This 309 // is not what it was meant for. However, gcc supports it and so should we. 310 // Make sure setter/getters are declared here. 311 ProcessPropertyDecl(PrimaryPDecl, CCPrimary, /* redeclaredProperty = */ 0, 312 /* lexicalDC = */ CDecl); 313 PDecl->setGetterMethodDecl(PrimaryPDecl->getGetterMethodDecl()); 314 PDecl->setSetterMethodDecl(PrimaryPDecl->getSetterMethodDecl()); 315 if (ASTMutationListener *L = Context.getASTMutationListener()) 316 L->AddedObjCPropertyInClassExtension(PrimaryPDecl, /*OrigProp=*/0, CDecl); 317 return PrimaryPDecl; 318 } 319 if (!Context.hasSameType(PIDecl->getType(), PDecl->getType())) { 320 bool IncompatibleObjC = false; 321 QualType ConvertedType; 322 // Relax the strict type matching for property type in continuation class. 323 // Allow property object type of continuation class to be different as long 324 // as it narrows the object type in its primary class property. Note that 325 // this conversion is safe only because the wider type is for a 'readonly' 326 // property in primary class and 'narrowed' type for a 'readwrite' property 327 // in continuation class. 328 if (!isa<ObjCObjectPointerType>(PIDecl->getType()) || 329 !isa<ObjCObjectPointerType>(PDecl->getType()) || 330 (!isObjCPointerConversion(PDecl->getType(), PIDecl->getType(), 331 ConvertedType, IncompatibleObjC)) 332 || IncompatibleObjC) { 333 Diag(AtLoc, 334 diag::err_type_mismatch_continuation_class) << PDecl->getType(); 335 Diag(PIDecl->getLocation(), diag::note_property_declare); 336 } 337 } 338 339 // The property 'PIDecl's readonly attribute will be over-ridden 340 // with continuation class's readwrite property attribute! 341 unsigned PIkind = PIDecl->getPropertyAttributesAsWritten(); 342 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { 343 unsigned retainCopyNonatomic = 344 (ObjCPropertyDecl::OBJC_PR_retain | 345 ObjCPropertyDecl::OBJC_PR_strong | 346 ObjCPropertyDecl::OBJC_PR_copy | 347 ObjCPropertyDecl::OBJC_PR_nonatomic); 348 if ((Attributes & retainCopyNonatomic) != 349 (PIkind & retainCopyNonatomic)) { 350 Diag(AtLoc, diag::warn_property_attr_mismatch); 351 Diag(PIDecl->getLocation(), diag::note_property_declare); 352 } 353 DeclContext *DC = cast<DeclContext>(CCPrimary); 354 if (!ObjCPropertyDecl::findPropertyDecl(DC, 355 PIDecl->getDeclName().getAsIdentifierInfo())) { 356 // Protocol is not in the primary class. Must build one for it. 357 ObjCDeclSpec ProtocolPropertyODS; 358 // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind 359 // and ObjCPropertyDecl::PropertyAttributeKind have identical 360 // values. Should consolidate both into one enum type. 361 ProtocolPropertyODS. 362 setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind) 363 PIkind); 364 // Must re-establish the context from class extension to primary 365 // class context. 366 ContextRAII SavedContext(*this, CCPrimary); 367 368 Decl *ProtocolPtrTy = 369 ActOnProperty(S, AtLoc, LParenLoc, FD, ProtocolPropertyODS, 370 PIDecl->getGetterName(), 371 PIDecl->getSetterName(), 372 isOverridingProperty, 373 MethodImplKind, 374 /* lexicalDC = */ CDecl); 375 PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy); 376 } 377 PIDecl->makeitReadWriteAttribute(); 378 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 379 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 380 if (Attributes & ObjCDeclSpec::DQ_PR_strong) 381 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 382 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 383 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 384 PIDecl->setSetterName(SetterSel); 385 } else { 386 // Tailor the diagnostics for the common case where a readwrite 387 // property is declared both in the @interface and the continuation. 388 // This is a common error where the user often intended the original 389 // declaration to be readonly. 390 unsigned diag = 391 (Attributes & ObjCDeclSpec::DQ_PR_readwrite) && 392 (PIkind & ObjCPropertyDecl::OBJC_PR_readwrite) 393 ? diag::err_use_continuation_class_redeclaration_readwrite 394 : diag::err_use_continuation_class; 395 Diag(AtLoc, diag) 396 << CCPrimary->getDeclName(); 397 Diag(PIDecl->getLocation(), diag::note_property_declare); 398 } 399 *isOverridingProperty = true; 400 // Make sure setter decl is synthesized, and added to primary class's list. 401 ProcessPropertyDecl(PIDecl, CCPrimary, PDecl, CDecl); 402 PDecl->setGetterMethodDecl(PIDecl->getGetterMethodDecl()); 403 PDecl->setSetterMethodDecl(PIDecl->getSetterMethodDecl()); 404 if (ASTMutationListener *L = Context.getASTMutationListener()) 405 L->AddedObjCPropertyInClassExtension(PDecl, PIDecl, CDecl); 406 return 0; 407} 408 409ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S, 410 ObjCContainerDecl *CDecl, 411 SourceLocation AtLoc, 412 SourceLocation LParenLoc, 413 FieldDeclarator &FD, 414 Selector GetterSel, 415 Selector SetterSel, 416 const bool isAssign, 417 const bool isReadWrite, 418 const unsigned Attributes, 419 const unsigned AttributesAsWritten, 420 TypeSourceInfo *TInfo, 421 tok::ObjCKeywordKind MethodImplKind, 422 DeclContext *lexicalDC){ 423 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 424 QualType T = TInfo->getType(); 425 426 // Issue a warning if property is 'assign' as default and its object, which is 427 // gc'able conforms to NSCopying protocol 428 if (getLangOpts().getGC() != LangOptions::NonGC && 429 isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign)) 430 if (const ObjCObjectPointerType *ObjPtrTy = 431 T->getAs<ObjCObjectPointerType>()) { 432 ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface(); 433 if (IDecl) 434 if (ObjCProtocolDecl* PNSCopying = 435 LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc)) 436 if (IDecl->ClassImplementsProtocol(PNSCopying, true)) 437 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId; 438 } 439 if (T->isObjCObjectType()) 440 Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object); 441 442 DeclContext *DC = cast<DeclContext>(CDecl); 443 ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC, 444 FD.D.getIdentifierLoc(), 445 PropertyId, AtLoc, LParenLoc, TInfo); 446 447 if (ObjCPropertyDecl *prevDecl = 448 ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) { 449 Diag(PDecl->getLocation(), diag::err_duplicate_property); 450 Diag(prevDecl->getLocation(), diag::note_property_declare); 451 PDecl->setInvalidDecl(); 452 } 453 else { 454 DC->addDecl(PDecl); 455 if (lexicalDC) 456 PDecl->setLexicalDeclContext(lexicalDC); 457 } 458 459 if (T->isArrayType() || T->isFunctionType()) { 460 Diag(AtLoc, diag::err_property_type) << T; 461 PDecl->setInvalidDecl(); 462 } 463 464 ProcessDeclAttributes(S, PDecl, FD.D); 465 466 // Regardless of setter/getter attribute, we save the default getter/setter 467 // selector names in anticipation of declaration of setter/getter methods. 468 PDecl->setGetterName(GetterSel); 469 PDecl->setSetterName(SetterSel); 470 PDecl->setPropertyAttributesAsWritten( 471 makePropertyAttributesAsWritten(AttributesAsWritten)); 472 473 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 474 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 475 476 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 477 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter); 478 479 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 480 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter); 481 482 if (isReadWrite) 483 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 484 485 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 486 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 487 488 if (Attributes & ObjCDeclSpec::DQ_PR_strong) 489 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 490 491 if (Attributes & ObjCDeclSpec::DQ_PR_weak) 492 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak); 493 494 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 495 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 496 497 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) 498 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained); 499 500 if (isAssign) 501 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 502 503 // In the semantic attributes, one of nonatomic or atomic is always set. 504 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 505 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); 506 else 507 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic); 508 509 // 'unsafe_unretained' is alias for 'assign'. 510 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) 511 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 512 if (isAssign) 513 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained); 514 515 if (MethodImplKind == tok::objc_required) 516 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required); 517 else if (MethodImplKind == tok::objc_optional) 518 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional); 519 520 return PDecl; 521} 522 523static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc, 524 ObjCPropertyDecl *property, 525 ObjCIvarDecl *ivar) { 526 if (property->isInvalidDecl() || ivar->isInvalidDecl()) return; 527 528 QualType ivarType = ivar->getType(); 529 Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime(); 530 531 // The lifetime implied by the property's attributes. 532 Qualifiers::ObjCLifetime propertyLifetime = 533 getImpliedARCOwnership(property->getPropertyAttributes(), 534 property->getType()); 535 536 // We're fine if they match. 537 if (propertyLifetime == ivarLifetime) return; 538 539 // These aren't valid lifetimes for object ivars; don't diagnose twice. 540 if (ivarLifetime == Qualifiers::OCL_None || 541 ivarLifetime == Qualifiers::OCL_Autoreleasing) 542 return; 543 544 switch (propertyLifetime) { 545 case Qualifiers::OCL_Strong: 546 S.Diag(propertyImplLoc, diag::err_arc_strong_property_ownership) 547 << property->getDeclName() 548 << ivar->getDeclName() 549 << ivarLifetime; 550 break; 551 552 case Qualifiers::OCL_Weak: 553 S.Diag(propertyImplLoc, diag::error_weak_property) 554 << property->getDeclName() 555 << ivar->getDeclName(); 556 break; 557 558 case Qualifiers::OCL_ExplicitNone: 559 S.Diag(propertyImplLoc, diag::err_arc_assign_property_ownership) 560 << property->getDeclName() 561 << ivar->getDeclName() 562 << ((property->getPropertyAttributesAsWritten() 563 & ObjCPropertyDecl::OBJC_PR_assign) != 0); 564 break; 565 566 case Qualifiers::OCL_Autoreleasing: 567 llvm_unreachable("properties cannot be autoreleasing"); 568 569 case Qualifiers::OCL_None: 570 // Any other property should be ignored. 571 return; 572 } 573 574 S.Diag(property->getLocation(), diag::note_property_declare); 575} 576 577/// setImpliedPropertyAttributeForReadOnlyProperty - 578/// This routine evaludates life-time attributes for a 'readonly' 579/// property with no known lifetime of its own, using backing 580/// 'ivar's attribute, if any. If no backing 'ivar', property's 581/// life-time is assumed 'strong'. 582static void setImpliedPropertyAttributeForReadOnlyProperty( 583 ObjCPropertyDecl *property, ObjCIvarDecl *ivar) { 584 Qualifiers::ObjCLifetime propertyLifetime = 585 getImpliedARCOwnership(property->getPropertyAttributes(), 586 property->getType()); 587 if (propertyLifetime != Qualifiers::OCL_None) 588 return; 589 590 if (!ivar) { 591 // if no backing ivar, make property 'strong'. 592 property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 593 return; 594 } 595 // property assumes owenership of backing ivar. 596 QualType ivarType = ivar->getType(); 597 Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime(); 598 if (ivarLifetime == Qualifiers::OCL_Strong) 599 property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 600 else if (ivarLifetime == Qualifiers::OCL_Weak) 601 property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak); 602 return; 603} 604 605/// ActOnPropertyImplDecl - This routine performs semantic checks and 606/// builds the AST node for a property implementation declaration; declared 607/// as @synthesize or @dynamic. 608/// 609Decl *Sema::ActOnPropertyImplDecl(Scope *S, 610 SourceLocation AtLoc, 611 SourceLocation PropertyLoc, 612 bool Synthesize, 613 IdentifierInfo *PropertyId, 614 IdentifierInfo *PropertyIvar, 615 SourceLocation PropertyIvarLoc) { 616 ObjCContainerDecl *ClassImpDecl = 617 dyn_cast<ObjCContainerDecl>(CurContext); 618 // Make sure we have a context for the property implementation declaration. 619 if (!ClassImpDecl) { 620 Diag(AtLoc, diag::error_missing_property_context); 621 return 0; 622 } 623 if (PropertyIvarLoc.isInvalid()) 624 PropertyIvarLoc = PropertyLoc; 625 SourceLocation PropertyDiagLoc = PropertyLoc; 626 if (PropertyDiagLoc.isInvalid()) 627 PropertyDiagLoc = ClassImpDecl->getLocStart(); 628 ObjCPropertyDecl *property = 0; 629 ObjCInterfaceDecl* IDecl = 0; 630 // Find the class or category class where this property must have 631 // a declaration. 632 ObjCImplementationDecl *IC = 0; 633 ObjCCategoryImplDecl* CatImplClass = 0; 634 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) { 635 IDecl = IC->getClassInterface(); 636 // We always synthesize an interface for an implementation 637 // without an interface decl. So, IDecl is always non-zero. 638 assert(IDecl && 639 "ActOnPropertyImplDecl - @implementation without @interface"); 640 641 // Look for this property declaration in the @implementation's @interface 642 property = IDecl->FindPropertyDeclaration(PropertyId); 643 if (!property) { 644 Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName(); 645 return 0; 646 } 647 unsigned PIkind = property->getPropertyAttributesAsWritten(); 648 if ((PIkind & (ObjCPropertyDecl::OBJC_PR_atomic | 649 ObjCPropertyDecl::OBJC_PR_nonatomic) ) == 0) { 650 if (AtLoc.isValid()) 651 Diag(AtLoc, diag::warn_implicit_atomic_property); 652 else 653 Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property); 654 Diag(property->getLocation(), diag::note_property_declare); 655 } 656 657 if (const ObjCCategoryDecl *CD = 658 dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) { 659 if (!CD->IsClassExtension()) { 660 Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName(); 661 Diag(property->getLocation(), diag::note_property_declare); 662 return 0; 663 } 664 } 665 666 if (Synthesize&& 667 (PIkind & ObjCPropertyDecl::OBJC_PR_readonly) && 668 property->hasAttr<IBOutletAttr>() && 669 !AtLoc.isValid()) { 670 unsigned rwPIKind = (PIkind | ObjCPropertyDecl::OBJC_PR_readwrite); 671 rwPIKind &= (~ObjCPropertyDecl::OBJC_PR_readonly); 672 Diag(IC->getLocation(), diag::warn_auto_readonly_iboutlet_property); 673 Diag(property->getLocation(), diag::note_property_declare); 674 SourceLocation readonlyLoc; 675 if (LocPropertyAttribute(*this, Context, "readonly", 676 property->getLParenLoc(), readonlyLoc)) { 677 SourceLocation endLoc = 678 readonlyLoc.getLocWithOffset(strlen("readonly")-1); 679 SourceRange ReadonlySourceRange(readonlyLoc, endLoc); 680 Diag(property->getLocation(), 681 diag::note_auto_readonly_iboutlet_fixup_suggest) << 682 FixItHint::CreateReplacement(ReadonlySourceRange, "readwrite"); 683 } 684 } 685 686 } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) { 687 if (Synthesize) { 688 Diag(AtLoc, diag::error_synthesize_category_decl); 689 return 0; 690 } 691 IDecl = CatImplClass->getClassInterface(); 692 if (!IDecl) { 693 Diag(AtLoc, diag::error_missing_property_interface); 694 return 0; 695 } 696 ObjCCategoryDecl *Category = 697 IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier()); 698 699 // If category for this implementation not found, it is an error which 700 // has already been reported eralier. 701 if (!Category) 702 return 0; 703 // Look for this property declaration in @implementation's category 704 property = Category->FindPropertyDeclaration(PropertyId); 705 if (!property) { 706 Diag(PropertyLoc, diag::error_bad_category_property_decl) 707 << Category->getDeclName(); 708 return 0; 709 } 710 } else { 711 Diag(AtLoc, diag::error_bad_property_context); 712 return 0; 713 } 714 ObjCIvarDecl *Ivar = 0; 715 bool CompleteTypeErr = false; 716 bool compat = true; 717 // Check that we have a valid, previously declared ivar for @synthesize 718 if (Synthesize) { 719 // @synthesize 720 if (!PropertyIvar) 721 PropertyIvar = PropertyId; 722 // Check that this is a previously declared 'ivar' in 'IDecl' interface 723 ObjCInterfaceDecl *ClassDeclared; 724 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared); 725 QualType PropType = property->getType(); 726 QualType PropertyIvarType = PropType.getNonReferenceType(); 727 728 if (RequireCompleteType(PropertyDiagLoc, PropertyIvarType, 729 diag::err_incomplete_synthesized_property, 730 property->getDeclName())) { 731 Diag(property->getLocation(), diag::note_property_declare); 732 CompleteTypeErr = true; 733 } 734 735 if (getLangOpts().ObjCAutoRefCount && 736 (property->getPropertyAttributesAsWritten() & 737 ObjCPropertyDecl::OBJC_PR_readonly) && 738 PropertyIvarType->isObjCRetainableType()) { 739 setImpliedPropertyAttributeForReadOnlyProperty(property, Ivar); 740 } 741 742 ObjCPropertyDecl::PropertyAttributeKind kind 743 = property->getPropertyAttributes(); 744 745 // Add GC __weak to the ivar type if the property is weak. 746 if ((kind & ObjCPropertyDecl::OBJC_PR_weak) && 747 getLangOpts().getGC() != LangOptions::NonGC) { 748 assert(!getLangOpts().ObjCAutoRefCount); 749 if (PropertyIvarType.isObjCGCStrong()) { 750 Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type); 751 Diag(property->getLocation(), diag::note_property_declare); 752 } else { 753 PropertyIvarType = 754 Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak); 755 } 756 } 757 758 if (!Ivar) { 759 // In ARC, give the ivar a lifetime qualifier based on the 760 // property attributes. 761 if (getLangOpts().ObjCAutoRefCount && 762 !PropertyIvarType.getObjCLifetime() && 763 PropertyIvarType->isObjCRetainableType()) { 764 765 // It's an error if we have to do this and the user didn't 766 // explicitly write an ownership attribute on the property. 767 if (!property->hasWrittenStorageAttribute() && 768 !(kind & ObjCPropertyDecl::OBJC_PR_strong)) { 769 Diag(PropertyDiagLoc, 770 diag::err_arc_objc_property_default_assign_on_object); 771 Diag(property->getLocation(), diag::note_property_declare); 772 } else { 773 Qualifiers::ObjCLifetime lifetime = 774 getImpliedARCOwnership(kind, PropertyIvarType); 775 assert(lifetime && "no lifetime for property?"); 776 if (lifetime == Qualifiers::OCL_Weak) { 777 bool err = false; 778 if (const ObjCObjectPointerType *ObjT = 779 PropertyIvarType->getAs<ObjCObjectPointerType>()) 780 if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable()) { 781 Diag(PropertyDiagLoc, diag::err_arc_weak_unavailable_property); 782 Diag(property->getLocation(), diag::note_property_declare); 783 err = true; 784 } 785 if (!err && !getLangOpts().ObjCRuntimeHasWeak) { 786 Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime); 787 Diag(property->getLocation(), diag::note_property_declare); 788 } 789 } 790 791 Qualifiers qs; 792 qs.addObjCLifetime(lifetime); 793 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs); 794 } 795 } 796 797 if (kind & ObjCPropertyDecl::OBJC_PR_weak && 798 !getLangOpts().ObjCAutoRefCount && 799 getLangOpts().getGC() == LangOptions::NonGC) { 800 Diag(PropertyDiagLoc, diag::error_synthesize_weak_non_arc_or_gc); 801 Diag(property->getLocation(), diag::note_property_declare); 802 } 803 804 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, 805 PropertyIvarLoc,PropertyIvarLoc, PropertyIvar, 806 PropertyIvarType, /*Dinfo=*/0, 807 ObjCIvarDecl::Private, 808 (Expr *)0, true); 809 if (CompleteTypeErr) 810 Ivar->setInvalidDecl(); 811 ClassImpDecl->addDecl(Ivar); 812 IDecl->makeDeclVisibleInContext(Ivar); 813 property->setPropertyIvarDecl(Ivar); 814 815 if (!getLangOpts().ObjCNonFragileABI) 816 Diag(PropertyDiagLoc, diag::error_missing_property_ivar_decl) 817 << PropertyId; 818 // Note! I deliberately want it to fall thru so, we have a 819 // a property implementation and to avoid future warnings. 820 } else if (getLangOpts().ObjCNonFragileABI && 821 !declaresSameEntity(ClassDeclared, IDecl)) { 822 Diag(PropertyDiagLoc, diag::error_ivar_in_superclass_use) 823 << property->getDeclName() << Ivar->getDeclName() 824 << ClassDeclared->getDeclName(); 825 Diag(Ivar->getLocation(), diag::note_previous_access_declaration) 826 << Ivar << Ivar->getName(); 827 // Note! I deliberately want it to fall thru so more errors are caught. 828 } 829 QualType IvarType = Context.getCanonicalType(Ivar->getType()); 830 831 // Check that type of property and its ivar are type compatible. 832 if (!Context.hasSameType(PropertyIvarType, IvarType)) { 833 compat = false; 834 if (isa<ObjCObjectPointerType>(PropertyIvarType) 835 && isa<ObjCObjectPointerType>(IvarType)) 836 compat = 837 Context.canAssignObjCInterfaces( 838 PropertyIvarType->getAs<ObjCObjectPointerType>(), 839 IvarType->getAs<ObjCObjectPointerType>()); 840 else { 841 compat = (CheckAssignmentConstraints(PropertyIvarLoc, PropertyIvarType, 842 IvarType) 843 == Compatible); 844 } 845 if (!compat) { 846 Diag(PropertyDiagLoc, diag::error_property_ivar_type) 847 << property->getDeclName() << PropType 848 << Ivar->getDeclName() << IvarType; 849 Diag(Ivar->getLocation(), diag::note_ivar_decl); 850 // Note! I deliberately want it to fall thru so, we have a 851 // a property implementation and to avoid future warnings. 852 } 853 else { 854 // FIXME! Rules for properties are somewhat different that those 855 // for assignments. Use a new routine to consolidate all cases; 856 // specifically for property redeclarations as well as for ivars. 857 QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType(); 858 QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType(); 859 if (lhsType != rhsType && 860 lhsType->isArithmeticType()) { 861 Diag(PropertyDiagLoc, diag::error_property_ivar_type) 862 << property->getDeclName() << PropType 863 << Ivar->getDeclName() << IvarType; 864 Diag(Ivar->getLocation(), diag::note_ivar_decl); 865 // Fall thru - see previous comment 866 } 867 } 868 // __weak is explicit. So it works on Canonical type. 869 if ((PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() && 870 getLangOpts().getGC() != LangOptions::NonGC)) { 871 Diag(PropertyDiagLoc, diag::error_weak_property) 872 << property->getDeclName() << Ivar->getDeclName(); 873 Diag(Ivar->getLocation(), diag::note_ivar_decl); 874 // Fall thru - see previous comment 875 } 876 // Fall thru - see previous comment 877 if ((property->getType()->isObjCObjectPointerType() || 878 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() && 879 getLangOpts().getGC() != LangOptions::NonGC) { 880 Diag(PropertyDiagLoc, diag::error_strong_property) 881 << property->getDeclName() << Ivar->getDeclName(); 882 // Fall thru - see previous comment 883 } 884 } 885 if (getLangOpts().ObjCAutoRefCount) 886 checkARCPropertyImpl(*this, PropertyLoc, property, Ivar); 887 } else if (PropertyIvar) 888 // @dynamic 889 Diag(PropertyDiagLoc, diag::error_dynamic_property_ivar_decl); 890 891 assert (property && "ActOnPropertyImplDecl - property declaration missing"); 892 ObjCPropertyImplDecl *PIDecl = 893 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, 894 property, 895 (Synthesize ? 896 ObjCPropertyImplDecl::Synthesize 897 : ObjCPropertyImplDecl::Dynamic), 898 Ivar, PropertyIvarLoc); 899 900 if (CompleteTypeErr || !compat) 901 PIDecl->setInvalidDecl(); 902 903 if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) { 904 getterMethod->createImplicitParams(Context, IDecl); 905 if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr && 906 Ivar->getType()->isRecordType()) { 907 // For Objective-C++, need to synthesize the AST for the IVAR object to be 908 // returned by the getter as it must conform to C++'s copy-return rules. 909 // FIXME. Eventually we want to do this for Objective-C as well. 910 ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); 911 DeclRefExpr *SelfExpr = 912 new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(), 913 VK_RValue, SourceLocation()); 914 Expr *IvarRefExpr = 915 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 916 SelfExpr, true, true); 917 ExprResult Res = 918 PerformCopyInitialization(InitializedEntity::InitializeResult( 919 SourceLocation(), 920 getterMethod->getResultType(), 921 /*NRVO=*/false), 922 SourceLocation(), 923 Owned(IvarRefExpr)); 924 if (!Res.isInvalid()) { 925 Expr *ResExpr = Res.takeAs<Expr>(); 926 if (ResExpr) 927 ResExpr = MaybeCreateExprWithCleanups(ResExpr); 928 PIDecl->setGetterCXXConstructor(ResExpr); 929 } 930 } 931 if (property->hasAttr<NSReturnsNotRetainedAttr>() && 932 !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) { 933 Diag(getterMethod->getLocation(), 934 diag::warn_property_getter_owning_mismatch); 935 Diag(property->getLocation(), diag::note_property_declare); 936 } 937 } 938 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) { 939 setterMethod->createImplicitParams(Context, IDecl); 940 if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr && 941 Ivar->getType()->isRecordType()) { 942 // FIXME. Eventually we want to do this for Objective-C as well. 943 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); 944 DeclRefExpr *SelfExpr = 945 new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(), 946 VK_RValue, SourceLocation()); 947 Expr *lhs = 948 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 949 SelfExpr, true, true); 950 ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); 951 ParmVarDecl *Param = (*P); 952 QualType T = Param->getType().getNonReferenceType(); 953 Expr *rhs = new (Context) DeclRefExpr(Param, false, T, 954 VK_LValue, SourceLocation()); 955 ExprResult Res = BuildBinOp(S, lhs->getLocEnd(), 956 BO_Assign, lhs, rhs); 957 if (property->getPropertyAttributes() & 958 ObjCPropertyDecl::OBJC_PR_atomic) { 959 Expr *callExpr = Res.takeAs<Expr>(); 960 if (const CXXOperatorCallExpr *CXXCE = 961 dyn_cast_or_null<CXXOperatorCallExpr>(callExpr)) 962 if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee()) 963 if (!FuncDecl->isTrivial()) 964 if (property->getType()->isReferenceType()) { 965 Diag(PropertyLoc, 966 diag::err_atomic_property_nontrivial_assign_op) 967 << property->getType(); 968 Diag(FuncDecl->getLocStart(), 969 diag::note_callee_decl) << FuncDecl; 970 } 971 } 972 PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>()); 973 } 974 } 975 976 if (IC) { 977 if (Synthesize) 978 if (ObjCPropertyImplDecl *PPIDecl = 979 IC->FindPropertyImplIvarDecl(PropertyIvar)) { 980 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 981 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 982 << PropertyIvar; 983 Diag(PPIDecl->getLocation(), diag::note_previous_use); 984 } 985 986 if (ObjCPropertyImplDecl *PPIDecl 987 = IC->FindPropertyImplDecl(PropertyId)) { 988 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 989 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 990 return 0; 991 } 992 IC->addPropertyImplementation(PIDecl); 993 if (getLangOpts().ObjCDefaultSynthProperties && 994 getLangOpts().ObjCNonFragileABI2 && 995 !IDecl->isObjCRequiresPropertyDefs()) { 996 // Diagnose if an ivar was lazily synthesdized due to a previous 997 // use and if 1) property is @dynamic or 2) property is synthesized 998 // but it requires an ivar of different name. 999 ObjCInterfaceDecl *ClassDeclared=0; 1000 ObjCIvarDecl *Ivar = 0; 1001 if (!Synthesize) 1002 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 1003 else { 1004 if (PropertyIvar && PropertyIvar != PropertyId) 1005 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 1006 } 1007 // Issue diagnostics only if Ivar belongs to current class. 1008 if (Ivar && Ivar->getSynthesize() && 1009 declaresSameEntity(IC->getClassInterface(), ClassDeclared)) { 1010 Diag(Ivar->getLocation(), diag::err_undeclared_var_use) 1011 << PropertyId; 1012 Ivar->setInvalidDecl(); 1013 } 1014 } 1015 } else { 1016 if (Synthesize) 1017 if (ObjCPropertyImplDecl *PPIDecl = 1018 CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) { 1019 Diag(PropertyDiagLoc, diag::error_duplicate_ivar_use) 1020 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 1021 << PropertyIvar; 1022 Diag(PPIDecl->getLocation(), diag::note_previous_use); 1023 } 1024 1025 if (ObjCPropertyImplDecl *PPIDecl = 1026 CatImplClass->FindPropertyImplDecl(PropertyId)) { 1027 Diag(PropertyDiagLoc, diag::error_property_implemented) << PropertyId; 1028 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 1029 return 0; 1030 } 1031 CatImplClass->addPropertyImplementation(PIDecl); 1032 } 1033 1034 return PIDecl; 1035} 1036 1037//===----------------------------------------------------------------------===// 1038// Helper methods. 1039//===----------------------------------------------------------------------===// 1040 1041/// DiagnosePropertyMismatch - Compares two properties for their 1042/// attributes and types and warns on a variety of inconsistencies. 1043/// 1044void 1045Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, 1046 ObjCPropertyDecl *SuperProperty, 1047 const IdentifierInfo *inheritedName) { 1048 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1049 Property->getPropertyAttributes(); 1050 ObjCPropertyDecl::PropertyAttributeKind SAttr = 1051 SuperProperty->getPropertyAttributes(); 1052 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) 1053 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) 1054 Diag(Property->getLocation(), diag::warn_readonly_property) 1055 << Property->getDeclName() << inheritedName; 1056 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) 1057 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) 1058 Diag(Property->getLocation(), diag::warn_property_attribute) 1059 << Property->getDeclName() << "copy" << inheritedName; 1060 else if (!(SAttr & ObjCPropertyDecl::OBJC_PR_readonly)){ 1061 unsigned CAttrRetain = 1062 (CAttr & 1063 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 1064 unsigned SAttrRetain = 1065 (SAttr & 1066 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 1067 bool CStrong = (CAttrRetain != 0); 1068 bool SStrong = (SAttrRetain != 0); 1069 if (CStrong != SStrong) 1070 Diag(Property->getLocation(), diag::warn_property_attribute) 1071 << Property->getDeclName() << "retain (or strong)" << inheritedName; 1072 } 1073 1074 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) 1075 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) 1076 Diag(Property->getLocation(), diag::warn_property_attribute) 1077 << Property->getDeclName() << "atomic" << inheritedName; 1078 if (Property->getSetterName() != SuperProperty->getSetterName()) 1079 Diag(Property->getLocation(), diag::warn_property_attribute) 1080 << Property->getDeclName() << "setter" << inheritedName; 1081 if (Property->getGetterName() != SuperProperty->getGetterName()) 1082 Diag(Property->getLocation(), diag::warn_property_attribute) 1083 << Property->getDeclName() << "getter" << inheritedName; 1084 1085 QualType LHSType = 1086 Context.getCanonicalType(SuperProperty->getType()); 1087 QualType RHSType = 1088 Context.getCanonicalType(Property->getType()); 1089 1090 if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) { 1091 // Do cases not handled in above. 1092 // FIXME. For future support of covariant property types, revisit this. 1093 bool IncompatibleObjC = false; 1094 QualType ConvertedType; 1095 if (!isObjCPointerConversion(RHSType, LHSType, 1096 ConvertedType, IncompatibleObjC) || 1097 IncompatibleObjC) { 1098 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) 1099 << Property->getType() << SuperProperty->getType() << inheritedName; 1100 Diag(SuperProperty->getLocation(), diag::note_property_declare); 1101 } 1102 } 1103} 1104 1105bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, 1106 ObjCMethodDecl *GetterMethod, 1107 SourceLocation Loc) { 1108 if (!GetterMethod) 1109 return false; 1110 QualType GetterType = GetterMethod->getResultType().getNonReferenceType(); 1111 QualType PropertyIvarType = property->getType().getNonReferenceType(); 1112 bool compat = Context.hasSameType(PropertyIvarType, GetterType); 1113 if (!compat) { 1114 if (isa<ObjCObjectPointerType>(PropertyIvarType) && 1115 isa<ObjCObjectPointerType>(GetterType)) 1116 compat = 1117 Context.canAssignObjCInterfaces( 1118 PropertyIvarType->getAs<ObjCObjectPointerType>(), 1119 GetterType->getAs<ObjCObjectPointerType>()); 1120 else if (CheckAssignmentConstraints(Loc, PropertyIvarType, GetterType) 1121 != Compatible) { 1122 Diag(Loc, diag::error_property_accessor_type) 1123 << property->getDeclName() << PropertyIvarType 1124 << GetterMethod->getSelector() << GetterType; 1125 Diag(GetterMethod->getLocation(), diag::note_declared_at); 1126 return true; 1127 } else { 1128 compat = true; 1129 QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType(); 1130 QualType rhsType =Context.getCanonicalType(GetterType).getUnqualifiedType(); 1131 if (lhsType != rhsType && lhsType->isArithmeticType()) 1132 compat = false; 1133 } 1134 } 1135 1136 if (!compat) { 1137 Diag(Loc, diag::warn_accessor_property_type_mismatch) 1138 << property->getDeclName() 1139 << GetterMethod->getSelector(); 1140 Diag(GetterMethod->getLocation(), diag::note_declared_at); 1141 return true; 1142 } 1143 1144 return false; 1145} 1146 1147/// ComparePropertiesInBaseAndSuper - This routine compares property 1148/// declarations in base and its super class, if any, and issues 1149/// diagnostics in a variety of inconsistent situations. 1150/// 1151void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) { 1152 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); 1153 if (!SDecl) 1154 return; 1155 // FIXME: O(N^2) 1156 for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(), 1157 E = SDecl->prop_end(); S != E; ++S) { 1158 ObjCPropertyDecl *SuperPDecl = &*S; 1159 // Does property in super class has declaration in current class? 1160 for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(), 1161 E = IDecl->prop_end(); I != E; ++I) { 1162 ObjCPropertyDecl *PDecl = &*I; 1163 if (SuperPDecl->getIdentifier() == PDecl->getIdentifier()) 1164 DiagnosePropertyMismatch(PDecl, SuperPDecl, 1165 SDecl->getIdentifier()); 1166 } 1167 } 1168} 1169 1170/// MatchOneProtocolPropertiesInClass - This routine goes thru the list 1171/// of properties declared in a protocol and compares their attribute against 1172/// the same property declared in the class or category. 1173void 1174Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl, 1175 ObjCProtocolDecl *PDecl) { 1176 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 1177 if (!IDecl) { 1178 // Category 1179 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 1180 assert (CatDecl && "MatchOneProtocolPropertiesInClass"); 1181 if (!CatDecl->IsClassExtension()) 1182 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1183 E = PDecl->prop_end(); P != E; ++P) { 1184 ObjCPropertyDecl *Pr = &*P; 1185 ObjCCategoryDecl::prop_iterator CP, CE; 1186 // Is this property already in category's list of properties? 1187 for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP!=CE; ++CP) 1188 if (CP->getIdentifier() == Pr->getIdentifier()) 1189 break; 1190 if (CP != CE) 1191 // Property protocol already exist in class. Diagnose any mismatch. 1192 DiagnosePropertyMismatch(&*CP, Pr, PDecl->getIdentifier()); 1193 } 1194 return; 1195 } 1196 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1197 E = PDecl->prop_end(); P != E; ++P) { 1198 ObjCPropertyDecl *Pr = &*P; 1199 ObjCInterfaceDecl::prop_iterator CP, CE; 1200 // Is this property already in class's list of properties? 1201 for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP) 1202 if (CP->getIdentifier() == Pr->getIdentifier()) 1203 break; 1204 if (CP != CE) 1205 // Property protocol already exist in class. Diagnose any mismatch. 1206 DiagnosePropertyMismatch(&*CP, Pr, PDecl->getIdentifier()); 1207 } 1208} 1209 1210/// CompareProperties - This routine compares properties 1211/// declared in 'ClassOrProtocol' objects (which can be a class or an 1212/// inherited protocol with the list of properties for class/category 'CDecl' 1213/// 1214void Sema::CompareProperties(Decl *CDecl, Decl *ClassOrProtocol) { 1215 Decl *ClassDecl = ClassOrProtocol; 1216 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 1217 1218 if (!IDecl) { 1219 // Category 1220 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 1221 assert (CatDecl && "CompareProperties"); 1222 if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 1223 for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(), 1224 E = MDecl->protocol_end(); P != E; ++P) 1225 // Match properties of category with those of protocol (*P) 1226 MatchOneProtocolPropertiesInClass(CatDecl, *P); 1227 1228 // Go thru the list of protocols for this category and recursively match 1229 // their properties with those in the category. 1230 for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(), 1231 E = CatDecl->protocol_end(); P != E; ++P) 1232 CompareProperties(CatDecl, *P); 1233 } else { 1234 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 1235 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 1236 E = MD->protocol_end(); P != E; ++P) 1237 MatchOneProtocolPropertiesInClass(CatDecl, *P); 1238 } 1239 return; 1240 } 1241 1242 if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { 1243 for (ObjCInterfaceDecl::all_protocol_iterator 1244 P = MDecl->all_referenced_protocol_begin(), 1245 E = MDecl->all_referenced_protocol_end(); P != E; ++P) 1246 // Match properties of class IDecl with those of protocol (*P). 1247 MatchOneProtocolPropertiesInClass(IDecl, *P); 1248 1249 // Go thru the list of protocols for this class and recursively match 1250 // their properties with those declared in the class. 1251 for (ObjCInterfaceDecl::all_protocol_iterator 1252 P = IDecl->all_referenced_protocol_begin(), 1253 E = IDecl->all_referenced_protocol_end(); P != E; ++P) 1254 CompareProperties(IDecl, *P); 1255 } else { 1256 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 1257 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 1258 E = MD->protocol_end(); P != E; ++P) 1259 MatchOneProtocolPropertiesInClass(IDecl, *P); 1260 } 1261} 1262 1263/// isPropertyReadonly - Return true if property is readonly, by searching 1264/// for the property in the class and in its categories and implementations 1265/// 1266bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl, 1267 ObjCInterfaceDecl *IDecl) { 1268 // by far the most common case. 1269 if (!PDecl->isReadOnly()) 1270 return false; 1271 // Even if property is ready only, if interface has a user defined setter, 1272 // it is not considered read only. 1273 if (IDecl->getInstanceMethod(PDecl->getSetterName())) 1274 return false; 1275 1276 // Main class has the property as 'readonly'. Must search 1277 // through the category list to see if the property's 1278 // attribute has been over-ridden to 'readwrite'. 1279 for (ObjCCategoryDecl *Category = IDecl->getCategoryList(); 1280 Category; Category = Category->getNextClassCategory()) { 1281 // Even if property is ready only, if a category has a user defined setter, 1282 // it is not considered read only. 1283 if (Category->getInstanceMethod(PDecl->getSetterName())) 1284 return false; 1285 ObjCPropertyDecl *P = 1286 Category->FindPropertyDeclaration(PDecl->getIdentifier()); 1287 if (P && !P->isReadOnly()) 1288 return false; 1289 } 1290 1291 // Also, check for definition of a setter method in the implementation if 1292 // all else failed. 1293 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) { 1294 if (ObjCImplementationDecl *IMD = 1295 dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) { 1296 if (IMD->getInstanceMethod(PDecl->getSetterName())) 1297 return false; 1298 } else if (ObjCCategoryImplDecl *CIMD = 1299 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 1300 if (CIMD->getInstanceMethod(PDecl->getSetterName())) 1301 return false; 1302 } 1303 } 1304 // Lastly, look through the implementation (if one is in scope). 1305 if (ObjCImplementationDecl *ImpDecl = IDecl->getImplementation()) 1306 if (ImpDecl->getInstanceMethod(PDecl->getSetterName())) 1307 return false; 1308 // If all fails, look at the super class. 1309 if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass()) 1310 return isPropertyReadonly(PDecl, SIDecl); 1311 return true; 1312} 1313 1314/// CollectImmediateProperties - This routine collects all properties in 1315/// the class and its conforming protocols; but not those it its super class. 1316void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, 1317 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap, 1318 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap) { 1319 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1320 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 1321 E = IDecl->prop_end(); P != E; ++P) { 1322 ObjCPropertyDecl *Prop = &*P; 1323 PropMap[Prop->getIdentifier()] = Prop; 1324 } 1325 // scan through class's protocols. 1326 for (ObjCInterfaceDecl::all_protocol_iterator 1327 PI = IDecl->all_referenced_protocol_begin(), 1328 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) 1329 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 1330 } 1331 if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) { 1332 if (!CATDecl->IsClassExtension()) 1333 for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(), 1334 E = CATDecl->prop_end(); P != E; ++P) { 1335 ObjCPropertyDecl *Prop = &*P; 1336 PropMap[Prop->getIdentifier()] = Prop; 1337 } 1338 // scan through class's protocols. 1339 for (ObjCCategoryDecl::protocol_iterator PI = CATDecl->protocol_begin(), 1340 E = CATDecl->protocol_end(); PI != E; ++PI) 1341 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 1342 } 1343 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 1344 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1345 E = PDecl->prop_end(); P != E; ++P) { 1346 ObjCPropertyDecl *Prop = &*P; 1347 ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()]; 1348 // Exclude property for protocols which conform to class's super-class, 1349 // as super-class has to implement the property. 1350 if (!PropertyFromSuper || 1351 PropertyFromSuper->getIdentifier() != Prop->getIdentifier()) { 1352 ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()]; 1353 if (!PropEntry) 1354 PropEntry = Prop; 1355 } 1356 } 1357 // scan through protocol's protocols. 1358 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 1359 E = PDecl->protocol_end(); PI != E; ++PI) 1360 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 1361 } 1362} 1363 1364/// CollectClassPropertyImplementations - This routine collects list of 1365/// properties to be implemented in the class. This includes, class's 1366/// and its conforming protocols' properties. 1367static void CollectClassPropertyImplementations(ObjCContainerDecl *CDecl, 1368 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 1369 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1370 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 1371 E = IDecl->prop_end(); P != E; ++P) { 1372 ObjCPropertyDecl *Prop = &*P; 1373 PropMap[Prop->getIdentifier()] = Prop; 1374 } 1375 for (ObjCInterfaceDecl::all_protocol_iterator 1376 PI = IDecl->all_referenced_protocol_begin(), 1377 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) 1378 CollectClassPropertyImplementations((*PI), PropMap); 1379 } 1380 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 1381 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1382 E = PDecl->prop_end(); P != E; ++P) { 1383 ObjCPropertyDecl *Prop = &*P; 1384 if (!PropMap.count(Prop->getIdentifier())) 1385 PropMap[Prop->getIdentifier()] = Prop; 1386 } 1387 // scan through protocol's protocols. 1388 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 1389 E = PDecl->protocol_end(); PI != E; ++PI) 1390 CollectClassPropertyImplementations((*PI), PropMap); 1391 } 1392} 1393 1394/// CollectSuperClassPropertyImplementations - This routine collects list of 1395/// properties to be implemented in super class(s) and also coming from their 1396/// conforming protocols. 1397static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, 1398 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 1399 if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) { 1400 while (SDecl) { 1401 CollectClassPropertyImplementations(SDecl, PropMap); 1402 SDecl = SDecl->getSuperClass(); 1403 } 1404 } 1405} 1406 1407/// LookupPropertyDecl - Looks up a property in the current class and all 1408/// its protocols. 1409ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, 1410 IdentifierInfo *II) { 1411 if (const ObjCInterfaceDecl *IDecl = 1412 dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1413 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 1414 E = IDecl->prop_end(); P != E; ++P) { 1415 ObjCPropertyDecl *Prop = &*P; 1416 if (Prop->getIdentifier() == II) 1417 return Prop; 1418 } 1419 // scan through class's protocols. 1420 for (ObjCInterfaceDecl::all_protocol_iterator 1421 PI = IDecl->all_referenced_protocol_begin(), 1422 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) { 1423 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 1424 if (Prop) 1425 return Prop; 1426 } 1427 } 1428 else if (const ObjCProtocolDecl *PDecl = 1429 dyn_cast<ObjCProtocolDecl>(CDecl)) { 1430 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1431 E = PDecl->prop_end(); P != E; ++P) { 1432 ObjCPropertyDecl *Prop = &*P; 1433 if (Prop->getIdentifier() == II) 1434 return Prop; 1435 } 1436 // scan through protocol's protocols. 1437 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 1438 E = PDecl->protocol_end(); PI != E; ++PI) { 1439 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 1440 if (Prop) 1441 return Prop; 1442 } 1443 } 1444 return 0; 1445} 1446 1447static IdentifierInfo * getDefaultSynthIvarName(ObjCPropertyDecl *Prop, 1448 ASTContext &Ctx) { 1449 SmallString<128> ivarName; 1450 { 1451 llvm::raw_svector_ostream os(ivarName); 1452 os << '_' << Prop->getIdentifier()->getName(); 1453 } 1454 return &Ctx.Idents.get(ivarName.str()); 1455} 1456 1457/// DefaultSynthesizeProperties - This routine default synthesizes all 1458/// properties which must be synthesized in class's @implementation. 1459void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl, 1460 ObjCInterfaceDecl *IDecl) { 1461 1462 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 1463 CollectClassPropertyImplementations(IDecl, PropMap); 1464 if (PropMap.empty()) 1465 return; 1466 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; 1467 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 1468 1469 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 1470 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1471 ObjCPropertyDecl *Prop = P->second; 1472 // If property to be implemented in the super class, ignore. 1473 if (SuperPropMap[Prop->getIdentifier()]) 1474 continue; 1475 // Is there a matching propery synthesize/dynamic? 1476 if (Prop->isInvalidDecl() || 1477 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 1478 IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) 1479 continue; 1480 // Property may have been synthesized by user. 1481 if (IMPDecl->FindPropertyImplDecl(Prop->getIdentifier())) 1482 continue; 1483 if (IMPDecl->getInstanceMethod(Prop->getGetterName())) { 1484 if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly) 1485 continue; 1486 if (IMPDecl->getInstanceMethod(Prop->getSetterName())) 1487 continue; 1488 } 1489 if (isa<ObjCProtocolDecl>(Prop->getDeclContext())) { 1490 // We won't auto-synthesize properties declared in protocols. 1491 Diag(IMPDecl->getLocation(), 1492 diag::warn_auto_synthesizing_protocol_property); 1493 Diag(Prop->getLocation(), diag::note_property_declare); 1494 continue; 1495 } 1496 1497 // We use invalid SourceLocations for the synthesized ivars since they 1498 // aren't really synthesized at a particular location; they just exist. 1499 // Saying that they are located at the @implementation isn't really going 1500 // to help users. 1501 ObjCPropertyImplDecl *PIDecl = dyn_cast_or_null<ObjCPropertyImplDecl>( 1502 ActOnPropertyImplDecl(S, SourceLocation(), SourceLocation(), 1503 true, 1504 /* property = */ Prop->getIdentifier(), 1505 /* ivar = */ getDefaultSynthIvarName(Prop, Context), 1506 SourceLocation())); 1507 if (PIDecl) { 1508 Diag(Prop->getLocation(), diag::warn_missing_explicit_synthesis); 1509 Diag(IMPDecl->getLocation(), diag::note_while_in_implementation); 1510 } 1511 } 1512} 1513 1514void Sema::DefaultSynthesizeProperties(Scope *S, Decl *D) { 1515 if (!LangOpts.ObjCDefaultSynthProperties || !LangOpts.ObjCNonFragileABI2) 1516 return; 1517 ObjCImplementationDecl *IC=dyn_cast_or_null<ObjCImplementationDecl>(D); 1518 if (!IC) 1519 return; 1520 if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) 1521 if (!IDecl->isObjCRequiresPropertyDefs()) 1522 DefaultSynthesizeProperties(S, IC, IDecl); 1523} 1524 1525void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, 1526 ObjCContainerDecl *CDecl, 1527 const llvm::DenseSet<Selector>& InsMap) { 1528 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; 1529 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) 1530 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 1531 1532 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 1533 CollectImmediateProperties(CDecl, PropMap, SuperPropMap); 1534 if (PropMap.empty()) 1535 return; 1536 1537 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap; 1538 for (ObjCImplDecl::propimpl_iterator 1539 I = IMPDecl->propimpl_begin(), 1540 EI = IMPDecl->propimpl_end(); I != EI; ++I) 1541 PropImplMap.insert(I->getPropertyDecl()); 1542 1543 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 1544 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1545 ObjCPropertyDecl *Prop = P->second; 1546 // Is there a matching propery synthesize/dynamic? 1547 if (Prop->isInvalidDecl() || 1548 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 1549 PropImplMap.count(Prop) || Prop->hasAttr<UnavailableAttr>()) 1550 continue; 1551 if (!InsMap.count(Prop->getGetterName())) { 1552 Diag(IMPDecl->getLocation(), 1553 isa<ObjCCategoryDecl>(CDecl) ? 1554 diag::warn_setter_getter_impl_required_in_category : 1555 diag::warn_setter_getter_impl_required) 1556 << Prop->getDeclName() << Prop->getGetterName(); 1557 Diag(Prop->getLocation(), 1558 diag::note_property_declare); 1559 if (LangOpts.ObjCDefaultSynthProperties && LangOpts.ObjCNonFragileABI2) 1560 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl)) 1561 if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs()) 1562 Diag(RID->getLocation(), diag::note_suppressed_class_declare); 1563 1564 } 1565 1566 if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) { 1567 Diag(IMPDecl->getLocation(), 1568 isa<ObjCCategoryDecl>(CDecl) ? 1569 diag::warn_setter_getter_impl_required_in_category : 1570 diag::warn_setter_getter_impl_required) 1571 << Prop->getDeclName() << Prop->getSetterName(); 1572 Diag(Prop->getLocation(), 1573 diag::note_property_declare); 1574 if (LangOpts.ObjCDefaultSynthProperties && LangOpts.ObjCNonFragileABI2) 1575 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl)) 1576 if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs()) 1577 Diag(RID->getLocation(), diag::note_suppressed_class_declare); 1578 } 1579 } 1580} 1581 1582void 1583Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, 1584 ObjCContainerDecl* IDecl) { 1585 // Rules apply in non-GC mode only 1586 if (getLangOpts().getGC() != LangOptions::NonGC) 1587 return; 1588 for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(), 1589 E = IDecl->prop_end(); 1590 I != E; ++I) { 1591 ObjCPropertyDecl *Property = &*I; 1592 ObjCMethodDecl *GetterMethod = 0; 1593 ObjCMethodDecl *SetterMethod = 0; 1594 bool LookedUpGetterSetter = false; 1595 1596 unsigned Attributes = Property->getPropertyAttributes(); 1597 unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten(); 1598 1599 if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic) && 1600 !(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_nonatomic)) { 1601 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1602 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1603 LookedUpGetterSetter = true; 1604 if (GetterMethod) { 1605 Diag(GetterMethod->getLocation(), 1606 diag::warn_default_atomic_custom_getter_setter) 1607 << Property->getIdentifier() << 0; 1608 Diag(Property->getLocation(), diag::note_property_declare); 1609 } 1610 if (SetterMethod) { 1611 Diag(SetterMethod->getLocation(), 1612 diag::warn_default_atomic_custom_getter_setter) 1613 << Property->getIdentifier() << 1; 1614 Diag(Property->getLocation(), diag::note_property_declare); 1615 } 1616 } 1617 1618 // We only care about readwrite atomic property. 1619 if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) || 1620 !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite)) 1621 continue; 1622 if (const ObjCPropertyImplDecl *PIDecl 1623 = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) { 1624 if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 1625 continue; 1626 if (!LookedUpGetterSetter) { 1627 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1628 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1629 LookedUpGetterSetter = true; 1630 } 1631 if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { 1632 SourceLocation MethodLoc = 1633 (GetterMethod ? GetterMethod->getLocation() 1634 : SetterMethod->getLocation()); 1635 Diag(MethodLoc, diag::warn_atomic_property_rule) 1636 << Property->getIdentifier() << (GetterMethod != 0) 1637 << (SetterMethod != 0); 1638 // fixit stuff. 1639 if (!AttributesAsWritten) { 1640 if (Property->getLParenLoc().isValid()) { 1641 // @property () ... case. 1642 SourceRange PropSourceRange(Property->getAtLoc(), 1643 Property->getLParenLoc()); 1644 Diag(Property->getLocation(), diag::note_atomic_property_fixup_suggest) << 1645 FixItHint::CreateReplacement(PropSourceRange, "@property (nonatomic"); 1646 } 1647 else { 1648 //@property id etc. 1649 SourceLocation endLoc = 1650 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); 1651 endLoc = endLoc.getLocWithOffset(-1); 1652 SourceRange PropSourceRange(Property->getAtLoc(), endLoc); 1653 Diag(Property->getLocation(), diag::note_atomic_property_fixup_suggest) << 1654 FixItHint::CreateReplacement(PropSourceRange, "@property (nonatomic) "); 1655 } 1656 } 1657 else if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic)) { 1658 // @property () ... case. 1659 SourceLocation endLoc = Property->getLParenLoc(); 1660 SourceRange PropSourceRange(Property->getAtLoc(), endLoc); 1661 Diag(Property->getLocation(), diag::note_atomic_property_fixup_suggest) << 1662 FixItHint::CreateReplacement(PropSourceRange, "@property (nonatomic, "); 1663 } 1664 else 1665 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest); 1666 Diag(Property->getLocation(), diag::note_property_declare); 1667 } 1668 } 1669 } 1670} 1671 1672void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) { 1673 if (getLangOpts().getGC() == LangOptions::GCOnly) 1674 return; 1675 1676 for (ObjCImplementationDecl::propimpl_iterator 1677 i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) { 1678 ObjCPropertyImplDecl *PID = &*i; 1679 if (PID->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) 1680 continue; 1681 1682 const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 1683 if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() && 1684 !D->getInstanceMethod(PD->getGetterName())) { 1685 ObjCMethodDecl *method = PD->getGetterMethodDecl(); 1686 if (!method) 1687 continue; 1688 ObjCMethodFamily family = method->getMethodFamily(); 1689 if (family == OMF_alloc || family == OMF_copy || 1690 family == OMF_mutableCopy || family == OMF_new) { 1691 if (getLangOpts().ObjCAutoRefCount) 1692 Diag(PID->getLocation(), diag::err_ownin_getter_rule); 1693 else 1694 Diag(PID->getLocation(), diag::warn_owning_getter_rule); 1695 Diag(PD->getLocation(), diag::note_property_declare); 1696 } 1697 } 1698 } 1699} 1700 1701/// AddPropertyAttrs - Propagates attributes from a property to the 1702/// implicitly-declared getter or setter for that property. 1703static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, 1704 ObjCPropertyDecl *Property) { 1705 // Should we just clone all attributes over? 1706 for (Decl::attr_iterator A = Property->attr_begin(), 1707 AEnd = Property->attr_end(); 1708 A != AEnd; ++A) { 1709 if (isa<DeprecatedAttr>(*A) || 1710 isa<UnavailableAttr>(*A) || 1711 isa<AvailabilityAttr>(*A)) 1712 PropertyMethod->addAttr((*A)->clone(S.Context)); 1713 } 1714} 1715 1716/// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods 1717/// have the property type and issue diagnostics if they don't. 1718/// Also synthesize a getter/setter method if none exist (and update the 1719/// appropriate lookup tables. FIXME: Should reconsider if adding synthesized 1720/// methods is the "right" thing to do. 1721void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, 1722 ObjCContainerDecl *CD, 1723 ObjCPropertyDecl *redeclaredProperty, 1724 ObjCContainerDecl *lexicalDC) { 1725 1726 ObjCMethodDecl *GetterMethod, *SetterMethod; 1727 1728 GetterMethod = CD->getInstanceMethod(property->getGetterName()); 1729 SetterMethod = CD->getInstanceMethod(property->getSetterName()); 1730 DiagnosePropertyAccessorMismatch(property, GetterMethod, 1731 property->getLocation()); 1732 1733 if (SetterMethod) { 1734 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1735 property->getPropertyAttributes(); 1736 if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) && 1737 Context.getCanonicalType(SetterMethod->getResultType()) != 1738 Context.VoidTy) 1739 Diag(SetterMethod->getLocation(), diag::err_setter_type_void); 1740 if (SetterMethod->param_size() != 1 || 1741 !Context.hasSameUnqualifiedType( 1742 (*SetterMethod->param_begin())->getType().getNonReferenceType(), 1743 property->getType().getNonReferenceType())) { 1744 Diag(property->getLocation(), 1745 diag::warn_accessor_property_type_mismatch) 1746 << property->getDeclName() 1747 << SetterMethod->getSelector(); 1748 Diag(SetterMethod->getLocation(), diag::note_declared_at); 1749 } 1750 } 1751 1752 // Synthesize getter/setter methods if none exist. 1753 // Find the default getter and if one not found, add one. 1754 // FIXME: The synthesized property we set here is misleading. We almost always 1755 // synthesize these methods unless the user explicitly provided prototypes 1756 // (which is odd, but allowed). Sema should be typechecking that the 1757 // declarations jive in that situation (which it is not currently). 1758 if (!GetterMethod) { 1759 // No instance method of same name as property getter name was found. 1760 // Declare a getter method and add it to the list of methods 1761 // for this class. 1762 SourceLocation Loc = redeclaredProperty ? 1763 redeclaredProperty->getLocation() : 1764 property->getLocation(); 1765 1766 GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc, 1767 property->getGetterName(), 1768 property->getType(), 0, CD, /*isInstance=*/true, 1769 /*isVariadic=*/false, /*isSynthesized=*/true, 1770 /*isImplicitlyDeclared=*/true, /*isDefined=*/false, 1771 (property->getPropertyImplementation() == 1772 ObjCPropertyDecl::Optional) ? 1773 ObjCMethodDecl::Optional : 1774 ObjCMethodDecl::Required); 1775 CD->addDecl(GetterMethod); 1776 1777 AddPropertyAttrs(*this, GetterMethod, property); 1778 1779 // FIXME: Eventually this shouldn't be needed, as the lexical context 1780 // and the real context should be the same. 1781 if (lexicalDC) 1782 GetterMethod->setLexicalDeclContext(lexicalDC); 1783 if (property->hasAttr<NSReturnsNotRetainedAttr>()) 1784 GetterMethod->addAttr( 1785 ::new (Context) NSReturnsNotRetainedAttr(Loc, Context)); 1786 } else 1787 // A user declared getter will be synthesize when @synthesize of 1788 // the property with the same name is seen in the @implementation 1789 GetterMethod->setSynthesized(true); 1790 property->setGetterMethodDecl(GetterMethod); 1791 1792 // Skip setter if property is read-only. 1793 if (!property->isReadOnly()) { 1794 // Find the default setter and if one not found, add one. 1795 if (!SetterMethod) { 1796 // No instance method of same name as property setter name was found. 1797 // Declare a setter method and add it to the list of methods 1798 // for this class. 1799 SourceLocation Loc = redeclaredProperty ? 1800 redeclaredProperty->getLocation() : 1801 property->getLocation(); 1802 1803 SetterMethod = 1804 ObjCMethodDecl::Create(Context, Loc, Loc, 1805 property->getSetterName(), Context.VoidTy, 0, 1806 CD, /*isInstance=*/true, /*isVariadic=*/false, 1807 /*isSynthesized=*/true, 1808 /*isImplicitlyDeclared=*/true, 1809 /*isDefined=*/false, 1810 (property->getPropertyImplementation() == 1811 ObjCPropertyDecl::Optional) ? 1812 ObjCMethodDecl::Optional : 1813 ObjCMethodDecl::Required); 1814 1815 // Invent the arguments for the setter. We don't bother making a 1816 // nice name for the argument. 1817 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, 1818 Loc, Loc, 1819 property->getIdentifier(), 1820 property->getType().getUnqualifiedType(), 1821 /*TInfo=*/0, 1822 SC_None, 1823 SC_None, 1824 0); 1825 SetterMethod->setMethodParams(Context, Argument, 1826 ArrayRef<SourceLocation>()); 1827 1828 AddPropertyAttrs(*this, SetterMethod, property); 1829 1830 CD->addDecl(SetterMethod); 1831 // FIXME: Eventually this shouldn't be needed, as the lexical context 1832 // and the real context should be the same. 1833 if (lexicalDC) 1834 SetterMethod->setLexicalDeclContext(lexicalDC); 1835 } else 1836 // A user declared setter will be synthesize when @synthesize of 1837 // the property with the same name is seen in the @implementation 1838 SetterMethod->setSynthesized(true); 1839 property->setSetterMethodDecl(SetterMethod); 1840 } 1841 // Add any synthesized methods to the global pool. This allows us to 1842 // handle the following, which is supported by GCC (and part of the design). 1843 // 1844 // @interface Foo 1845 // @property double bar; 1846 // @end 1847 // 1848 // void thisIsUnfortunate() { 1849 // id foo; 1850 // double bar = [foo bar]; 1851 // } 1852 // 1853 if (GetterMethod) 1854 AddInstanceMethodToGlobalPool(GetterMethod); 1855 if (SetterMethod) 1856 AddInstanceMethodToGlobalPool(SetterMethod); 1857 1858 ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(CD); 1859 if (!CurrentClass) { 1860 if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CD)) 1861 CurrentClass = Cat->getClassInterface(); 1862 else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(CD)) 1863 CurrentClass = Impl->getClassInterface(); 1864 } 1865 if (GetterMethod) 1866 CheckObjCMethodOverrides(GetterMethod, CurrentClass, Sema::RTC_Unknown); 1867 if (SetterMethod) 1868 CheckObjCMethodOverrides(SetterMethod, CurrentClass, Sema::RTC_Unknown); 1869} 1870 1871void Sema::CheckObjCPropertyAttributes(Decl *PDecl, 1872 SourceLocation Loc, 1873 unsigned &Attributes) { 1874 // FIXME: Improve the reported location. 1875 if (!PDecl || PDecl->isInvalidDecl()) 1876 return; 1877 1878 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 1879 QualType PropertyTy = PropertyDecl->getType(); 1880 1881 if (getLangOpts().ObjCAutoRefCount && 1882 (Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1883 PropertyTy->isObjCRetainableType()) { 1884 // 'readonly' property with no obvious lifetime. 1885 // its life time will be determined by its backing ivar. 1886 unsigned rel = (ObjCDeclSpec::DQ_PR_unsafe_unretained | 1887 ObjCDeclSpec::DQ_PR_copy | 1888 ObjCDeclSpec::DQ_PR_retain | 1889 ObjCDeclSpec::DQ_PR_strong | 1890 ObjCDeclSpec::DQ_PR_weak | 1891 ObjCDeclSpec::DQ_PR_assign); 1892 if ((Attributes & rel) == 0) 1893 return; 1894 } 1895 1896 // readonly and readwrite/assign/retain/copy conflict. 1897 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1898 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 1899 ObjCDeclSpec::DQ_PR_assign | 1900 ObjCDeclSpec::DQ_PR_unsafe_unretained | 1901 ObjCDeclSpec::DQ_PR_copy | 1902 ObjCDeclSpec::DQ_PR_retain | 1903 ObjCDeclSpec::DQ_PR_strong))) { 1904 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ? 1905 "readwrite" : 1906 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 1907 "assign" : 1908 (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) ? 1909 "unsafe_unretained" : 1910 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 1911 "copy" : "retain"; 1912 1913 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 1914 diag::err_objc_property_attr_mutually_exclusive : 1915 diag::warn_objc_property_attr_mutually_exclusive) 1916 << "readonly" << which; 1917 } 1918 1919 // Check for copy or retain on non-object types. 1920 if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 1921 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) && 1922 !PropertyTy->isObjCRetainableType() && 1923 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { 1924 Diag(Loc, diag::err_objc_property_requires_object) 1925 << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" : 1926 Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)"); 1927 Attributes &= ~(ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 1928 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong); 1929 PropertyDecl->setInvalidDecl(); 1930 } 1931 1932 // Check for more than one of { assign, copy, retain }. 1933 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 1934 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1935 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1936 << "assign" << "copy"; 1937 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1938 } 1939 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1940 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1941 << "assign" << "retain"; 1942 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1943 } 1944 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 1945 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1946 << "assign" << "strong"; 1947 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 1948 } 1949 if (getLangOpts().ObjCAutoRefCount && 1950 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1951 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1952 << "assign" << "weak"; 1953 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1954 } 1955 } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) { 1956 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1957 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1958 << "unsafe_unretained" << "copy"; 1959 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1960 } 1961 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1962 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1963 << "unsafe_unretained" << "retain"; 1964 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1965 } 1966 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 1967 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1968 << "unsafe_unretained" << "strong"; 1969 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 1970 } 1971 if (getLangOpts().ObjCAutoRefCount && 1972 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1973 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1974 << "unsafe_unretained" << "weak"; 1975 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1976 } 1977 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1978 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1979 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1980 << "copy" << "retain"; 1981 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1982 } 1983 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 1984 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1985 << "copy" << "strong"; 1986 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 1987 } 1988 if (Attributes & ObjCDeclSpec::DQ_PR_weak) { 1989 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1990 << "copy" << "weak"; 1991 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1992 } 1993 } 1994 else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) && 1995 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1996 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1997 << "retain" << "weak"; 1998 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1999 } 2000 else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) && 2001 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 2002 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2003 << "strong" << "weak"; 2004 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 2005 } 2006 2007 if ((Attributes & ObjCDeclSpec::DQ_PR_atomic) && 2008 (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)) { 2009 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2010 << "atomic" << "nonatomic"; 2011 Attributes &= ~ObjCDeclSpec::DQ_PR_atomic; 2012 } 2013 2014 // Warn if user supplied no assignment attribute, property is 2015 // readwrite, and this is an object type. 2016 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | 2017 ObjCDeclSpec::DQ_PR_unsafe_unretained | 2018 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong | 2019 ObjCDeclSpec::DQ_PR_weak)) && 2020 PropertyTy->isObjCObjectPointerType()) { 2021 if (getLangOpts().ObjCAutoRefCount) 2022 // With arc, @property definitions should default to (strong) when 2023 // not specified; including when property is 'readonly'. 2024 PropertyDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 2025 else if (!(Attributes & ObjCDeclSpec::DQ_PR_readonly)) { 2026 bool isAnyClassTy = 2027 (PropertyTy->isObjCClassType() || 2028 PropertyTy->isObjCQualifiedClassType()); 2029 // In non-gc, non-arc mode, 'Class' is treated as a 'void *' no need to 2030 // issue any warning. 2031 if (isAnyClassTy && getLangOpts().getGC() == LangOptions::NonGC) 2032 ; 2033 else { 2034 // Skip this warning in gc-only mode. 2035 if (getLangOpts().getGC() != LangOptions::GCOnly) 2036 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 2037 2038 // If non-gc code warn that this is likely inappropriate. 2039 if (getLangOpts().getGC() == LangOptions::NonGC) 2040 Diag(Loc, diag::warn_objc_property_default_assign_on_object); 2041 } 2042 } 2043 2044 // FIXME: Implement warning dependent on NSCopying being 2045 // implemented. See also: 2046 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496> 2047 // (please trim this list while you are at it). 2048 } 2049 2050 if (!(Attributes & ObjCDeclSpec::DQ_PR_copy) 2051 &&!(Attributes & ObjCDeclSpec::DQ_PR_readonly) 2052 && getLangOpts().getGC() == LangOptions::GCOnly 2053 && PropertyTy->isBlockPointerType()) 2054 Diag(Loc, diag::warn_objc_property_copy_missing_on_block); 2055 else if (getLangOpts().ObjCAutoRefCount && 2056 (Attributes & ObjCDeclSpec::DQ_PR_retain) && 2057 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 2058 !(Attributes & ObjCDeclSpec::DQ_PR_strong) && 2059 PropertyTy->isBlockPointerType()) 2060 Diag(Loc, diag::warn_objc_property_retain_of_block); 2061 2062 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 2063 (Attributes & ObjCDeclSpec::DQ_PR_setter)) 2064 Diag(Loc, diag::warn_objc_readonly_property_has_setter); 2065 2066} 2067