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 type->getObjCARCImplicitLifetime(); 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 switch (propertyLifetime) { 547 case Qualifiers::OCL_Strong: 548 S.Diag(propertyImplLoc, diag::err_arc_strong_property_ownership) 549 << property->getDeclName() 550 << ivar->getDeclName() 551 << ivarLifetime; 552 break; 553 554 case Qualifiers::OCL_Weak: 555 S.Diag(propertyImplLoc, diag::error_weak_property) 556 << property->getDeclName() 557 << ivar->getDeclName(); 558 break; 559 560 case Qualifiers::OCL_ExplicitNone: 561 S.Diag(propertyImplLoc, diag::err_arc_assign_property_ownership) 562 << property->getDeclName() 563 << ivar->getDeclName() 564 << ((property->getPropertyAttributesAsWritten() 565 & ObjCPropertyDecl::OBJC_PR_assign) != 0); 566 break; 567 568 case Qualifiers::OCL_Autoreleasing: 569 llvm_unreachable("properties cannot be autoreleasing"); 570 571 case Qualifiers::OCL_None: 572 // Any other property should be ignored. 573 return; 574 } 575 576 S.Diag(property->getLocation(), diag::note_property_declare); 577 } 578 579 /// setImpliedPropertyAttributeForReadOnlyProperty - 580 /// This routine evaludates life-time attributes for a 'readonly' 581 /// property with no known lifetime of its own, using backing 582 /// 'ivar's attribute, if any. If no backing 'ivar', property's 583 /// life-time is assumed 'strong'. 584 static void setImpliedPropertyAttributeForReadOnlyProperty( 585 ObjCPropertyDecl *property, ObjCIvarDecl *ivar) { 586 Qualifiers::ObjCLifetime propertyLifetime = 587 getImpliedARCOwnership(property->getPropertyAttributes(), 588 property->getType()); 589 if (propertyLifetime != Qualifiers::OCL_None) 590 return; 591 592 if (!ivar) { 593 // if no backing ivar, make property 'strong'. 594 property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 595 return; 596 } 597 // property assumes owenership of backing ivar. 598 QualType ivarType = ivar->getType(); 599 Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime(); 600 if (ivarLifetime == Qualifiers::OCL_Strong) 601 property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 602 else if (ivarLifetime == Qualifiers::OCL_Weak) 603 property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak); 604 return; 605 } 606 607 /// DiagnoseClassAndClassExtPropertyMismatch - diagnose inconsistant property 608 /// attribute declared in primary class and attributes overridden in any of its 609 /// class extensions. 610 static void 611 DiagnoseClassAndClassExtPropertyMismatch(Sema &S, ObjCInterfaceDecl *ClassDecl, 612 ObjCPropertyDecl *property) { 613 unsigned Attributes = property->getPropertyAttributesAsWritten(); 614 bool warn = (Attributes & ObjCDeclSpec::DQ_PR_readonly); 615 for (const ObjCCategoryDecl *CDecl = ClassDecl->getFirstClassExtension(); 616 CDecl; CDecl = CDecl->getNextClassExtension()) { 617 ObjCPropertyDecl *ClassExtProperty = 0; 618 for (ObjCContainerDecl::prop_iterator P = CDecl->prop_begin(), 619 E = CDecl->prop_end(); P != E; ++P) { 620 if ((*P)->getIdentifier() == property->getIdentifier()) { 621 ClassExtProperty = *P; 622 break; 623 } 624 } 625 if (ClassExtProperty) { 626 warn = false; 627 unsigned classExtPropertyAttr = 628 ClassExtProperty->getPropertyAttributesAsWritten(); 629 // We are issuing the warning that we postponed because class extensions 630 // can override readonly->readwrite and 'setter' attributes originally 631 // placed on class's property declaration now make sense in the overridden 632 // property. 633 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) { 634 if (!classExtPropertyAttr || 635 (classExtPropertyAttr & ObjCDeclSpec::DQ_PR_readwrite)) 636 continue; 637 warn = true; 638 break; 639 } 640 } 641 } 642 if (warn) { 643 unsigned setterAttrs = (ObjCDeclSpec::DQ_PR_assign | 644 ObjCDeclSpec::DQ_PR_unsafe_unretained | 645 ObjCDeclSpec::DQ_PR_copy | 646 ObjCDeclSpec::DQ_PR_retain | 647 ObjCDeclSpec::DQ_PR_strong); 648 if (Attributes & setterAttrs) { 649 const char * which = 650 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 651 "assign" : 652 (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) ? 653 "unsafe_unretained" : 654 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 655 "copy" : 656 (Attributes & ObjCDeclSpec::DQ_PR_retain) ? 657 "retain" : "strong"; 658 659 S.Diag(property->getLocation(), 660 diag::warn_objc_property_attr_mutually_exclusive) 661 << "readonly" << which; 662 } 663 } 664 665 666 } 667 668 /// ActOnPropertyImplDecl - This routine performs semantic checks and 669 /// builds the AST node for a property implementation declaration; declared 670 /// as \@synthesize or \@dynamic. 671 /// 672 Decl *Sema::ActOnPropertyImplDecl(Scope *S, 673 SourceLocation AtLoc, 674 SourceLocation PropertyLoc, 675 bool Synthesize, 676 IdentifierInfo *PropertyId, 677 IdentifierInfo *PropertyIvar, 678 SourceLocation PropertyIvarLoc) { 679 ObjCContainerDecl *ClassImpDecl = 680 dyn_cast<ObjCContainerDecl>(CurContext); 681 // Make sure we have a context for the property implementation declaration. 682 if (!ClassImpDecl) { 683 Diag(AtLoc, diag::error_missing_property_context); 684 return 0; 685 } 686 if (PropertyIvarLoc.isInvalid()) 687 PropertyIvarLoc = PropertyLoc; 688 SourceLocation PropertyDiagLoc = PropertyLoc; 689 if (PropertyDiagLoc.isInvalid()) 690 PropertyDiagLoc = ClassImpDecl->getLocStart(); 691 ObjCPropertyDecl *property = 0; 692 ObjCInterfaceDecl* IDecl = 0; 693 // Find the class or category class where this property must have 694 // a declaration. 695 ObjCImplementationDecl *IC = 0; 696 ObjCCategoryImplDecl* CatImplClass = 0; 697 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) { 698 IDecl = IC->getClassInterface(); 699 // We always synthesize an interface for an implementation 700 // without an interface decl. So, IDecl is always non-zero. 701 assert(IDecl && 702 "ActOnPropertyImplDecl - @implementation without @interface"); 703 704 // Look for this property declaration in the @implementation's @interface 705 property = IDecl->FindPropertyDeclaration(PropertyId); 706 if (!property) { 707 Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName(); 708 return 0; 709 } 710 unsigned PIkind = property->getPropertyAttributesAsWritten(); 711 if ((PIkind & (ObjCPropertyDecl::OBJC_PR_atomic | 712 ObjCPropertyDecl::OBJC_PR_nonatomic) ) == 0) { 713 if (AtLoc.isValid()) 714 Diag(AtLoc, diag::warn_implicit_atomic_property); 715 else 716 Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property); 717 Diag(property->getLocation(), diag::note_property_declare); 718 } 719 720 if (const ObjCCategoryDecl *CD = 721 dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) { 722 if (!CD->IsClassExtension()) { 723 Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName(); 724 Diag(property->getLocation(), diag::note_property_declare); 725 return 0; 726 } 727 } 728 729 if (Synthesize&& 730 (PIkind & ObjCPropertyDecl::OBJC_PR_readonly) && 731 property->hasAttr<IBOutletAttr>() && 732 !AtLoc.isValid()) { 733 unsigned rwPIKind = (PIkind | ObjCPropertyDecl::OBJC_PR_readwrite); 734 rwPIKind &= (~ObjCPropertyDecl::OBJC_PR_readonly); 735 Diag(IC->getLocation(), diag::warn_auto_readonly_iboutlet_property); 736 Diag(property->getLocation(), diag::note_property_declare); 737 SourceLocation readonlyLoc; 738 if (LocPropertyAttribute(Context, "readonly", 739 property->getLParenLoc(), readonlyLoc)) { 740 SourceLocation endLoc = 741 readonlyLoc.getLocWithOffset(strlen("readonly")-1); 742 SourceRange ReadonlySourceRange(readonlyLoc, endLoc); 743 Diag(property->getLocation(), 744 diag::note_auto_readonly_iboutlet_fixup_suggest) << 745 FixItHint::CreateReplacement(ReadonlySourceRange, "readwrite"); 746 } 747 } 748 749 DiagnoseClassAndClassExtPropertyMismatch(*this, IDecl, property); 750 751 } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) { 752 if (Synthesize) { 753 Diag(AtLoc, diag::error_synthesize_category_decl); 754 return 0; 755 } 756 IDecl = CatImplClass->getClassInterface(); 757 if (!IDecl) { 758 Diag(AtLoc, diag::error_missing_property_interface); 759 return 0; 760 } 761 ObjCCategoryDecl *Category = 762 IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier()); 763 764 // If category for this implementation not found, it is an error which 765 // has already been reported eralier. 766 if (!Category) 767 return 0; 768 // Look for this property declaration in @implementation's category 769 property = Category->FindPropertyDeclaration(PropertyId); 770 if (!property) { 771 Diag(PropertyLoc, diag::error_bad_category_property_decl) 772 << Category->getDeclName(); 773 return 0; 774 } 775 } else { 776 Diag(AtLoc, diag::error_bad_property_context); 777 return 0; 778 } 779 ObjCIvarDecl *Ivar = 0; 780 bool CompleteTypeErr = false; 781 bool compat = true; 782 // Check that we have a valid, previously declared ivar for @synthesize 783 if (Synthesize) { 784 // @synthesize 785 if (!PropertyIvar) 786 PropertyIvar = PropertyId; 787 // Check that this is a previously declared 'ivar' in 'IDecl' interface 788 ObjCInterfaceDecl *ClassDeclared; 789 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared); 790 QualType PropType = property->getType(); 791 QualType PropertyIvarType = PropType.getNonReferenceType(); 792 793 if (RequireCompleteType(PropertyDiagLoc, PropertyIvarType, 794 diag::err_incomplete_synthesized_property, 795 property->getDeclName())) { 796 Diag(property->getLocation(), diag::note_property_declare); 797 CompleteTypeErr = true; 798 } 799 800 if (getLangOpts().ObjCAutoRefCount && 801 (property->getPropertyAttributesAsWritten() & 802 ObjCPropertyDecl::OBJC_PR_readonly) && 803 PropertyIvarType->isObjCRetainableType()) { 804 setImpliedPropertyAttributeForReadOnlyProperty(property, Ivar); 805 } 806 807 ObjCPropertyDecl::PropertyAttributeKind kind 808 = property->getPropertyAttributes(); 809 810 // Add GC __weak to the ivar type if the property is weak. 811 if ((kind & ObjCPropertyDecl::OBJC_PR_weak) && 812 getLangOpts().getGC() != LangOptions::NonGC) { 813 assert(!getLangOpts().ObjCAutoRefCount); 814 if (PropertyIvarType.isObjCGCStrong()) { 815 Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type); 816 Diag(property->getLocation(), diag::note_property_declare); 817 } else { 818 PropertyIvarType = 819 Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak); 820 } 821 } 822 if (AtLoc.isInvalid()) { 823 // Check when default synthesizing a property that there is 824 // an ivar matching property name and issue warning; since this 825 // is the most common case of not using an ivar used for backing 826 // property in non-default synthesis case. 827 ObjCInterfaceDecl *ClassDeclared=0; 828 ObjCIvarDecl *originalIvar = 829 IDecl->lookupInstanceVariable(property->getIdentifier(), 830 ClassDeclared); 831 if (originalIvar) { 832 Diag(PropertyDiagLoc, 833 diag::warn_autosynthesis_property_ivar_match) 834 << PropertyId << (Ivar == 0) << PropertyIvar 835 << originalIvar->getIdentifier(); 836 Diag(property->getLocation(), diag::note_property_declare); 837 Diag(originalIvar->getLocation(), diag::note_ivar_decl); 838 } 839 } 840 841 if (!Ivar) { 842 // In ARC, give the ivar a lifetime qualifier based on the 843 // property attributes. 844 if (getLangOpts().ObjCAutoRefCount && 845 !PropertyIvarType.getObjCLifetime() && 846 PropertyIvarType->isObjCRetainableType()) { 847 848 // It's an error if we have to do this and the user didn't 849 // explicitly write an ownership attribute on the property. 850 if (!property->hasWrittenStorageAttribute() && 851 !(kind & ObjCPropertyDecl::OBJC_PR_strong)) { 852 Diag(PropertyDiagLoc, 853 diag::err_arc_objc_property_default_assign_on_object); 854 Diag(property->getLocation(), diag::note_property_declare); 855 } else { 856 Qualifiers::ObjCLifetime lifetime = 857 getImpliedARCOwnership(kind, PropertyIvarType); 858 assert(lifetime && "no lifetime for property?"); 859 if (lifetime == Qualifiers::OCL_Weak) { 860 bool err = false; 861 if (const ObjCObjectPointerType *ObjT = 862 PropertyIvarType->getAs<ObjCObjectPointerType>()) 863 if (ObjT->getInterfaceDecl()->isArcWeakrefUnavailable()) { 864 Diag(PropertyDiagLoc, diag::err_arc_weak_unavailable_property); 865 Diag(property->getLocation(), diag::note_property_declare); 866 err = true; 867 } 868 if (!err && !getLangOpts().ObjCRuntimeHasWeak) { 869 Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime); 870 Diag(property->getLocation(), diag::note_property_declare); 871 } 872 } 873 874 Qualifiers qs; 875 qs.addObjCLifetime(lifetime); 876 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs); 877 } 878 } 879 880 if (kind & ObjCPropertyDecl::OBJC_PR_weak && 881 !getLangOpts().ObjCAutoRefCount && 882 getLangOpts().getGC() == LangOptions::NonGC) { 883 Diag(PropertyDiagLoc, diag::error_synthesize_weak_non_arc_or_gc); 884 Diag(property->getLocation(), diag::note_property_declare); 885 } 886 887 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, 888 PropertyIvarLoc,PropertyIvarLoc, PropertyIvar, 889 PropertyIvarType, /*Dinfo=*/0, 890 ObjCIvarDecl::Private, 891 (Expr *)0, true); 892 if (CompleteTypeErr) 893 Ivar->setInvalidDecl(); 894 ClassImpDecl->addDecl(Ivar); 895 IDecl->makeDeclVisibleInContext(Ivar); 896 property->setPropertyIvarDecl(Ivar); 897 898 if (getLangOpts().ObjCRuntime.isFragile()) 899 Diag(PropertyDiagLoc, diag::error_missing_property_ivar_decl) 900 << PropertyId; 901 // Note! I deliberately want it to fall thru so, we have a 902 // a property implementation and to avoid future warnings. 903 } else if (getLangOpts().ObjCRuntime.isNonFragile() && 904 !declaresSameEntity(ClassDeclared, IDecl)) { 905 Diag(PropertyDiagLoc, diag::error_ivar_in_superclass_use) 906 << property->getDeclName() << Ivar->getDeclName() 907 << ClassDeclared->getDeclName(); 908 Diag(Ivar->getLocation(), diag::note_previous_access_declaration) 909 << Ivar << Ivar->getName(); 910 // Note! I deliberately want it to fall thru so more errors are caught. 911 } 912 QualType IvarType = Context.getCanonicalType(Ivar->getType()); 913 914 // Check that type of property and its ivar are type compatible. 915 if (!Context.hasSameType(PropertyIvarType, IvarType)) { 916 compat = false; 917 if (isa<ObjCObjectPointerType>(PropertyIvarType) 918 && isa<ObjCObjectPointerType>(IvarType)) 919 compat = 920 Context.canAssignObjCInterfaces( 921 PropertyIvarType->getAs<ObjCObjectPointerType>(), 922 IvarType->getAs<ObjCObjectPointerType>()); 923 else { 924 compat = (CheckAssignmentConstraints(PropertyIvarLoc, PropertyIvarType, 925 IvarType) 926 == Compatible); 927 } 928 if (!compat) { 929 Diag(PropertyDiagLoc, diag::error_property_ivar_type) 930 << property->getDeclName() << PropType 931 << Ivar->getDeclName() << IvarType; 932 Diag(Ivar->getLocation(), diag::note_ivar_decl); 933 // Note! I deliberately want it to fall thru so, we have a 934 // a property implementation and to avoid future warnings. 935 } 936 else { 937 // FIXME! Rules for properties are somewhat different that those 938 // for assignments. Use a new routine to consolidate all cases; 939 // specifically for property redeclarations as well as for ivars. 940 QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType(); 941 QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType(); 942 if (lhsType != rhsType && 943 lhsType->isArithmeticType()) { 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 // Fall thru - see previous comment 949 } 950 } 951 // __weak is explicit. So it works on Canonical type. 952 if ((PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() && 953 getLangOpts().getGC() != LangOptions::NonGC)) { 954 Diag(PropertyDiagLoc, diag::error_weak_property) 955 << property->getDeclName() << Ivar->getDeclName(); 956 Diag(Ivar->getLocation(), diag::note_ivar_decl); 957 // Fall thru - see previous comment 958 } 959 // Fall thru - see previous comment 960 if ((property->getType()->isObjCObjectPointerType() || 961 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() && 962 getLangOpts().getGC() != LangOptions::NonGC) { 963 Diag(PropertyDiagLoc, diag::error_strong_property) 964 << property->getDeclName() << Ivar->getDeclName(); 965 // Fall thru - see previous comment 966 } 967 } 968 if (getLangOpts().ObjCAutoRefCount) 969 checkARCPropertyImpl(*this, PropertyLoc, property, Ivar); 970 } else if (PropertyIvar) 971 // @dynamic 972 Diag(PropertyDiagLoc, diag::error_dynamic_property_ivar_decl); 973 974 assert (property && "ActOnPropertyImplDecl - property declaration missing"); 975 ObjCPropertyImplDecl *PIDecl = 976 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, 977 property, 978 (Synthesize ? 979 ObjCPropertyImplDecl::Synthesize 980 : ObjCPropertyImplDecl::Dynamic), 981 Ivar, PropertyIvarLoc); 982 983 if (CompleteTypeErr || !compat) 984 PIDecl->setInvalidDecl(); 985 986 if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) { 987 getterMethod->createImplicitParams(Context, IDecl); 988 if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr && 989 Ivar->getType()->isRecordType()) { 990 // For Objective-C++, need to synthesize the AST for the IVAR object to be 991 // returned by the getter as it must conform to C++'s copy-return rules. 992 // FIXME. Eventually we want to do this for Objective-C as well. 993 ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); 994 DeclRefExpr *SelfExpr = 995 new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(), 996 VK_RValue, SourceLocation()); 997 Expr *IvarRefExpr = 998 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 999 SelfExpr, true, true); 1000 ExprResult Res = 1001 PerformCopyInitialization(InitializedEntity::InitializeResult( 1002 SourceLocation(), 1003 getterMethod->getResultType(), 1004 /*NRVO=*/false), 1005 SourceLocation(), 1006 Owned(IvarRefExpr)); 1007 if (!Res.isInvalid()) { 1008 Expr *ResExpr = Res.takeAs<Expr>(); 1009 if (ResExpr) 1010 ResExpr = MaybeCreateExprWithCleanups(ResExpr); 1011 PIDecl->setGetterCXXConstructor(ResExpr); 1012 } 1013 } 1014 if (property->hasAttr<NSReturnsNotRetainedAttr>() && 1015 !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) { 1016 Diag(getterMethod->getLocation(), 1017 diag::warn_property_getter_owning_mismatch); 1018 Diag(property->getLocation(), diag::note_property_declare); 1019 } 1020 } 1021 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) { 1022 setterMethod->createImplicitParams(Context, IDecl); 1023 if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr && 1024 Ivar->getType()->isRecordType()) { 1025 // FIXME. Eventually we want to do this for Objective-C as well. 1026 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); 1027 DeclRefExpr *SelfExpr = 1028 new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(), 1029 VK_RValue, SourceLocation()); 1030 Expr *lhs = 1031 new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, 1032 SelfExpr, true, true); 1033 ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); 1034 ParmVarDecl *Param = (*P); 1035 QualType T = Param->getType().getNonReferenceType(); 1036 Expr *rhs = new (Context) DeclRefExpr(Param, false, T, 1037 VK_LValue, SourceLocation()); 1038 ExprResult Res = BuildBinOp(S, lhs->getLocEnd(), 1039 BO_Assign, lhs, rhs); 1040 if (property->getPropertyAttributes() & 1041 ObjCPropertyDecl::OBJC_PR_atomic) { 1042 Expr *callExpr = Res.takeAs<Expr>(); 1043 if (const CXXOperatorCallExpr *CXXCE = 1044 dyn_cast_or_null<CXXOperatorCallExpr>(callExpr)) 1045 if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee()) 1046 if (!FuncDecl->isTrivial()) 1047 if (property->getType()->isReferenceType()) { 1048 Diag(PropertyLoc, 1049 diag::err_atomic_property_nontrivial_assign_op) 1050 << property->getType(); 1051 Diag(FuncDecl->getLocStart(), 1052 diag::note_callee_decl) << FuncDecl; 1053 } 1054 } 1055 PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>()); 1056 } 1057 } 1058 1059 if (IC) { 1060 if (Synthesize) 1061 if (ObjCPropertyImplDecl *PPIDecl = 1062 IC->FindPropertyImplIvarDecl(PropertyIvar)) { 1063 Diag(PropertyLoc, diag::error_duplicate_ivar_use) 1064 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 1065 << PropertyIvar; 1066 Diag(PPIDecl->getLocation(), diag::note_previous_use); 1067 } 1068 1069 if (ObjCPropertyImplDecl *PPIDecl 1070 = IC->FindPropertyImplDecl(PropertyId)) { 1071 Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; 1072 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 1073 return 0; 1074 } 1075 IC->addPropertyImplementation(PIDecl); 1076 if (getLangOpts().ObjCDefaultSynthProperties && 1077 getLangOpts().ObjCRuntime.isNonFragile() && 1078 !IDecl->isObjCRequiresPropertyDefs()) { 1079 // Diagnose if an ivar was lazily synthesdized due to a previous 1080 // use and if 1) property is @dynamic or 2) property is synthesized 1081 // but it requires an ivar of different name. 1082 ObjCInterfaceDecl *ClassDeclared=0; 1083 ObjCIvarDecl *Ivar = 0; 1084 if (!Synthesize) 1085 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 1086 else { 1087 if (PropertyIvar && PropertyIvar != PropertyId) 1088 Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared); 1089 } 1090 // Issue diagnostics only if Ivar belongs to current class. 1091 if (Ivar && Ivar->getSynthesize() && 1092 declaresSameEntity(IC->getClassInterface(), ClassDeclared)) { 1093 Diag(Ivar->getLocation(), diag::err_undeclared_var_use) 1094 << PropertyId; 1095 Ivar->setInvalidDecl(); 1096 } 1097 } 1098 } else { 1099 if (Synthesize) 1100 if (ObjCPropertyImplDecl *PPIDecl = 1101 CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) { 1102 Diag(PropertyDiagLoc, diag::error_duplicate_ivar_use) 1103 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() 1104 << PropertyIvar; 1105 Diag(PPIDecl->getLocation(), diag::note_previous_use); 1106 } 1107 1108 if (ObjCPropertyImplDecl *PPIDecl = 1109 CatImplClass->FindPropertyImplDecl(PropertyId)) { 1110 Diag(PropertyDiagLoc, diag::error_property_implemented) << PropertyId; 1111 Diag(PPIDecl->getLocation(), diag::note_previous_declaration); 1112 return 0; 1113 } 1114 CatImplClass->addPropertyImplementation(PIDecl); 1115 } 1116 1117 return PIDecl; 1118 } 1119 1120 //===----------------------------------------------------------------------===// 1121 // Helper methods. 1122 //===----------------------------------------------------------------------===// 1123 1124 /// DiagnosePropertyMismatch - Compares two properties for their 1125 /// attributes and types and warns on a variety of inconsistencies. 1126 /// 1127 void 1128 Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, 1129 ObjCPropertyDecl *SuperProperty, 1130 const IdentifierInfo *inheritedName) { 1131 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1132 Property->getPropertyAttributes(); 1133 ObjCPropertyDecl::PropertyAttributeKind SAttr = 1134 SuperProperty->getPropertyAttributes(); 1135 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) 1136 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) 1137 Diag(Property->getLocation(), diag::warn_readonly_property) 1138 << Property->getDeclName() << inheritedName; 1139 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) 1140 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) 1141 Diag(Property->getLocation(), diag::warn_property_attribute) 1142 << Property->getDeclName() << "copy" << inheritedName; 1143 else if (!(SAttr & ObjCPropertyDecl::OBJC_PR_readonly)){ 1144 unsigned CAttrRetain = 1145 (CAttr & 1146 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 1147 unsigned SAttrRetain = 1148 (SAttr & 1149 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 1150 bool CStrong = (CAttrRetain != 0); 1151 bool SStrong = (SAttrRetain != 0); 1152 if (CStrong != SStrong) 1153 Diag(Property->getLocation(), diag::warn_property_attribute) 1154 << Property->getDeclName() << "retain (or strong)" << inheritedName; 1155 } 1156 1157 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) 1158 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) 1159 Diag(Property->getLocation(), diag::warn_property_attribute) 1160 << Property->getDeclName() << "atomic" << inheritedName; 1161 if (Property->getSetterName() != SuperProperty->getSetterName()) 1162 Diag(Property->getLocation(), diag::warn_property_attribute) 1163 << Property->getDeclName() << "setter" << inheritedName; 1164 if (Property->getGetterName() != SuperProperty->getGetterName()) 1165 Diag(Property->getLocation(), diag::warn_property_attribute) 1166 << Property->getDeclName() << "getter" << inheritedName; 1167 1168 QualType LHSType = 1169 Context.getCanonicalType(SuperProperty->getType()); 1170 QualType RHSType = 1171 Context.getCanonicalType(Property->getType()); 1172 1173 if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) { 1174 // Do cases not handled in above. 1175 // FIXME. For future support of covariant property types, revisit this. 1176 bool IncompatibleObjC = false; 1177 QualType ConvertedType; 1178 if (!isObjCPointerConversion(RHSType, LHSType, 1179 ConvertedType, IncompatibleObjC) || 1180 IncompatibleObjC) { 1181 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) 1182 << Property->getType() << SuperProperty->getType() << inheritedName; 1183 Diag(SuperProperty->getLocation(), diag::note_property_declare); 1184 } 1185 } 1186 } 1187 1188 bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, 1189 ObjCMethodDecl *GetterMethod, 1190 SourceLocation Loc) { 1191 if (!GetterMethod) 1192 return false; 1193 QualType GetterType = GetterMethod->getResultType().getNonReferenceType(); 1194 QualType PropertyIvarType = property->getType().getNonReferenceType(); 1195 bool compat = Context.hasSameType(PropertyIvarType, GetterType); 1196 if (!compat) { 1197 if (isa<ObjCObjectPointerType>(PropertyIvarType) && 1198 isa<ObjCObjectPointerType>(GetterType)) 1199 compat = 1200 Context.canAssignObjCInterfaces( 1201 GetterType->getAs<ObjCObjectPointerType>(), 1202 PropertyIvarType->getAs<ObjCObjectPointerType>()); 1203 else if (CheckAssignmentConstraints(Loc, GetterType, PropertyIvarType) 1204 != Compatible) { 1205 Diag(Loc, diag::error_property_accessor_type) 1206 << property->getDeclName() << PropertyIvarType 1207 << GetterMethod->getSelector() << GetterType; 1208 Diag(GetterMethod->getLocation(), diag::note_declared_at); 1209 return true; 1210 } else { 1211 compat = true; 1212 QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType(); 1213 QualType rhsType =Context.getCanonicalType(GetterType).getUnqualifiedType(); 1214 if (lhsType != rhsType && lhsType->isArithmeticType()) 1215 compat = false; 1216 } 1217 } 1218 1219 if (!compat) { 1220 Diag(Loc, diag::warn_accessor_property_type_mismatch) 1221 << property->getDeclName() 1222 << GetterMethod->getSelector(); 1223 Diag(GetterMethod->getLocation(), diag::note_declared_at); 1224 return true; 1225 } 1226 1227 return false; 1228 } 1229 1230 /// ComparePropertiesInBaseAndSuper - This routine compares property 1231 /// declarations in base and its super class, if any, and issues 1232 /// diagnostics in a variety of inconsistent situations. 1233 /// 1234 void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) { 1235 ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); 1236 if (!SDecl) 1237 return; 1238 // FIXME: O(N^2) 1239 for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(), 1240 E = SDecl->prop_end(); S != E; ++S) { 1241 ObjCPropertyDecl *SuperPDecl = *S; 1242 // Does property in super class has declaration in current class? 1243 for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(), 1244 E = IDecl->prop_end(); I != E; ++I) { 1245 ObjCPropertyDecl *PDecl = *I; 1246 if (SuperPDecl->getIdentifier() == PDecl->getIdentifier()) 1247 DiagnosePropertyMismatch(PDecl, SuperPDecl, 1248 SDecl->getIdentifier()); 1249 } 1250 } 1251 } 1252 1253 /// MatchOneProtocolPropertiesInClass - This routine goes thru the list 1254 /// of properties declared in a protocol and compares their attribute against 1255 /// the same property declared in the class or category. 1256 void 1257 Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl, 1258 ObjCProtocolDecl *PDecl) { 1259 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 1260 if (!IDecl) { 1261 // Category 1262 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 1263 assert (CatDecl && "MatchOneProtocolPropertiesInClass"); 1264 if (!CatDecl->IsClassExtension()) 1265 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1266 E = PDecl->prop_end(); P != E; ++P) { 1267 ObjCPropertyDecl *Pr = *P; 1268 ObjCCategoryDecl::prop_iterator CP, CE; 1269 // Is this property already in category's list of properties? 1270 for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP!=CE; ++CP) 1271 if (CP->getIdentifier() == Pr->getIdentifier()) 1272 break; 1273 if (CP != CE) 1274 // Property protocol already exist in class. Diagnose any mismatch. 1275 DiagnosePropertyMismatch(*CP, Pr, PDecl->getIdentifier()); 1276 } 1277 return; 1278 } 1279 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1280 E = PDecl->prop_end(); P != E; ++P) { 1281 ObjCPropertyDecl *Pr = *P; 1282 ObjCInterfaceDecl::prop_iterator CP, CE; 1283 // Is this property already in class's list of properties? 1284 for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP) 1285 if (CP->getIdentifier() == Pr->getIdentifier()) 1286 break; 1287 if (CP != CE) 1288 // Property protocol already exist in class. Diagnose any mismatch. 1289 DiagnosePropertyMismatch(*CP, Pr, PDecl->getIdentifier()); 1290 } 1291 } 1292 1293 /// CompareProperties - This routine compares properties 1294 /// declared in 'ClassOrProtocol' objects (which can be a class or an 1295 /// inherited protocol with the list of properties for class/category 'CDecl' 1296 /// 1297 void Sema::CompareProperties(Decl *CDecl, Decl *ClassOrProtocol) { 1298 Decl *ClassDecl = ClassOrProtocol; 1299 ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl); 1300 1301 if (!IDecl) { 1302 // Category 1303 ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl); 1304 assert (CatDecl && "CompareProperties"); 1305 if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) { 1306 for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(), 1307 E = MDecl->protocol_end(); P != E; ++P) 1308 // Match properties of category with those of protocol (*P) 1309 MatchOneProtocolPropertiesInClass(CatDecl, *P); 1310 1311 // Go thru the list of protocols for this category and recursively match 1312 // their properties with those in the category. 1313 for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(), 1314 E = CatDecl->protocol_end(); P != E; ++P) 1315 CompareProperties(CatDecl, *P); 1316 } else { 1317 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 1318 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 1319 E = MD->protocol_end(); P != E; ++P) 1320 MatchOneProtocolPropertiesInClass(CatDecl, *P); 1321 } 1322 return; 1323 } 1324 1325 if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { 1326 for (ObjCInterfaceDecl::all_protocol_iterator 1327 P = MDecl->all_referenced_protocol_begin(), 1328 E = MDecl->all_referenced_protocol_end(); P != E; ++P) 1329 // Match properties of class IDecl with those of protocol (*P). 1330 MatchOneProtocolPropertiesInClass(IDecl, *P); 1331 1332 // Go thru the list of protocols for this class and recursively match 1333 // their properties with those declared in the class. 1334 for (ObjCInterfaceDecl::all_protocol_iterator 1335 P = IDecl->all_referenced_protocol_begin(), 1336 E = IDecl->all_referenced_protocol_end(); P != E; ++P) 1337 CompareProperties(IDecl, *P); 1338 } else { 1339 ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl); 1340 for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(), 1341 E = MD->protocol_end(); P != E; ++P) 1342 MatchOneProtocolPropertiesInClass(IDecl, *P); 1343 } 1344 } 1345 1346 /// isPropertyReadonly - Return true if property is readonly, by searching 1347 /// for the property in the class and in its categories and implementations 1348 /// 1349 bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl, 1350 ObjCInterfaceDecl *IDecl) { 1351 // by far the most common case. 1352 if (!PDecl->isReadOnly()) 1353 return false; 1354 // Even if property is ready only, if interface has a user defined setter, 1355 // it is not considered read only. 1356 if (IDecl->getInstanceMethod(PDecl->getSetterName())) 1357 return false; 1358 1359 // Main class has the property as 'readonly'. Must search 1360 // through the category list to see if the property's 1361 // attribute has been over-ridden to 'readwrite'. 1362 for (ObjCCategoryDecl *Category = IDecl->getCategoryList(); 1363 Category; Category = Category->getNextClassCategory()) { 1364 // Even if property is ready only, if a category has a user defined setter, 1365 // it is not considered read only. 1366 if (Category->getInstanceMethod(PDecl->getSetterName())) 1367 return false; 1368 ObjCPropertyDecl *P = 1369 Category->FindPropertyDeclaration(PDecl->getIdentifier()); 1370 if (P && !P->isReadOnly()) 1371 return false; 1372 } 1373 1374 // Also, check for definition of a setter method in the implementation if 1375 // all else failed. 1376 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) { 1377 if (ObjCImplementationDecl *IMD = 1378 dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) { 1379 if (IMD->getInstanceMethod(PDecl->getSetterName())) 1380 return false; 1381 } else if (ObjCCategoryImplDecl *CIMD = 1382 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) { 1383 if (CIMD->getInstanceMethod(PDecl->getSetterName())) 1384 return false; 1385 } 1386 } 1387 // Lastly, look through the implementation (if one is in scope). 1388 if (ObjCImplementationDecl *ImpDecl = IDecl->getImplementation()) 1389 if (ImpDecl->getInstanceMethod(PDecl->getSetterName())) 1390 return false; 1391 // If all fails, look at the super class. 1392 if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass()) 1393 return isPropertyReadonly(PDecl, SIDecl); 1394 return true; 1395 } 1396 1397 /// CollectImmediateProperties - This routine collects all properties in 1398 /// the class and its conforming protocols; but not those it its super class. 1399 void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, 1400 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap, 1401 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap) { 1402 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1403 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 1404 E = IDecl->prop_end(); P != E; ++P) { 1405 ObjCPropertyDecl *Prop = *P; 1406 PropMap[Prop->getIdentifier()] = Prop; 1407 } 1408 // scan through class's protocols. 1409 for (ObjCInterfaceDecl::all_protocol_iterator 1410 PI = IDecl->all_referenced_protocol_begin(), 1411 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) 1412 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 1413 } 1414 if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) { 1415 if (!CATDecl->IsClassExtension()) 1416 for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(), 1417 E = CATDecl->prop_end(); P != E; ++P) { 1418 ObjCPropertyDecl *Prop = *P; 1419 PropMap[Prop->getIdentifier()] = Prop; 1420 } 1421 // scan through class's protocols. 1422 for (ObjCCategoryDecl::protocol_iterator PI = CATDecl->protocol_begin(), 1423 E = CATDecl->protocol_end(); PI != E; ++PI) 1424 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 1425 } 1426 else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) { 1427 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1428 E = PDecl->prop_end(); P != E; ++P) { 1429 ObjCPropertyDecl *Prop = *P; 1430 ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()]; 1431 // Exclude property for protocols which conform to class's super-class, 1432 // as super-class has to implement the property. 1433 if (!PropertyFromSuper || 1434 PropertyFromSuper->getIdentifier() != Prop->getIdentifier()) { 1435 ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()]; 1436 if (!PropEntry) 1437 PropEntry = Prop; 1438 } 1439 } 1440 // scan through protocol's protocols. 1441 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 1442 E = PDecl->protocol_end(); PI != E; ++PI) 1443 CollectImmediateProperties((*PI), PropMap, SuperPropMap); 1444 } 1445 } 1446 1447 /// CollectClassPropertyImplementations - This routine collects list of 1448 /// properties to be implemented in the class. This includes, class's 1449 /// and its conforming protocols' properties. 1450 static void CollectClassPropertyImplementations(ObjCContainerDecl *CDecl, 1451 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 1452 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1453 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 1454 E = IDecl->prop_end(); P != E; ++P) { 1455 ObjCPropertyDecl *Prop = *P; 1456 PropMap[Prop->getIdentifier()] = Prop; 1457 } 1458 for (ObjCInterfaceDecl::all_protocol_iterator 1459 PI = IDecl->all_referenced_protocol_begin(), 1460 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) 1461 CollectClassPropertyImplementations((*PI), PropMap); 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 if (!PropMap.count(Prop->getIdentifier())) 1468 PropMap[Prop->getIdentifier()] = Prop; 1469 } 1470 // scan through protocol's protocols. 1471 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 1472 E = PDecl->protocol_end(); PI != E; ++PI) 1473 CollectClassPropertyImplementations((*PI), PropMap); 1474 } 1475 } 1476 1477 /// CollectSuperClassPropertyImplementations - This routine collects list of 1478 /// properties to be implemented in super class(s) and also coming from their 1479 /// conforming protocols. 1480 static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, 1481 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) { 1482 if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) { 1483 while (SDecl) { 1484 CollectClassPropertyImplementations(SDecl, PropMap); 1485 SDecl = SDecl->getSuperClass(); 1486 } 1487 } 1488 } 1489 1490 /// LookupPropertyDecl - Looks up a property in the current class and all 1491 /// its protocols. 1492 ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl, 1493 IdentifierInfo *II) { 1494 if (const ObjCInterfaceDecl *IDecl = 1495 dyn_cast<ObjCInterfaceDecl>(CDecl)) { 1496 for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(), 1497 E = IDecl->prop_end(); P != E; ++P) { 1498 ObjCPropertyDecl *Prop = *P; 1499 if (Prop->getIdentifier() == II) 1500 return Prop; 1501 } 1502 // scan through class's protocols. 1503 for (ObjCInterfaceDecl::all_protocol_iterator 1504 PI = IDecl->all_referenced_protocol_begin(), 1505 E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) { 1506 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 1507 if (Prop) 1508 return Prop; 1509 } 1510 } 1511 else if (const ObjCProtocolDecl *PDecl = 1512 dyn_cast<ObjCProtocolDecl>(CDecl)) { 1513 for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), 1514 E = PDecl->prop_end(); P != E; ++P) { 1515 ObjCPropertyDecl *Prop = *P; 1516 if (Prop->getIdentifier() == II) 1517 return Prop; 1518 } 1519 // scan through protocol's protocols. 1520 for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), 1521 E = PDecl->protocol_end(); PI != E; ++PI) { 1522 ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II); 1523 if (Prop) 1524 return Prop; 1525 } 1526 } 1527 return 0; 1528 } 1529 1530 static IdentifierInfo * getDefaultSynthIvarName(ObjCPropertyDecl *Prop, 1531 ASTContext &Ctx) { 1532 SmallString<128> ivarName; 1533 { 1534 llvm::raw_svector_ostream os(ivarName); 1535 os << '_' << Prop->getIdentifier()->getName(); 1536 } 1537 return &Ctx.Idents.get(ivarName.str()); 1538 } 1539 1540 /// \brief Default synthesizes all properties which must be synthesized 1541 /// in class's \@implementation. 1542 void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl, 1543 ObjCInterfaceDecl *IDecl) { 1544 1545 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 1546 CollectClassPropertyImplementations(IDecl, PropMap); 1547 if (PropMap.empty()) 1548 return; 1549 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; 1550 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 1551 1552 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 1553 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1554 ObjCPropertyDecl *Prop = P->second; 1555 // If property to be implemented in the super class, ignore. 1556 if (SuperPropMap[Prop->getIdentifier()]) 1557 continue; 1558 // Is there a matching propery synthesize/dynamic? 1559 if (Prop->isInvalidDecl() || 1560 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 1561 IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) 1562 continue; 1563 // Property may have been synthesized by user. 1564 if (IMPDecl->FindPropertyImplDecl(Prop->getIdentifier())) 1565 continue; 1566 if (IMPDecl->getInstanceMethod(Prop->getGetterName())) { 1567 if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly) 1568 continue; 1569 if (IMPDecl->getInstanceMethod(Prop->getSetterName())) 1570 continue; 1571 } 1572 if (isa<ObjCProtocolDecl>(Prop->getDeclContext())) { 1573 // We won't auto-synthesize properties declared in protocols. 1574 Diag(IMPDecl->getLocation(), 1575 diag::warn_auto_synthesizing_protocol_property); 1576 Diag(Prop->getLocation(), diag::note_property_declare); 1577 continue; 1578 } 1579 1580 // We use invalid SourceLocations for the synthesized ivars since they 1581 // aren't really synthesized at a particular location; they just exist. 1582 // Saying that they are located at the @implementation isn't really going 1583 // to help users. 1584 ObjCPropertyImplDecl *PIDecl = dyn_cast_or_null<ObjCPropertyImplDecl>( 1585 ActOnPropertyImplDecl(S, SourceLocation(), SourceLocation(), 1586 true, 1587 /* property = */ Prop->getIdentifier(), 1588 /* ivar = */ getDefaultSynthIvarName(Prop, Context), 1589 Prop->getLocation())); 1590 if (PIDecl) { 1591 Diag(Prop->getLocation(), diag::warn_missing_explicit_synthesis); 1592 Diag(IMPDecl->getLocation(), diag::note_while_in_implementation); 1593 } 1594 } 1595 } 1596 1597 void Sema::DefaultSynthesizeProperties(Scope *S, Decl *D) { 1598 if (!LangOpts.ObjCDefaultSynthProperties || LangOpts.ObjCRuntime.isFragile()) 1599 return; 1600 ObjCImplementationDecl *IC=dyn_cast_or_null<ObjCImplementationDecl>(D); 1601 if (!IC) 1602 return; 1603 if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) 1604 if (!IDecl->isObjCRequiresPropertyDefs()) 1605 DefaultSynthesizeProperties(S, IC, IDecl); 1606 } 1607 1608 void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, 1609 ObjCContainerDecl *CDecl, 1610 const SelectorSet &InsMap) { 1611 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap; 1612 if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) 1613 CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); 1614 1615 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap; 1616 CollectImmediateProperties(CDecl, PropMap, SuperPropMap); 1617 if (PropMap.empty()) 1618 return; 1619 1620 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap; 1621 for (ObjCImplDecl::propimpl_iterator 1622 I = IMPDecl->propimpl_begin(), 1623 EI = IMPDecl->propimpl_end(); I != EI; ++I) 1624 PropImplMap.insert(I->getPropertyDecl()); 1625 1626 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 1627 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1628 ObjCPropertyDecl *Prop = P->second; 1629 // Is there a matching propery synthesize/dynamic? 1630 if (Prop->isInvalidDecl() || 1631 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || 1632 PropImplMap.count(Prop) || Prop->hasAttr<UnavailableAttr>()) 1633 continue; 1634 if (!InsMap.count(Prop->getGetterName())) { 1635 Diag(IMPDecl->getLocation(), 1636 isa<ObjCCategoryDecl>(CDecl) ? 1637 diag::warn_setter_getter_impl_required_in_category : 1638 diag::warn_setter_getter_impl_required) 1639 << Prop->getDeclName() << Prop->getGetterName(); 1640 Diag(Prop->getLocation(), 1641 diag::note_property_declare); 1642 if (LangOpts.ObjCDefaultSynthProperties && LangOpts.ObjCRuntime.isNonFragile()) 1643 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl)) 1644 if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs()) 1645 Diag(RID->getLocation(), diag::note_suppressed_class_declare); 1646 1647 } 1648 1649 if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) { 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->getSetterName(); 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 1665 void 1666 Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl, 1667 ObjCContainerDecl* IDecl) { 1668 // Rules apply in non-GC mode only 1669 if (getLangOpts().getGC() != LangOptions::NonGC) 1670 return; 1671 for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(), 1672 E = IDecl->prop_end(); 1673 I != E; ++I) { 1674 ObjCPropertyDecl *Property = *I; 1675 ObjCMethodDecl *GetterMethod = 0; 1676 ObjCMethodDecl *SetterMethod = 0; 1677 bool LookedUpGetterSetter = false; 1678 1679 unsigned Attributes = Property->getPropertyAttributes(); 1680 unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten(); 1681 1682 if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic) && 1683 !(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_nonatomic)) { 1684 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1685 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1686 LookedUpGetterSetter = true; 1687 if (GetterMethod) { 1688 Diag(GetterMethod->getLocation(), 1689 diag::warn_default_atomic_custom_getter_setter) 1690 << Property->getIdentifier() << 0; 1691 Diag(Property->getLocation(), diag::note_property_declare); 1692 } 1693 if (SetterMethod) { 1694 Diag(SetterMethod->getLocation(), 1695 diag::warn_default_atomic_custom_getter_setter) 1696 << Property->getIdentifier() << 1; 1697 Diag(Property->getLocation(), diag::note_property_declare); 1698 } 1699 } 1700 1701 // We only care about readwrite atomic property. 1702 if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) || 1703 !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite)) 1704 continue; 1705 if (const ObjCPropertyImplDecl *PIDecl 1706 = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) { 1707 if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) 1708 continue; 1709 if (!LookedUpGetterSetter) { 1710 GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName()); 1711 SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName()); 1712 LookedUpGetterSetter = true; 1713 } 1714 if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) { 1715 SourceLocation MethodLoc = 1716 (GetterMethod ? GetterMethod->getLocation() 1717 : SetterMethod->getLocation()); 1718 Diag(MethodLoc, diag::warn_atomic_property_rule) 1719 << Property->getIdentifier() << (GetterMethod != 0) 1720 << (SetterMethod != 0); 1721 // fixit stuff. 1722 if (!AttributesAsWritten) { 1723 if (Property->getLParenLoc().isValid()) { 1724 // @property () ... case. 1725 SourceRange PropSourceRange(Property->getAtLoc(), 1726 Property->getLParenLoc()); 1727 Diag(Property->getLocation(), diag::note_atomic_property_fixup_suggest) << 1728 FixItHint::CreateReplacement(PropSourceRange, "@property (nonatomic"); 1729 } 1730 else { 1731 //@property id etc. 1732 SourceLocation endLoc = 1733 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); 1734 endLoc = endLoc.getLocWithOffset(-1); 1735 SourceRange PropSourceRange(Property->getAtLoc(), endLoc); 1736 Diag(Property->getLocation(), diag::note_atomic_property_fixup_suggest) << 1737 FixItHint::CreateReplacement(PropSourceRange, "@property (nonatomic) "); 1738 } 1739 } 1740 else if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic)) { 1741 // @property () ... case. 1742 SourceLocation endLoc = Property->getLParenLoc(); 1743 SourceRange PropSourceRange(Property->getAtLoc(), endLoc); 1744 Diag(Property->getLocation(), diag::note_atomic_property_fixup_suggest) << 1745 FixItHint::CreateReplacement(PropSourceRange, "@property (nonatomic, "); 1746 } 1747 else 1748 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest); 1749 Diag(Property->getLocation(), diag::note_property_declare); 1750 } 1751 } 1752 } 1753 } 1754 1755 void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) { 1756 if (getLangOpts().getGC() == LangOptions::GCOnly) 1757 return; 1758 1759 for (ObjCImplementationDecl::propimpl_iterator 1760 i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) { 1761 ObjCPropertyImplDecl *PID = *i; 1762 if (PID->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) 1763 continue; 1764 1765 const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 1766 if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() && 1767 !D->getInstanceMethod(PD->getGetterName())) { 1768 ObjCMethodDecl *method = PD->getGetterMethodDecl(); 1769 if (!method) 1770 continue; 1771 ObjCMethodFamily family = method->getMethodFamily(); 1772 if (family == OMF_alloc || family == OMF_copy || 1773 family == OMF_mutableCopy || family == OMF_new) { 1774 if (getLangOpts().ObjCAutoRefCount) 1775 Diag(PID->getLocation(), diag::err_ownin_getter_rule); 1776 else 1777 Diag(PID->getLocation(), diag::warn_owning_getter_rule); 1778 Diag(PD->getLocation(), diag::note_property_declare); 1779 } 1780 } 1781 } 1782 } 1783 1784 /// AddPropertyAttrs - Propagates attributes from a property to the 1785 /// implicitly-declared getter or setter for that property. 1786 static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, 1787 ObjCPropertyDecl *Property) { 1788 // Should we just clone all attributes over? 1789 for (Decl::attr_iterator A = Property->attr_begin(), 1790 AEnd = Property->attr_end(); 1791 A != AEnd; ++A) { 1792 if (isa<DeprecatedAttr>(*A) || 1793 isa<UnavailableAttr>(*A) || 1794 isa<AvailabilityAttr>(*A)) 1795 PropertyMethod->addAttr((*A)->clone(S.Context)); 1796 } 1797 } 1798 1799 /// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods 1800 /// have the property type and issue diagnostics if they don't. 1801 /// Also synthesize a getter/setter method if none exist (and update the 1802 /// appropriate lookup tables. FIXME: Should reconsider if adding synthesized 1803 /// methods is the "right" thing to do. 1804 void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property, 1805 ObjCContainerDecl *CD, 1806 ObjCPropertyDecl *redeclaredProperty, 1807 ObjCContainerDecl *lexicalDC) { 1808 1809 ObjCMethodDecl *GetterMethod, *SetterMethod; 1810 1811 GetterMethod = CD->getInstanceMethod(property->getGetterName()); 1812 SetterMethod = CD->getInstanceMethod(property->getSetterName()); 1813 DiagnosePropertyAccessorMismatch(property, GetterMethod, 1814 property->getLocation()); 1815 1816 if (SetterMethod) { 1817 ObjCPropertyDecl::PropertyAttributeKind CAttr = 1818 property->getPropertyAttributes(); 1819 if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) && 1820 Context.getCanonicalType(SetterMethod->getResultType()) != 1821 Context.VoidTy) 1822 Diag(SetterMethod->getLocation(), diag::err_setter_type_void); 1823 if (SetterMethod->param_size() != 1 || 1824 !Context.hasSameUnqualifiedType( 1825 (*SetterMethod->param_begin())->getType().getNonReferenceType(), 1826 property->getType().getNonReferenceType())) { 1827 Diag(property->getLocation(), 1828 diag::warn_accessor_property_type_mismatch) 1829 << property->getDeclName() 1830 << SetterMethod->getSelector(); 1831 Diag(SetterMethod->getLocation(), diag::note_declared_at); 1832 } 1833 } 1834 1835 // Synthesize getter/setter methods if none exist. 1836 // Find the default getter and if one not found, add one. 1837 // FIXME: The synthesized property we set here is misleading. We almost always 1838 // synthesize these methods unless the user explicitly provided prototypes 1839 // (which is odd, but allowed). Sema should be typechecking that the 1840 // declarations jive in that situation (which it is not currently). 1841 if (!GetterMethod) { 1842 // No instance method of same name as property getter name was found. 1843 // Declare a getter method and add it to the list of methods 1844 // for this class. 1845 SourceLocation Loc = redeclaredProperty ? 1846 redeclaredProperty->getLocation() : 1847 property->getLocation(); 1848 1849 GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc, 1850 property->getGetterName(), 1851 property->getType(), 0, CD, /*isInstance=*/true, 1852 /*isVariadic=*/false, /*isSynthesized=*/true, 1853 /*isImplicitlyDeclared=*/true, /*isDefined=*/false, 1854 (property->getPropertyImplementation() == 1855 ObjCPropertyDecl::Optional) ? 1856 ObjCMethodDecl::Optional : 1857 ObjCMethodDecl::Required); 1858 CD->addDecl(GetterMethod); 1859 1860 AddPropertyAttrs(*this, GetterMethod, property); 1861 1862 // FIXME: Eventually this shouldn't be needed, as the lexical context 1863 // and the real context should be the same. 1864 if (lexicalDC) 1865 GetterMethod->setLexicalDeclContext(lexicalDC); 1866 if (property->hasAttr<NSReturnsNotRetainedAttr>()) 1867 GetterMethod->addAttr( 1868 ::new (Context) NSReturnsNotRetainedAttr(Loc, Context)); 1869 } else 1870 // A user declared getter will be synthesize when @synthesize of 1871 // the property with the same name is seen in the @implementation 1872 GetterMethod->setSynthesized(true); 1873 property->setGetterMethodDecl(GetterMethod); 1874 1875 // Skip setter if property is read-only. 1876 if (!property->isReadOnly()) { 1877 // Find the default setter and if one not found, add one. 1878 if (!SetterMethod) { 1879 // No instance method of same name as property setter name was found. 1880 // Declare a setter method and add it to the list of methods 1881 // for this class. 1882 SourceLocation Loc = redeclaredProperty ? 1883 redeclaredProperty->getLocation() : 1884 property->getLocation(); 1885 1886 SetterMethod = 1887 ObjCMethodDecl::Create(Context, Loc, Loc, 1888 property->getSetterName(), Context.VoidTy, 0, 1889 CD, /*isInstance=*/true, /*isVariadic=*/false, 1890 /*isSynthesized=*/true, 1891 /*isImplicitlyDeclared=*/true, 1892 /*isDefined=*/false, 1893 (property->getPropertyImplementation() == 1894 ObjCPropertyDecl::Optional) ? 1895 ObjCMethodDecl::Optional : 1896 ObjCMethodDecl::Required); 1897 1898 // Invent the arguments for the setter. We don't bother making a 1899 // nice name for the argument. 1900 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, 1901 Loc, Loc, 1902 property->getIdentifier(), 1903 property->getType().getUnqualifiedType(), 1904 /*TInfo=*/0, 1905 SC_None, 1906 SC_None, 1907 0); 1908 SetterMethod->setMethodParams(Context, Argument, 1909 ArrayRef<SourceLocation>()); 1910 1911 AddPropertyAttrs(*this, SetterMethod, property); 1912 1913 CD->addDecl(SetterMethod); 1914 // FIXME: Eventually this shouldn't be needed, as the lexical context 1915 // and the real context should be the same. 1916 if (lexicalDC) 1917 SetterMethod->setLexicalDeclContext(lexicalDC); 1918 } else 1919 // A user declared setter will be synthesize when @synthesize of 1920 // the property with the same name is seen in the @implementation 1921 SetterMethod->setSynthesized(true); 1922 property->setSetterMethodDecl(SetterMethod); 1923 } 1924 // Add any synthesized methods to the global pool. This allows us to 1925 // handle the following, which is supported by GCC (and part of the design). 1926 // 1927 // @interface Foo 1928 // @property double bar; 1929 // @end 1930 // 1931 // void thisIsUnfortunate() { 1932 // id foo; 1933 // double bar = [foo bar]; 1934 // } 1935 // 1936 if (GetterMethod) 1937 AddInstanceMethodToGlobalPool(GetterMethod); 1938 if (SetterMethod) 1939 AddInstanceMethodToGlobalPool(SetterMethod); 1940 1941 ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(CD); 1942 if (!CurrentClass) { 1943 if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CD)) 1944 CurrentClass = Cat->getClassInterface(); 1945 else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(CD)) 1946 CurrentClass = Impl->getClassInterface(); 1947 } 1948 if (GetterMethod) 1949 CheckObjCMethodOverrides(GetterMethod, CurrentClass, Sema::RTC_Unknown); 1950 if (SetterMethod) 1951 CheckObjCMethodOverrides(SetterMethod, CurrentClass, Sema::RTC_Unknown); 1952 } 1953 1954 void Sema::CheckObjCPropertyAttributes(Decl *PDecl, 1955 SourceLocation Loc, 1956 unsigned &Attributes, 1957 bool propertyInPrimaryClass) { 1958 // FIXME: Improve the reported location. 1959 if (!PDecl || PDecl->isInvalidDecl()) 1960 return; 1961 1962 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 1963 QualType PropertyTy = PropertyDecl->getType(); 1964 1965 if (getLangOpts().ObjCAutoRefCount && 1966 (Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1967 PropertyTy->isObjCRetainableType()) { 1968 // 'readonly' property with no obvious lifetime. 1969 // its life time will be determined by its backing ivar. 1970 unsigned rel = (ObjCDeclSpec::DQ_PR_unsafe_unretained | 1971 ObjCDeclSpec::DQ_PR_copy | 1972 ObjCDeclSpec::DQ_PR_retain | 1973 ObjCDeclSpec::DQ_PR_strong | 1974 ObjCDeclSpec::DQ_PR_weak | 1975 ObjCDeclSpec::DQ_PR_assign); 1976 if ((Attributes & rel) == 0) 1977 return; 1978 } 1979 1980 if (propertyInPrimaryClass) { 1981 // we postpone most property diagnosis until class's implementation 1982 // because, its readonly attribute may be overridden in its class 1983 // extensions making other attributes, which make no sense, to make sense. 1984 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1985 (Attributes & ObjCDeclSpec::DQ_PR_readwrite)) 1986 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1987 << "readonly" << "readwrite"; 1988 } 1989 // readonly and readwrite/assign/retain/copy conflict. 1990 else if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1991 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 1992 ObjCDeclSpec::DQ_PR_assign | 1993 ObjCDeclSpec::DQ_PR_unsafe_unretained | 1994 ObjCDeclSpec::DQ_PR_copy | 1995 ObjCDeclSpec::DQ_PR_retain | 1996 ObjCDeclSpec::DQ_PR_strong))) { 1997 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ? 1998 "readwrite" : 1999 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 2000 "assign" : 2001 (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) ? 2002 "unsafe_unretained" : 2003 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 2004 "copy" : "retain"; 2005 2006 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 2007 diag::err_objc_property_attr_mutually_exclusive : 2008 diag::warn_objc_property_attr_mutually_exclusive) 2009 << "readonly" << which; 2010 } 2011 2012 // Check for copy or retain on non-object types. 2013 if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 2014 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) && 2015 !PropertyTy->isObjCRetainableType() && 2016 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { 2017 Diag(Loc, diag::err_objc_property_requires_object) 2018 << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" : 2019 Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)"); 2020 Attributes &= ~(ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 2021 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong); 2022 PropertyDecl->setInvalidDecl(); 2023 } 2024 2025 // Check for more than one of { assign, copy, retain }. 2026 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 2027 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 2028 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2029 << "assign" << "copy"; 2030 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 2031 } 2032 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 2033 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2034 << "assign" << "retain"; 2035 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 2036 } 2037 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 2038 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2039 << "assign" << "strong"; 2040 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 2041 } 2042 if (getLangOpts().ObjCAutoRefCount && 2043 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 2044 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2045 << "assign" << "weak"; 2046 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 2047 } 2048 } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) { 2049 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 2050 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2051 << "unsafe_unretained" << "copy"; 2052 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 2053 } 2054 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 2055 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2056 << "unsafe_unretained" << "retain"; 2057 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 2058 } 2059 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 2060 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2061 << "unsafe_unretained" << "strong"; 2062 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 2063 } 2064 if (getLangOpts().ObjCAutoRefCount && 2065 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 2066 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2067 << "unsafe_unretained" << "weak"; 2068 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 2069 } 2070 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 2071 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 2072 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2073 << "copy" << "retain"; 2074 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 2075 } 2076 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 2077 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2078 << "copy" << "strong"; 2079 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 2080 } 2081 if (Attributes & ObjCDeclSpec::DQ_PR_weak) { 2082 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2083 << "copy" << "weak"; 2084 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 2085 } 2086 } 2087 else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) && 2088 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 2089 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2090 << "retain" << "weak"; 2091 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 2092 } 2093 else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) && 2094 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 2095 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2096 << "strong" << "weak"; 2097 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 2098 } 2099 2100 if ((Attributes & ObjCDeclSpec::DQ_PR_atomic) && 2101 (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)) { 2102 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 2103 << "atomic" << "nonatomic"; 2104 Attributes &= ~ObjCDeclSpec::DQ_PR_atomic; 2105 } 2106 2107 // Warn if user supplied no assignment attribute, property is 2108 // readwrite, and this is an object type. 2109 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | 2110 ObjCDeclSpec::DQ_PR_unsafe_unretained | 2111 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong | 2112 ObjCDeclSpec::DQ_PR_weak)) && 2113 PropertyTy->isObjCObjectPointerType()) { 2114 if (getLangOpts().ObjCAutoRefCount) 2115 // With arc, @property definitions should default to (strong) when 2116 // not specified; including when property is 'readonly'. 2117 PropertyDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 2118 else if (!(Attributes & ObjCDeclSpec::DQ_PR_readonly)) { 2119 bool isAnyClassTy = 2120 (PropertyTy->isObjCClassType() || 2121 PropertyTy->isObjCQualifiedClassType()); 2122 // In non-gc, non-arc mode, 'Class' is treated as a 'void *' no need to 2123 // issue any warning. 2124 if (isAnyClassTy && getLangOpts().getGC() == LangOptions::NonGC) 2125 ; 2126 else { 2127 // Skip this warning in gc-only mode. 2128 if (getLangOpts().getGC() != LangOptions::GCOnly) 2129 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 2130 2131 // If non-gc code warn that this is likely inappropriate. 2132 if (getLangOpts().getGC() == LangOptions::NonGC) 2133 Diag(Loc, diag::warn_objc_property_default_assign_on_object); 2134 } 2135 } 2136 2137 // FIXME: Implement warning dependent on NSCopying being 2138 // implemented. See also: 2139 // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496> 2140 // (please trim this list while you are at it). 2141 } 2142 2143 if (!(Attributes & ObjCDeclSpec::DQ_PR_copy) 2144 &&!(Attributes & ObjCDeclSpec::DQ_PR_readonly) 2145 && getLangOpts().getGC() == LangOptions::GCOnly 2146 && PropertyTy->isBlockPointerType()) 2147 Diag(Loc, diag::warn_objc_property_copy_missing_on_block); 2148 else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) && 2149 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 2150 !(Attributes & ObjCDeclSpec::DQ_PR_strong) && 2151 PropertyTy->isBlockPointerType()) 2152 Diag(Loc, diag::warn_objc_property_retain_of_block); 2153 2154 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 2155 (Attributes & ObjCDeclSpec::DQ_PR_setter)) 2156 Diag(Loc, diag::warn_objc_readonly_property_has_setter); 2157 2158 } 2159