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