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