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