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