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