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