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/Sema/Initialization.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 /// \brief Check this Objective-C property against a property declared in the 115 /// given protocol. 116 static void 117 CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop, 118 ObjCProtocolDecl *Proto, 119 llvm::SmallPtrSet<ObjCProtocolDecl *, 16> &Known) { 120 // Have we seen this protocol before? 121 if (!Known.insert(Proto)) 122 return; 123 124 // Look for a property with the same name. 125 DeclContext::lookup_result R = Proto->lookup(Prop->getDeclName()); 126 for (unsigned I = 0, N = R.size(); I != N; ++I) { 127 if (ObjCPropertyDecl *ProtoProp = dyn_cast<ObjCPropertyDecl>(R[I])) { 128 S.DiagnosePropertyMismatch(Prop, ProtoProp, Proto->getIdentifier(), true); 129 return; 130 } 131 } 132 133 // Check this property against any protocols we inherit. 134 for (auto *P : Proto->protocols()) 135 CheckPropertyAgainstProtocol(S, Prop, P, Known); 136 } 137 138 Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, 139 SourceLocation LParenLoc, 140 FieldDeclarator &FD, 141 ObjCDeclSpec &ODS, 142 Selector GetterSel, 143 Selector SetterSel, 144 bool *isOverridingProperty, 145 tok::ObjCKeywordKind MethodImplKind, 146 DeclContext *lexicalDC) { 147 unsigned Attributes = ODS.getPropertyAttributes(); 148 TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S); 149 QualType T = TSI->getType(); 150 Attributes |= deduceWeakPropertyFromType(*this, T); 151 152 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) || 153 // default is readwrite! 154 !(Attributes & ObjCDeclSpec::DQ_PR_readonly)); 155 // property is defaulted to 'assign' if it is readwrite and is 156 // not retain or copy 157 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) || 158 (isReadWrite && 159 !(Attributes & ObjCDeclSpec::DQ_PR_retain) && 160 !(Attributes & ObjCDeclSpec::DQ_PR_strong) && 161 !(Attributes & ObjCDeclSpec::DQ_PR_copy) && 162 !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) && 163 !(Attributes & ObjCDeclSpec::DQ_PR_weak))); 164 165 // Proceed with constructing the ObjCPropertyDecls. 166 ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext); 167 ObjCPropertyDecl *Res = nullptr; 168 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 169 if (CDecl->IsClassExtension()) { 170 Res = HandlePropertyInClassExtension(S, AtLoc, LParenLoc, 171 FD, GetterSel, SetterSel, 172 isAssign, isReadWrite, 173 Attributes, 174 ODS.getPropertyAttributes(), 175 isOverridingProperty, TSI, 176 MethodImplKind); 177 if (!Res) 178 return nullptr; 179 } 180 } 181 182 if (!Res) { 183 Res = CreatePropertyDecl(S, ClassDecl, AtLoc, LParenLoc, FD, 184 GetterSel, SetterSel, isAssign, isReadWrite, 185 Attributes, ODS.getPropertyAttributes(), 186 TSI, MethodImplKind); 187 if (lexicalDC) 188 Res->setLexicalDeclContext(lexicalDC); 189 } 190 191 // Validate the attributes on the @property. 192 CheckObjCPropertyAttributes(Res, AtLoc, Attributes, 193 (isa<ObjCInterfaceDecl>(ClassDecl) || 194 isa<ObjCProtocolDecl>(ClassDecl))); 195 196 if (getLangOpts().ObjCAutoRefCount) 197 checkARCPropertyDecl(*this, Res); 198 199 llvm::SmallPtrSet<ObjCProtocolDecl *, 16> KnownProtos; 200 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { 201 // For a class, compare the property against a property in our superclass. 202 bool FoundInSuper = false; 203 ObjCInterfaceDecl *CurrentInterfaceDecl = IFace; 204 while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) { 205 DeclContext::lookup_result R = Super->lookup(Res->getDeclName()); 206 for (unsigned I = 0, N = R.size(); I != N; ++I) { 207 if (ObjCPropertyDecl *SuperProp = dyn_cast<ObjCPropertyDecl>(R[I])) { 208 DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false); 209 FoundInSuper = true; 210 break; 211 } 212 } 213 if (FoundInSuper) 214 break; 215 else 216 CurrentInterfaceDecl = Super; 217 } 218 219 if (FoundInSuper) { 220 // Also compare the property against a property in our protocols. 221 for (auto *P : CurrentInterfaceDecl->protocols()) { 222 CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); 223 } 224 } else { 225 // Slower path: look in all protocols we referenced. 226 for (auto *P : IFace->all_referenced_protocols()) { 227 CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); 228 } 229 } 230 } else if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 231 for (auto *P : Cat->protocols()) 232 CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); 233 } else { 234 ObjCProtocolDecl *Proto = cast<ObjCProtocolDecl>(ClassDecl); 235 for (auto *P : Proto->protocols()) 236 CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos); 237 } 238 239 ActOnDocumentableDecl(Res); 240 return Res; 241 } 242 243 static ObjCPropertyDecl::PropertyAttributeKind 244 makePropertyAttributesAsWritten(unsigned Attributes) { 245 unsigned attributesAsWritten = 0; 246 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 247 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readonly; 248 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 249 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readwrite; 250 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 251 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_getter; 252 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 253 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_setter; 254 if (Attributes & ObjCDeclSpec::DQ_PR_assign) 255 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_assign; 256 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 257 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_retain; 258 if (Attributes & ObjCDeclSpec::DQ_PR_strong) 259 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_strong; 260 if (Attributes & ObjCDeclSpec::DQ_PR_weak) 261 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_weak; 262 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 263 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_copy; 264 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) 265 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_unsafe_unretained; 266 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 267 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_nonatomic; 268 if (Attributes & ObjCDeclSpec::DQ_PR_atomic) 269 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_atomic; 270 271 return (ObjCPropertyDecl::PropertyAttributeKind)attributesAsWritten; 272 } 273 274 static bool LocPropertyAttribute( ASTContext &Context, const char *attrName, 275 SourceLocation LParenLoc, SourceLocation &Loc) { 276 if (LParenLoc.isMacroID()) 277 return false; 278 279 SourceManager &SM = Context.getSourceManager(); 280 std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(LParenLoc); 281 // Try to load the file buffer. 282 bool invalidTemp = false; 283 StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); 284 if (invalidTemp) 285 return false; 286 const char *tokenBegin = file.data() + locInfo.second; 287 288 // Lex from the start of the given location. 289 Lexer lexer(SM.getLocForStartOfFile(locInfo.first), 290 Context.getLangOpts(), 291 file.begin(), tokenBegin, file.end()); 292 Token Tok; 293 do { 294 lexer.LexFromRawLexer(Tok); 295 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == attrName) { 296 Loc = Tok.getLocation(); 297 return true; 298 } 299 } while (Tok.isNot(tok::r_paren)); 300 return false; 301 302 } 303 304 static unsigned getOwnershipRule(unsigned attr) { 305 return attr & (ObjCPropertyDecl::OBJC_PR_assign | 306 ObjCPropertyDecl::OBJC_PR_retain | 307 ObjCPropertyDecl::OBJC_PR_copy | 308 ObjCPropertyDecl::OBJC_PR_weak | 309 ObjCPropertyDecl::OBJC_PR_strong | 310 ObjCPropertyDecl::OBJC_PR_unsafe_unretained); 311 } 312 313 ObjCPropertyDecl * 314 Sema::HandlePropertyInClassExtension(Scope *S, 315 SourceLocation AtLoc, 316 SourceLocation LParenLoc, 317 FieldDeclarator &FD, 318 Selector GetterSel, Selector SetterSel, 319 const bool isAssign, 320 const bool isReadWrite, 321 const unsigned Attributes, 322 const unsigned AttributesAsWritten, 323 bool *isOverridingProperty, 324 TypeSourceInfo *T, 325 tok::ObjCKeywordKind MethodImplKind) { 326 ObjCCategoryDecl *CDecl = cast<ObjCCategoryDecl>(CurContext); 327 // Diagnose if this property is already in continuation class. 328 DeclContext *DC = CurContext; 329 IdentifierInfo *PropertyId = FD.D.getIdentifier(); 330 ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface(); 331 332 if (CCPrimary) { 333 // Check for duplicate declaration of this property in current and 334 // other class extensions. 335 for (const auto *Ext : CCPrimary->known_extensions()) { 336 if (ObjCPropertyDecl *prevDecl 337 = ObjCPropertyDecl::findPropertyDecl(Ext, PropertyId)) { 338 Diag(AtLoc, diag::err_duplicate_property); 339 Diag(prevDecl->getLocation(), diag::note_property_declare); 340 return nullptr; 341 } 342 } 343 } 344 345 // Create a new ObjCPropertyDecl with the DeclContext being 346 // the class extension. 347 // FIXME. We should really be using CreatePropertyDecl for this. 348 ObjCPropertyDecl *PDecl = 349 ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(), 350 PropertyId, AtLoc, LParenLoc, T); 351 PDecl->setPropertyAttributesAsWritten( 352 makePropertyAttributesAsWritten(AttributesAsWritten)); 353 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 354 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 355 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 356 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 357 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 358 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); 359 if (Attributes & ObjCDeclSpec::DQ_PR_atomic) 360 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic); 361 // Set setter/getter selector name. Needed later. 362 PDecl->setGetterName(GetterSel); 363 PDecl->setSetterName(SetterSel); 364 ProcessDeclAttributes(S, PDecl, FD.D); 365 DC->addDecl(PDecl); 366 367 // We need to look in the @interface to see if the @property was 368 // already declared. 369 if (!CCPrimary) { 370 Diag(CDecl->getLocation(), diag::err_continuation_class); 371 *isOverridingProperty = true; 372 return nullptr; 373 } 374 375 // Find the property in continuation class's primary class only. 376 ObjCPropertyDecl *PIDecl = 377 CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId); 378 379 if (!PIDecl) { 380 // No matching property found in the primary class. Just fall thru 381 // and add property to continuation class's primary class. 382 ObjCPropertyDecl *PrimaryPDecl = 383 CreatePropertyDecl(S, CCPrimary, AtLoc, LParenLoc, 384 FD, GetterSel, SetterSel, isAssign, isReadWrite, 385 Attributes,AttributesAsWritten, T, MethodImplKind, DC); 386 387 // A case of continuation class adding a new property in the class. This 388 // is not what it was meant for. However, gcc supports it and so should we. 389 // Make sure setter/getters are declared here. 390 ProcessPropertyDecl(PrimaryPDecl, CCPrimary, 391 /* redeclaredProperty = */ nullptr, 392 /* lexicalDC = */ CDecl); 393 PDecl->setGetterMethodDecl(PrimaryPDecl->getGetterMethodDecl()); 394 PDecl->setSetterMethodDecl(PrimaryPDecl->getSetterMethodDecl()); 395 if (ASTMutationListener *L = Context.getASTMutationListener()) 396 L->AddedObjCPropertyInClassExtension(PrimaryPDecl, /*OrigProp=*/nullptr, 397 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 nullptr; 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 nullptr; 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 = 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 nullptr; 809 } 810 if (PropertyIvarLoc.isInvalid()) 811 PropertyIvarLoc = PropertyLoc; 812 SourceLocation PropertyDiagLoc = PropertyLoc; 813 if (PropertyDiagLoc.isInvalid()) 814 PropertyDiagLoc = ClassImpDecl->getLocStart(); 815 ObjCPropertyDecl *property = nullptr; 816 ObjCInterfaceDecl *IDecl = nullptr; 817 // Find the class or category class where this property must have 818 // a declaration. 819 ObjCImplementationDecl *IC = nullptr; 820 ObjCCategoryImplDecl *CatImplClass = nullptr; 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 nullptr; 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 nullptr; 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 nullptr; 893 } 894 IDecl = CatImplClass->getClassInterface(); 895 if (!IDecl) { 896 Diag(AtLoc, diag::error_missing_property_interface); 897 return nullptr; 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 nullptr; 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 nullptr; 912 } 913 } else { 914 Diag(AtLoc, diag::error_bad_property_context); 915 return nullptr; 916 } 917 ObjCIvarDecl *Ivar = nullptr; 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=nullptr; 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 == nullptr) << 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=*/nullptr, 1032 ObjCIvarDecl::Private, 1033 (Expr *)nullptr, 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, nullptr, 1150 VK_RValue); 1151 Expr *IvarRefExpr = 1152 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc, 1153 Ivar->getLocation(), 1154 LoadSelfExpr, true, true); 1155 ExprResult Res = PerformCopyInitialization( 1156 InitializedEntity::InitializeResult(PropertyDiagLoc, 1157 getterMethod->getReturnType(), 1158 /*NRVO=*/false), 1159 PropertyDiagLoc, IvarRefExpr); 1160 if (!Res.isInvalid()) { 1161 Expr *ResExpr = Res.getAs<Expr>(); 1162 if (ResExpr) 1163 ResExpr = MaybeCreateExprWithCleanups(ResExpr); 1164 PIDecl->setGetterCXXConstructor(ResExpr); 1165 } 1166 } 1167 if (property->hasAttr<NSReturnsNotRetainedAttr>() && 1168 !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) { 1169 Diag(getterMethod->getLocation(), 1170 diag::warn_property_getter_owning_mismatch); 1171 Diag(property->getLocation(), diag::note_property_declare); 1172 } 1173 if (getLangOpts().ObjCAutoRefCount && Synthesize) 1174 switch (getterMethod->getMethodFamily()) { 1175 case OMF_retain: 1176 case OMF_retainCount: 1177 case OMF_release: 1178 case OMF_autorelease: 1179 Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def) 1180 << 1 << getterMethod->getSelector(); 1181 break; 1182 default: 1183 break; 1184 } 1185 } 1186 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) { 1187 setterMethod->createImplicitParams(Context, IDecl); 1188 if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr && 1189 Ivar->getType()->isRecordType()) { 1190 // FIXME. Eventually we want to do this for Objective-C as well. 1191 SynthesizedFunctionScope Scope(*this, setterMethod); 1192 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); 1193 DeclRefExpr *SelfExpr = 1194 new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(), 1195 VK_LValue, PropertyDiagLoc); 1196 MarkDeclRefReferenced(SelfExpr); 1197 Expr *LoadSelfExpr = 1198 ImplicitCastExpr::Create(Context, SelfDecl->getType(), 1199 CK_LValueToRValue, SelfExpr, nullptr, 1200 VK_RValue); 1201 Expr *lhs = 1202 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc, 1203 Ivar->getLocation(), 1204 LoadSelfExpr, true, true); 1205 ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); 1206 ParmVarDecl *Param = (*P); 1207 QualType T = Param->getType().getNonReferenceType(); 1208 DeclRefExpr *rhs = new (Context) DeclRefExpr(Param, false, T, 1209 VK_LValue, PropertyDiagLoc); 1210 MarkDeclRefReferenced(rhs); 1211 ExprResult Res = BuildBinOp(S, PropertyDiagLoc, 1212 BO_Assign, lhs, rhs); 1213 if (property->getPropertyAttributes() & 1214 ObjCPropertyDecl::OBJC_PR_atomic) { 1215 Expr *callExpr = Res.getAs<Expr>(); 1216 if (const CXXOperatorCallExpr *CXXCE = 1217 dyn_cast_or_null<CXXOperatorCallExpr>(callExpr)) 1218 if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee()) 1219 if (!FuncDecl->isTrivial()) 1220 if (property->getType()->isReferenceType()) { 1221 Diag(PropertyDiagLoc, 1222 diag::err_atomic_property_nontrivial_assign_op) 1223 << property->getType(); 1224 Diag(FuncDecl->getLocStart(), 1225 diag::note_callee_decl) << FuncDecl; 1226 } 1227 } 1228 PIDecl->setSetterCXXAssignment(Res.getAs<Expr>()); 1229 } 1230 } 1231 1232 if (IC) { 1233 if (Synthesize) 1234 if (ObjCPropertyImplDecl *PPIDecl = 1235 IC->FindPropertyImplIvarDecl(PropertyIvar)) { 1236 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 1237 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 1238 << PropertyIvar; 1239 Diag(PPIDecl->getLocation(), diag::note_previous_use); 1240 } 1241 1242 if (ObjCPropertyImplDecl *PPIDecl 1243 = IC->FindPropertyImplDecl(PropertyId)) { 1244 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 1245 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 1246 return nullptr; 1247 } 1248 IC->addPropertyImplementation(PIDecl); 1249 if (getLangOpts().ObjCDefaultSynthProperties && 1250 getLangOpts().ObjCRuntime.isNonFragile() && 1251 !IDecl->isObjCRequiresPropertyDefs()) { 1252 // Diagnose if an ivar was lazily synthesdized due to a previous 1253 // use and if 1) property is @dynamic or 2) property is synthesized 1254 // but it requires an ivar of different name. 1255 ObjCInterfaceDecl *ClassDeclared=nullptr; 1256 ObjCIvarDecl *Ivar = nullptr; 1257 if (!Synthesize) 1258 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 1259 else { 1260 if (PropertyIvar && PropertyIvar != PropertyId) 1261 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 1262 } 1263 // Issue diagnostics only if Ivar belongs to current class. 1264 if (Ivar && Ivar->getSynthesize() && 1265 declaresSameEntity(IC->getClassInterface(), ClassDeclared)) { 1266 Diag(Ivar->getLocation(), diag::err_undeclared_var_use) 1267 << PropertyId; 1268 Ivar->setInvalidDecl(); 1269 } 1270 } 1271 } else { 1272 if (Synthesize) 1273 if (ObjCPropertyImplDecl *PPIDecl = 1274 CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) { 1275 Diag(PropertyDiagLoc, diag::error_duplicate_ivar_use) 1276 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 1277 << PropertyIvar; 1278 Diag(PPIDecl->getLocation(), diag::note_previous_use); 1279 } 1280 1281 if (ObjCPropertyImplDecl *PPIDecl = 1282 CatImplClass->FindPropertyImplDecl(PropertyId)) { 1283 Diag(PropertyDiagLoc, diag::error_property_implemented) << PropertyId; 1284 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 1285 return nullptr; 1286 } 1287 CatImplClass->addPropertyImplementation(PIDecl); 1288 } 1289 1290 return PIDecl; 1291 } 1292 1293 //===----------------------------------------------------------------------===// 1294 // Helper methods. 1295 //===----------------------------------------------------------------------===// 1296 1297 /// DiagnosePropertyMismatch - Compares two properties for their 1298 /// attributes and types and warns on a variety of inconsistencies. 1299 /// 1300 void 1301 Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, 1302 ObjCPropertyDecl *SuperProperty, 1303 const IdentifierInfo *inheritedName, 1304 bool OverridingProtocolProperty) { 1305 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1306 Property->getPropertyAttributes(); 1307 ObjCPropertyDecl::PropertyAttributeKind SAttr = 1308 SuperProperty->getPropertyAttributes(); 1309 1310 // We allow readonly properties without an explicit ownership 1311 // (assign/unsafe_unretained/weak/retain/strong/copy) in super class 1312 // to be overridden by a property with any explicit ownership in the subclass. 1313 if (!OverridingProtocolProperty && 1314 !getOwnershipRule(SAttr) && getOwnershipRule(CAttr)) 1315 ; 1316 else { 1317 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) 1318 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) 1319 Diag(Property->getLocation(), diag::warn_readonly_property) 1320 << Property->getDeclName() << inheritedName; 1321 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) 1322 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) 1323 Diag(Property->getLocation(), diag::warn_property_attribute) 1324 << Property->getDeclName() << "copy" << inheritedName; 1325 else if (!(SAttr & ObjCPropertyDecl::OBJC_PR_readonly)){ 1326 unsigned CAttrRetain = 1327 (CAttr & 1328 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 1329 unsigned SAttrRetain = 1330 (SAttr & 1331 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 1332 bool CStrong = (CAttrRetain != 0); 1333 bool SStrong = (SAttrRetain != 0); 1334 if (CStrong != SStrong) 1335 Diag(Property->getLocation(), diag::warn_property_attribute) 1336 << Property->getDeclName() << "retain (or strong)" << inheritedName; 1337 } 1338 } 1339 1340 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) 1341 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) { 1342 Diag(Property->getLocation(), diag::warn_property_attribute) 1343 << Property->getDeclName() << "atomic" << inheritedName; 1344 Diag(SuperProperty->getLocation(), diag::note_property_declare); 1345 } 1346 if (Property->getSetterName() != SuperProperty->getSetterName()) { 1347 Diag(Property->getLocation(), diag::warn_property_attribute) 1348 << Property->getDeclName() << "setter" << inheritedName; 1349 Diag(SuperProperty->getLocation(), diag::note_property_declare); 1350 } 1351 if (Property->getGetterName() != SuperProperty->getGetterName()) { 1352 Diag(Property->getLocation(), diag::warn_property_attribute) 1353 << Property->getDeclName() << "getter" << inheritedName; 1354 Diag(SuperProperty->getLocation(), diag::note_property_declare); 1355 } 1356 1357 QualType LHSType = 1358 Context.getCanonicalType(SuperProperty->getType()); 1359 QualType RHSType = 1360 Context.getCanonicalType(Property->getType()); 1361 1362 if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) { 1363 // Do cases not handled in above. 1364 // FIXME. For future support of covariant property types, revisit this. 1365 bool IncompatibleObjC = false; 1366 QualType ConvertedType; 1367 if (!isObjCPointerConversion(RHSType, LHSType, 1368 ConvertedType, IncompatibleObjC) || 1369 IncompatibleObjC) { 1370 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) 1371 << Property->getType() << SuperProperty->getType() << inheritedName; 1372 Diag(SuperProperty->getLocation(), diag::note_property_declare); 1373 } 1374 } 1375 } 1376 1377 bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, 1378 ObjCMethodDecl *GetterMethod, 1379 SourceLocation Loc) { 1380 if (!GetterMethod) 1381 return false; 1382 QualType GetterType = GetterMethod->getReturnType().getNonReferenceType(); 1383 QualType PropertyIvarType = property->getType().getNonReferenceType(); 1384 bool compat = Context.hasSameType(PropertyIvarType, GetterType); 1385 if (!compat) { 1386 if (isa<ObjCObjectPointerType>(PropertyIvarType) && 1387 isa<ObjCObjectPointerType>(GetterType)) 1388 compat = 1389 Context.canAssignObjCInterfaces( 1390 GetterType->getAs<ObjCObjectPointerType>(), 1391 PropertyIvarType->getAs<ObjCObjectPointerType>()); 1392 else if (CheckAssignmentConstraints(Loc, GetterType, PropertyIvarType) 1393 != Compatible) { 1394 Diag(Loc, diag::error_property_accessor_type) 1395 << property->getDeclName() << PropertyIvarType 1396 << GetterMethod->getSelector() << GetterType; 1397 Diag(GetterMethod->getLocation(), diag::note_declared_at); 1398 return true; 1399 } else { 1400 compat = true; 1401 QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType(); 1402 QualType rhsType =Context.getCanonicalType(GetterType).getUnqualifiedType(); 1403 if (lhsType != rhsType && lhsType->isArithmeticType()) 1404 compat = false; 1405 } 1406 } 1407 1408 if (!compat) { 1409 Diag(Loc, diag::warn_accessor_property_type_mismatch) 1410 << property->getDeclName() 1411 << GetterMethod->getSelector(); 1412 Diag(GetterMethod->getLocation(), diag::note_declared_at); 1413 return true; 1414 } 1415 1416 return false; 1417 } 1418 1419 /// CollectImmediateProperties - This routine collects all properties in 1420 /// the class and its conforming protocols; but not those in its super class. 1421 static void CollectImmediateProperties(ObjCContainerDecl *CDecl, 1422 ObjCContainerDecl::PropertyMap &PropMap, 1423 ObjCContainerDecl::PropertyMap &SuperPropMap, 1424 bool IncludeProtocols = true) { 1425 1426 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1427 for (auto *Prop : IDecl->properties()) 1428 PropMap[Prop->getIdentifier()] = Prop; 1429 if (IncludeProtocols) { 1430 // Scan through class's protocols. 1431 for (auto *PI : IDecl->all_referenced_protocols()) 1432 CollectImmediateProperties(PI, PropMap, SuperPropMap); 1433 } 1434 } 1435 if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) { 1436 if (!CATDecl->IsClassExtension()) 1437 for (auto *Prop : CATDecl->properties()) 1438 PropMap[Prop->getIdentifier()] = Prop; 1439 if (IncludeProtocols) { 1440 // Scan through class's protocols. 1441 for (auto *PI : CATDecl->protocols()) 1442 CollectImmediateProperties(PI, PropMap, SuperPropMap); 1443 } 1444 } 1445 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 1446 for (auto *Prop : PDecl->properties()) { 1447 ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()]; 1448 // Exclude property for protocols which conform to class's super-class, 1449 // as super-class has to implement the property. 1450 if (!PropertyFromSuper || 1451 PropertyFromSuper->getIdentifier() != Prop->getIdentifier()) { 1452 ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()]; 1453 if (!PropEntry) 1454 PropEntry = Prop; 1455 } 1456 } 1457 // scan through protocol's protocols. 1458 for (auto *PI : PDecl->protocols()) 1459 CollectImmediateProperties(PI, PropMap, SuperPropMap); 1460 } 1461 } 1462 1463 /// CollectSuperClassPropertyImplementations - This routine collects list of 1464 /// properties to be implemented in super class(s) and also coming from their 1465 /// conforming protocols. 1466 static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, 1467 ObjCInterfaceDecl::PropertyMap &PropMap) { 1468 if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) { 1469 ObjCInterfaceDecl::PropertyDeclOrder PO; 1470 while (SDecl) { 1471 SDecl->collectPropertiesToImplement(PropMap, PO); 1472 SDecl = SDecl->getSuperClass(); 1473 } 1474 } 1475 } 1476 1477 /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is 1478 /// an ivar synthesized for 'Method' and 'Method' is a property accessor 1479 /// declared in class 'IFace'. 1480 bool 1481 Sema::IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, 1482 ObjCMethodDecl *Method, ObjCIvarDecl *IV) { 1483 if (!IV->getSynthesize()) 1484 return false; 1485 ObjCMethodDecl *IMD = IFace->lookupMethod(Method->getSelector(), 1486 Method->isInstanceMethod()); 1487 if (!IMD || !IMD->isPropertyAccessor()) 1488 return false; 1489 1490 // look up a property declaration whose one of its accessors is implemented 1491 // by this method. 1492 for (const auto *Property : IFace->properties()) { 1493 if ((Property->getGetterName() == IMD->getSelector() || 1494 Property->getSetterName() == IMD->getSelector()) && 1495 (Property->getPropertyIvarDecl() == IV)) 1496 return true; 1497 } 1498 return false; 1499 } 1500 1501 static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl, 1502 ObjCPropertyDecl *Prop) { 1503 bool SuperClassImplementsGetter = false; 1504 bool SuperClassImplementsSetter = false; 1505 if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly) 1506 SuperClassImplementsSetter = true; 1507 1508 while (IDecl->getSuperClass()) { 1509 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); 1510 if (!SuperClassImplementsGetter && SDecl->getInstanceMethod(Prop->getGetterName())) 1511 SuperClassImplementsGetter = true; 1512 1513 if (!SuperClassImplementsSetter && SDecl->getInstanceMethod(Prop->getSetterName())) 1514 SuperClassImplementsSetter = true; 1515 if (SuperClassImplementsGetter && SuperClassImplementsSetter) 1516 return true; 1517 IDecl = IDecl->getSuperClass(); 1518 } 1519 return false; 1520 } 1521 1522 /// \brief Default synthesizes all properties which must be synthesized 1523 /// in class's \@implementation. 1524 void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl, 1525 ObjCInterfaceDecl *IDecl) { 1526 1527 ObjCInterfaceDecl::PropertyMap PropMap; 1528 ObjCInterfaceDecl::PropertyDeclOrder PropertyOrder; 1529 IDecl->collectPropertiesToImplement(PropMap, PropertyOrder); 1530 if (PropMap.empty()) 1531 return; 1532 ObjCInterfaceDecl::PropertyMap SuperPropMap; 1533 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 1534 1535 for (unsigned i = 0, e = PropertyOrder.size(); i != e; i++) { 1536 ObjCPropertyDecl *Prop = PropertyOrder[i]; 1537 // Is there a matching property synthesize/dynamic? 1538 if (Prop->isInvalidDecl() || 1539 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1540 continue; 1541 // Property may have been synthesized by user. 1542 if (IMPDecl->FindPropertyImplDecl(Prop->getIdentifier())) 1543 continue; 1544 if (IMPDecl->getInstanceMethod(Prop->getGetterName())) { 1545 if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly) 1546 continue; 1547 if (IMPDecl->getInstanceMethod(Prop->getSetterName())) 1548 continue; 1549 } 1550 // If property to be implemented in the super class, ignore. 1551 if (SuperPropMap[Prop->getIdentifier()]) { 1552 ObjCPropertyDecl *PropInSuperClass = SuperPropMap[Prop->getIdentifier()]; 1553 if ((Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite) && 1554 (PropInSuperClass->getPropertyAttributes() & 1555 ObjCPropertyDecl::OBJC_PR_readonly) && 1556 !IMPDecl->getInstanceMethod(Prop->getSetterName()) && 1557 !IDecl->HasUserDeclaredSetterMethod(Prop)) { 1558 Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property) 1559 << Prop->getIdentifier(); 1560 Diag(PropInSuperClass->getLocation(), diag::note_property_declare); 1561 } 1562 continue; 1563 } 1564 if (ObjCPropertyImplDecl *PID = 1565 IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) { 1566 if (PID->getPropertyDecl() != Prop) { 1567 Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property) 1568 << Prop->getIdentifier(); 1569 if (!PID->getLocation().isInvalid()) 1570 Diag(PID->getLocation(), diag::note_property_synthesize); 1571 } 1572 continue; 1573 } 1574 if (ObjCProtocolDecl *Proto = 1575 dyn_cast<ObjCProtocolDecl>(Prop->getDeclContext())) { 1576 // We won't auto-synthesize properties declared in protocols. 1577 // Suppress the warning if class's superclass implements property's 1578 // getter and implements property's setter (if readwrite property). 1579 if (!SuperClassImplementsProperty(IDecl, Prop)) { 1580 Diag(IMPDecl->getLocation(), 1581 diag::warn_auto_synthesizing_protocol_property) 1582 << Prop << Proto; 1583 Diag(Prop->getLocation(), diag::note_property_declare); 1584 } 1585 continue; 1586 } 1587 1588 // We use invalid SourceLocations for the synthesized ivars since they 1589 // aren't really synthesized at a particular location; they just exist. 1590 // Saying that they are located at the @implementation isn't really going 1591 // to help users. 1592 ObjCPropertyImplDecl *PIDecl = dyn_cast_or_null<ObjCPropertyImplDecl>( 1593 ActOnPropertyImplDecl(S, SourceLocation(), SourceLocation(), 1594 true, 1595 /* property = */ Prop->getIdentifier(), 1596 /* ivar = */ Prop->getDefaultSynthIvarName(Context), 1597 Prop->getLocation())); 1598 if (PIDecl) { 1599 Diag(Prop->getLocation(), diag::warn_missing_explicit_synthesis); 1600 Diag(IMPDecl->getLocation(), diag::note_while_in_implementation); 1601 } 1602 } 1603 } 1604 1605 void Sema::DefaultSynthesizeProperties(Scope *S, Decl *D) { 1606 if (!LangOpts.ObjCDefaultSynthProperties || LangOpts.ObjCRuntime.isFragile()) 1607 return; 1608 ObjCImplementationDecl *IC=dyn_cast_or_null<ObjCImplementationDecl>(D); 1609 if (!IC) 1610 return; 1611 if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) 1612 if (!IDecl->isObjCRequiresPropertyDefs()) 1613 DefaultSynthesizeProperties(S, IC, IDecl); 1614 } 1615 1616 static void DiagnoseUnimplementedAccessor(Sema &S, 1617 ObjCInterfaceDecl *PrimaryClass, 1618 Selector Method, 1619 ObjCImplDecl* IMPDecl, 1620 ObjCContainerDecl *CDecl, 1621 ObjCCategoryDecl *C, 1622 ObjCPropertyDecl *Prop, 1623 Sema::SelectorSet &SMap) { 1624 // When reporting on missing property setter/getter implementation in 1625 // categories, do not report when they are declared in primary class, 1626 // class's protocol, or one of it super classes. This is because, 1627 // the class is going to implement them. 1628 if (!SMap.count(Method) && 1629 (PrimaryClass == nullptr || 1630 !PrimaryClass->lookupPropertyAccessor(Method, C))) { 1631 S.Diag(IMPDecl->getLocation(), 1632 isa<ObjCCategoryDecl>(CDecl) ? 1633 diag::warn_setter_getter_impl_required_in_category : 1634 diag::warn_setter_getter_impl_required) 1635 << Prop->getDeclName() << Method; 1636 S.Diag(Prop->getLocation(), 1637 diag::note_property_declare); 1638 if (S.LangOpts.ObjCDefaultSynthProperties && 1639 S.LangOpts.ObjCRuntime.isNonFragile()) 1640 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl)) 1641 if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs()) 1642 S.Diag(RID->getLocation(), diag::note_suppressed_class_declare); 1643 } 1644 } 1645 1646 void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, 1647 ObjCContainerDecl *CDecl, 1648 bool SynthesizeProperties) { 1649 ObjCContainerDecl::PropertyMap PropMap; 1650 ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl); 1651 1652 if (!SynthesizeProperties) { 1653 ObjCContainerDecl::PropertyMap NoNeedToImplPropMap; 1654 // Gather properties which need not be implemented in this class 1655 // or category. 1656 if (!IDecl) 1657 if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) { 1658 // For categories, no need to implement properties declared in 1659 // its primary class (and its super classes) if property is 1660 // declared in one of those containers. 1661 if ((IDecl = C->getClassInterface())) { 1662 ObjCInterfaceDecl::PropertyDeclOrder PO; 1663 IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO); 1664 } 1665 } 1666 if (IDecl) 1667 CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap); 1668 1669 CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap); 1670 } 1671 1672 // Scan the @interface to see if any of the protocols it adopts 1673 // require an explicit implementation, via attribute 1674 // 'objc_protocol_requires_explicit_implementation'. 1675 if (IDecl) { 1676 std::unique_ptr<ObjCContainerDecl::PropertyMap> LazyMap; 1677 1678 for (auto *PDecl : IDecl->all_referenced_protocols()) { 1679 if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) 1680 continue; 1681 // Lazily construct a set of all the properties in the @interface 1682 // of the class, without looking at the superclass. We cannot 1683 // use the call to CollectImmediateProperties() above as that 1684 // utilizes information from the super class's properties as well 1685 // as scans the adopted protocols. This work only triggers for protocols 1686 // with the attribute, which is very rare, and only occurs when 1687 // analyzing the @implementation. 1688 if (!LazyMap) { 1689 ObjCContainerDecl::PropertyMap NoNeedToImplPropMap; 1690 LazyMap.reset(new ObjCContainerDecl::PropertyMap()); 1691 CollectImmediateProperties(CDecl, *LazyMap, NoNeedToImplPropMap, 1692 /* IncludeProtocols */ false); 1693 } 1694 // Add the properties of 'PDecl' to the list of properties that 1695 // need to be implemented. 1696 for (auto *PropDecl : PDecl->properties()) { 1697 if ((*LazyMap)[PropDecl->getIdentifier()]) 1698 continue; 1699 PropMap[PropDecl->getIdentifier()] = PropDecl; 1700 } 1701 } 1702 } 1703 1704 if (PropMap.empty()) 1705 return; 1706 1707 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap; 1708 for (const auto *I : IMPDecl->property_impls()) 1709 PropImplMap.insert(I->getPropertyDecl()); 1710 1711 SelectorSet InsMap; 1712 // Collect property accessors implemented in current implementation. 1713 for (const auto *I : IMPDecl->instance_methods()) 1714 InsMap.insert(I->getSelector()); 1715 1716 ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl); 1717 ObjCInterfaceDecl *PrimaryClass = nullptr; 1718 if (C && !C->IsClassExtension()) 1719 if ((PrimaryClass = C->getClassInterface())) 1720 // Report unimplemented properties in the category as well. 1721 if (ObjCImplDecl *IMP = PrimaryClass->getImplementation()) { 1722 // When reporting on missing setter/getters, do not report when 1723 // setter/getter is implemented in category's primary class 1724 // implementation. 1725 for (const auto *I : IMP->instance_methods()) 1726 InsMap.insert(I->getSelector()); 1727 } 1728 1729 for (ObjCContainerDecl::PropertyMap::iterator 1730 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1731 ObjCPropertyDecl *Prop = P->second; 1732 // Is there a matching propery synthesize/dynamic? 1733 if (Prop->isInvalidDecl() || 1734 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 1735 PropImplMap.count(Prop) || 1736 Prop->getAvailability() == AR_Unavailable) 1737 continue; 1738 1739 // Diagnose unimplemented getters and setters. 1740 DiagnoseUnimplementedAccessor(*this, 1741 PrimaryClass, Prop->getGetterName(), IMPDecl, CDecl, C, Prop, InsMap); 1742 if (!Prop->isReadOnly()) 1743 DiagnoseUnimplementedAccessor(*this, 1744 PrimaryClass, Prop->getSetterName(), 1745 IMPDecl, CDecl, C, Prop, InsMap); 1746 } 1747 } 1748 1749 void 1750 Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, 1751 ObjCContainerDecl* IDecl) { 1752 // Rules apply in non-GC mode only 1753 if (getLangOpts().getGC() != LangOptions::NonGC) 1754 return; 1755 for (const auto *Property : IDecl->properties()) { 1756 ObjCMethodDecl *GetterMethod = nullptr; 1757 ObjCMethodDecl *SetterMethod = nullptr; 1758 bool LookedUpGetterSetter = false; 1759 1760 unsigned Attributes = Property->getPropertyAttributes(); 1761 unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten(); 1762 1763 if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic) && 1764 !(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_nonatomic)) { 1765 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1766 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1767 LookedUpGetterSetter = true; 1768 if (GetterMethod) { 1769 Diag(GetterMethod->getLocation(), 1770 diag::warn_default_atomic_custom_getter_setter) 1771 << Property->getIdentifier() << 0; 1772 Diag(Property->getLocation(), diag::note_property_declare); 1773 } 1774 if (SetterMethod) { 1775 Diag(SetterMethod->getLocation(), 1776 diag::warn_default_atomic_custom_getter_setter) 1777 << Property->getIdentifier() << 1; 1778 Diag(Property->getLocation(), diag::note_property_declare); 1779 } 1780 } 1781 1782 // We only care about readwrite atomic property. 1783 if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) || 1784 !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite)) 1785 continue; 1786 if (const ObjCPropertyImplDecl *PIDecl 1787 = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) { 1788 if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 1789 continue; 1790 if (!LookedUpGetterSetter) { 1791 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1792 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1793 } 1794 if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { 1795 SourceLocation MethodLoc = 1796 (GetterMethod ? GetterMethod->getLocation() 1797 : SetterMethod->getLocation()); 1798 Diag(MethodLoc, diag::warn_atomic_property_rule) 1799 << Property->getIdentifier() << (GetterMethod != nullptr) 1800 << (SetterMethod != nullptr); 1801 // fixit stuff. 1802 if (!AttributesAsWritten) { 1803 if (Property->getLParenLoc().isValid()) { 1804 // @property () ... case. 1805 SourceRange PropSourceRange(Property->getAtLoc(), 1806 Property->getLParenLoc()); 1807 Diag(Property->getLocation(), diag::note_atomic_property_fixup_suggest) << 1808 FixItHint::CreateReplacement(PropSourceRange, "@property (nonatomic"); 1809 } 1810 else { 1811 //@property id etc. 1812 SourceLocation endLoc = 1813 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); 1814 endLoc = endLoc.getLocWithOffset(-1); 1815 SourceRange PropSourceRange(Property->getAtLoc(), endLoc); 1816 Diag(Property->getLocation(), diag::note_atomic_property_fixup_suggest) << 1817 FixItHint::CreateReplacement(PropSourceRange, "@property (nonatomic) "); 1818 } 1819 } 1820 else if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic)) { 1821 // @property () ... case. 1822 SourceLocation endLoc = Property->getLParenLoc(); 1823 SourceRange PropSourceRange(Property->getAtLoc(), endLoc); 1824 Diag(Property->getLocation(), diag::note_atomic_property_fixup_suggest) << 1825 FixItHint::CreateReplacement(PropSourceRange, "@property (nonatomic, "); 1826 } 1827 else 1828 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest); 1829 Diag(Property->getLocation(), diag::note_property_declare); 1830 } 1831 } 1832 } 1833 } 1834 1835 void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) { 1836 if (getLangOpts().getGC() == LangOptions::GCOnly) 1837 return; 1838 1839 for (const auto *PID : D->property_impls()) { 1840 const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 1841 if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() && 1842 !D->getInstanceMethod(PD->getGetterName())) { 1843 ObjCMethodDecl *method = PD->getGetterMethodDecl(); 1844 if (!method) 1845 continue; 1846 ObjCMethodFamily family = method->getMethodFamily(); 1847 if (family == OMF_alloc || family == OMF_copy || 1848 family == OMF_mutableCopy || family == OMF_new) { 1849 if (getLangOpts().ObjCAutoRefCount) 1850 Diag(PD->getLocation(), diag::err_cocoa_naming_owned_rule); 1851 else 1852 Diag(PD->getLocation(), diag::warn_cocoa_naming_owned_rule); 1853 } 1854 } 1855 } 1856 } 1857 1858 void Sema::DiagnoseMissingDesignatedInitOverrides( 1859 const ObjCImplementationDecl *ImplD, 1860 const ObjCInterfaceDecl *IFD) { 1861 assert(IFD->hasDesignatedInitializers()); 1862 const ObjCInterfaceDecl *SuperD = IFD->getSuperClass(); 1863 if (!SuperD) 1864 return; 1865 1866 SelectorSet InitSelSet; 1867 for (const auto *I : ImplD->instance_methods()) 1868 if (I->getMethodFamily() == OMF_init) 1869 InitSelSet.insert(I->getSelector()); 1870 1871 SmallVector<const ObjCMethodDecl *, 8> DesignatedInits; 1872 SuperD->getDesignatedInitializers(DesignatedInits); 1873 for (SmallVector<const ObjCMethodDecl *, 8>::iterator 1874 I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) { 1875 const ObjCMethodDecl *MD = *I; 1876 if (!InitSelSet.count(MD->getSelector())) { 1877 Diag(ImplD->getLocation(), 1878 diag::warn_objc_implementation_missing_designated_init_override) 1879 << MD->getSelector(); 1880 Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here); 1881 } 1882 } 1883 } 1884 1885 /// AddPropertyAttrs - Propagates attributes from a property to the 1886 /// implicitly-declared getter or setter for that property. 1887 static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, 1888 ObjCPropertyDecl *Property) { 1889 // Should we just clone all attributes over? 1890 for (const auto *A : Property->attrs()) { 1891 if (isa<DeprecatedAttr>(A) || 1892 isa<UnavailableAttr>(A) || 1893 isa<AvailabilityAttr>(A)) 1894 PropertyMethod->addAttr(A->clone(S.Context)); 1895 } 1896 } 1897 1898 /// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods 1899 /// have the property type and issue diagnostics if they don't. 1900 /// Also synthesize a getter/setter method if none exist (and update the 1901 /// appropriate lookup tables. FIXME: Should reconsider if adding synthesized 1902 /// methods is the "right" thing to do. 1903 void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, 1904 ObjCContainerDecl *CD, 1905 ObjCPropertyDecl *redeclaredProperty, 1906 ObjCContainerDecl *lexicalDC) { 1907 1908 ObjCMethodDecl *GetterMethod, *SetterMethod; 1909 1910 if (CD->isInvalidDecl()) 1911 return; 1912 1913 GetterMethod = CD->getInstanceMethod(property->getGetterName()); 1914 SetterMethod = CD->getInstanceMethod(property->getSetterName()); 1915 DiagnosePropertyAccessorMismatch(property, GetterMethod, 1916 property->getLocation()); 1917 1918 if (SetterMethod) { 1919 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1920 property->getPropertyAttributes(); 1921 if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) && 1922 Context.getCanonicalType(SetterMethod->getReturnType()) != 1923 Context.VoidTy) 1924 Diag(SetterMethod->getLocation(), diag::err_setter_type_void); 1925 if (SetterMethod->param_size() != 1 || 1926 !Context.hasSameUnqualifiedType( 1927 (*SetterMethod->param_begin())->getType().getNonReferenceType(), 1928 property->getType().getNonReferenceType())) { 1929 Diag(property->getLocation(), 1930 diag::warn_accessor_property_type_mismatch) 1931 << property->getDeclName() 1932 << SetterMethod->getSelector(); 1933 Diag(SetterMethod->getLocation(), diag::note_declared_at); 1934 } 1935 } 1936 1937 // Synthesize getter/setter methods if none exist. 1938 // Find the default getter and if one not found, add one. 1939 // FIXME: The synthesized property we set here is misleading. We almost always 1940 // synthesize these methods unless the user explicitly provided prototypes 1941 // (which is odd, but allowed). Sema should be typechecking that the 1942 // declarations jive in that situation (which it is not currently). 1943 if (!GetterMethod) { 1944 // No instance method of same name as property getter name was found. 1945 // Declare a getter method and add it to the list of methods 1946 // for this class. 1947 SourceLocation Loc = redeclaredProperty ? 1948 redeclaredProperty->getLocation() : 1949 property->getLocation(); 1950 1951 GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc, 1952 property->getGetterName(), 1953 property->getType(), nullptr, CD, 1954 /*isInstance=*/true, /*isVariadic=*/false, 1955 /*isPropertyAccessor=*/true, 1956 /*isImplicitlyDeclared=*/true, /*isDefined=*/false, 1957 (property->getPropertyImplementation() == 1958 ObjCPropertyDecl::Optional) ? 1959 ObjCMethodDecl::Optional : 1960 ObjCMethodDecl::Required); 1961 CD->addDecl(GetterMethod); 1962 1963 AddPropertyAttrs(*this, GetterMethod, property); 1964 1965 // FIXME: Eventually this shouldn't be needed, as the lexical context 1966 // and the real context should be the same. 1967 if (lexicalDC) 1968 GetterMethod->setLexicalDeclContext(lexicalDC); 1969 if (property->hasAttr<NSReturnsNotRetainedAttr>()) 1970 GetterMethod->addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context, 1971 Loc)); 1972 1973 if (property->hasAttr<ObjCReturnsInnerPointerAttr>()) 1974 GetterMethod->addAttr( 1975 ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc)); 1976 1977 if (const SectionAttr *SA = property->getAttr<SectionAttr>()) 1978 GetterMethod->addAttr( 1979 SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section, 1980 SA->getName(), Loc)); 1981 1982 if (getLangOpts().ObjCAutoRefCount) 1983 CheckARCMethodDecl(GetterMethod); 1984 } else 1985 // A user declared getter will be synthesize when @synthesize of 1986 // the property with the same name is seen in the @implementation 1987 GetterMethod->setPropertyAccessor(true); 1988 property->setGetterMethodDecl(GetterMethod); 1989 1990 // Skip setter if property is read-only. 1991 if (!property->isReadOnly()) { 1992 // Find the default setter and if one not found, add one. 1993 if (!SetterMethod) { 1994 // No instance method of same name as property setter name was found. 1995 // Declare a setter method and add it to the list of methods 1996 // for this class. 1997 SourceLocation Loc = redeclaredProperty ? 1998 redeclaredProperty->getLocation() : 1999 property->getLocation(); 2000 2001 SetterMethod = 2002 ObjCMethodDecl::Create(Context, Loc, Loc, 2003 property->getSetterName(), Context.VoidTy, 2004 nullptr, CD, /*isInstance=*/true, 2005 /*isVariadic=*/false, 2006 /*isPropertyAccessor=*/true, 2007 /*isImplicitlyDeclared=*/true, 2008 /*isDefined=*/false, 2009 (property->getPropertyImplementation() == 2010 ObjCPropertyDecl::Optional) ? 2011 ObjCMethodDecl::Optional : 2012 ObjCMethodDecl::Required); 2013 2014 // Invent the arguments for the setter. We don't bother making a 2015 // nice name for the argument. 2016 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, 2017 Loc, Loc, 2018 property->getIdentifier(), 2019 property->getType().getUnqualifiedType(), 2020 /*TInfo=*/nullptr, 2021 SC_None, 2022 nullptr); 2023 SetterMethod->setMethodParams(Context, Argument, None); 2024 2025 AddPropertyAttrs(*this, SetterMethod, property); 2026 2027 CD->addDecl(SetterMethod); 2028 // FIXME: Eventually this shouldn't be needed, as the lexical context 2029 // and the real context should be the same. 2030 if (lexicalDC) 2031 SetterMethod->setLexicalDeclContext(lexicalDC); 2032 if (const SectionAttr *SA = property->getAttr<SectionAttr>()) 2033 SetterMethod->addAttr( 2034 SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section, 2035 SA->getName(), Loc)); 2036 // It's possible for the user to have set a very odd custom 2037 // setter selector that causes it to have a method family. 2038 if (getLangOpts().ObjCAutoRefCount) 2039 CheckARCMethodDecl(SetterMethod); 2040 } else 2041 // A user declared setter will be synthesize when @synthesize of 2042 // the property with the same name is seen in the @implementation 2043 SetterMethod->setPropertyAccessor(true); 2044 property->setSetterMethodDecl(SetterMethod); 2045 } 2046 // Add any synthesized methods to the global pool. This allows us to 2047 // handle the following, which is supported by GCC (and part of the design). 2048 // 2049 // @interface Foo 2050 // @property double bar; 2051 // @end 2052 // 2053 // void thisIsUnfortunate() { 2054 // id foo; 2055 // double bar = [foo bar]; 2056 // } 2057 // 2058 if (GetterMethod) 2059 AddInstanceMethodToGlobalPool(GetterMethod); 2060 if (SetterMethod) 2061 AddInstanceMethodToGlobalPool(SetterMethod); 2062 2063 ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(CD); 2064 if (!CurrentClass) { 2065 if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CD)) 2066 CurrentClass = Cat->getClassInterface(); 2067 else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(CD)) 2068 CurrentClass = Impl->getClassInterface(); 2069 } 2070 if (GetterMethod) 2071 CheckObjCMethodOverrides(GetterMethod, CurrentClass, Sema::RTC_Unknown); 2072 if (SetterMethod) 2073 CheckObjCMethodOverrides(SetterMethod, CurrentClass, Sema::RTC_Unknown); 2074 } 2075 2076 void Sema::CheckObjCPropertyAttributes(Decl *PDecl, 2077 SourceLocation Loc, 2078 unsigned &Attributes, 2079 bool propertyInPrimaryClass) { 2080 // FIXME: Improve the reported location. 2081 if (!PDecl || PDecl->isInvalidDecl()) 2082 return; 2083 2084 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 2085 (Attributes & ObjCDeclSpec::DQ_PR_readwrite)) 2086 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2087 << "readonly" << "readwrite"; 2088 2089 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 2090 QualType PropertyTy = PropertyDecl->getType(); 2091 unsigned PropertyOwnership = getOwnershipRule(Attributes); 2092 2093 // 'readonly' property with no obvious lifetime. 2094 // its life time will be determined by its backing ivar. 2095 if (getLangOpts().ObjCAutoRefCount && 2096 Attributes & ObjCDeclSpec::DQ_PR_readonly && 2097 PropertyTy->isObjCRetainableType() && 2098 !PropertyOwnership) 2099 return; 2100 2101 // Check for copy or retain on non-object types. 2102 if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 2103 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) && 2104 !PropertyTy->isObjCRetainableType() && 2105 !PropertyDecl->hasAttr<ObjCNSObjectAttr>()) { 2106 Diag(Loc, diag::err_objc_property_requires_object) 2107 << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" : 2108 Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)"); 2109 Attributes &= ~(ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 2110 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong); 2111 PropertyDecl->setInvalidDecl(); 2112 } 2113 2114 // Check for more than one of { assign, copy, retain }. 2115 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 2116 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 2117 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2118 << "assign" << "copy"; 2119 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 2120 } 2121 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 2122 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2123 << "assign" << "retain"; 2124 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 2125 } 2126 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 2127 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2128 << "assign" << "strong"; 2129 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 2130 } 2131 if (getLangOpts().ObjCAutoRefCount && 2132 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 2133 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2134 << "assign" << "weak"; 2135 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 2136 } 2137 if (PropertyDecl->hasAttr<IBOutletCollectionAttr>()) 2138 Diag(Loc, diag::warn_iboutletcollection_property_assign); 2139 } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) { 2140 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 2141 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2142 << "unsafe_unretained" << "copy"; 2143 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 2144 } 2145 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 2146 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2147 << "unsafe_unretained" << "retain"; 2148 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 2149 } 2150 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 2151 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2152 << "unsafe_unretained" << "strong"; 2153 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 2154 } 2155 if (getLangOpts().ObjCAutoRefCount && 2156 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 2157 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2158 << "unsafe_unretained" << "weak"; 2159 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 2160 } 2161 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 2162 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 2163 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2164 << "copy" << "retain"; 2165 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 2166 } 2167 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 2168 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2169 << "copy" << "strong"; 2170 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 2171 } 2172 if (Attributes & ObjCDeclSpec::DQ_PR_weak) { 2173 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2174 << "copy" << "weak"; 2175 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 2176 } 2177 } 2178 else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) && 2179 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 2180 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2181 << "retain" << "weak"; 2182 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 2183 } 2184 else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) && 2185 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 2186 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2187 << "strong" << "weak"; 2188 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 2189 } 2190 2191 if ((Attributes & ObjCDeclSpec::DQ_PR_atomic) && 2192 (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)) { 2193 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2194 << "atomic" << "nonatomic"; 2195 Attributes &= ~ObjCDeclSpec::DQ_PR_atomic; 2196 } 2197 2198 // Warn if user supplied no assignment attribute, property is 2199 // readwrite, and this is an object type. 2200 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | 2201 ObjCDeclSpec::DQ_PR_unsafe_unretained | 2202 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong | 2203 ObjCDeclSpec::DQ_PR_weak)) && 2204 PropertyTy->isObjCObjectPointerType()) { 2205 if (getLangOpts().ObjCAutoRefCount) 2206 // With arc, @property definitions should default to (strong) when 2207 // not specified; including when property is 'readonly'. 2208 PropertyDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 2209 else if (!(Attributes & ObjCDeclSpec::DQ_PR_readonly)) { 2210 bool isAnyClassTy = 2211 (PropertyTy->isObjCClassType() || 2212 PropertyTy->isObjCQualifiedClassType()); 2213 // In non-gc, non-arc mode, 'Class' is treated as a 'void *' no need to 2214 // issue any warning. 2215 if (isAnyClassTy && getLangOpts().getGC() == LangOptions::NonGC) 2216 ; 2217 else if (propertyInPrimaryClass) { 2218 // Don't issue warning on property with no life time in class 2219 // extension as it is inherited from property in primary class. 2220 // Skip this warning in gc-only mode. 2221 if (getLangOpts().getGC() != LangOptions::GCOnly) 2222 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 2223 2224 // If non-gc code warn that this is likely inappropriate. 2225 if (getLangOpts().getGC() == LangOptions::NonGC) 2226 Diag(Loc, diag::warn_objc_property_default_assign_on_object); 2227 } 2228 } 2229 2230 // FIXME: Implement warning dependent on NSCopying being 2231 // implemented. See also: 2232 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496> 2233 // (please trim this list while you are at it). 2234 } 2235 2236 if (!(Attributes & ObjCDeclSpec::DQ_PR_copy) 2237 &&!(Attributes & ObjCDeclSpec::DQ_PR_readonly) 2238 && getLangOpts().getGC() == LangOptions::GCOnly 2239 && PropertyTy->isBlockPointerType()) 2240 Diag(Loc, diag::warn_objc_property_copy_missing_on_block); 2241 else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) && 2242 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 2243 !(Attributes & ObjCDeclSpec::DQ_PR_strong) && 2244 PropertyTy->isBlockPointerType()) 2245 Diag(Loc, diag::warn_objc_property_retain_of_block); 2246 2247 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 2248 (Attributes & ObjCDeclSpec::DQ_PR_setter)) 2249 Diag(Loc, diag::warn_objc_readonly_property_has_setter); 2250 2251 } 2252