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