SemaObjCProperty.cpp (221345) | SemaObjCProperty.cpp (224145) |
---|---|
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//===----------------------------------------------------------------------===// --- 10 unchanged lines hidden (view full) --- 19#include "llvm/ADT/DenseSet.h" 20 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// Grammar actions. 25//===----------------------------------------------------------------------===// 26 | 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//===----------------------------------------------------------------------===// --- 10 unchanged lines hidden (view full) --- 19#include "llvm/ADT/DenseSet.h" 20 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// Grammar actions. 25//===----------------------------------------------------------------------===// 26 |
27/// Check the internal consistency of a property declaration. 28static void checkARCPropertyDecl(Sema &S, ObjCPropertyDecl *property) { 29 if (property->isInvalidDecl()) return; 30 31 ObjCPropertyDecl::PropertyAttributeKind propertyKind 32 = property->getPropertyAttributes(); 33 Qualifiers::ObjCLifetime propertyLifetime 34 = property->getType().getObjCLifetime(); 35 36 // Nothing to do if we don't have a lifetime. 37 if (propertyLifetime == Qualifiers::OCL_None) return; 38 39 Qualifiers::ObjCLifetime expectedLifetime; 40 unsigned selector; 41 42 // Strong properties should have either strong or no lifetime. 43 if (propertyKind & (ObjCPropertyDecl::OBJC_PR_retain | 44 ObjCPropertyDecl::OBJC_PR_strong | 45 ObjCPropertyDecl::OBJC_PR_copy)) { 46 expectedLifetime = Qualifiers::OCL_Strong; 47 selector = 0; 48 } else if (propertyKind & ObjCPropertyDecl::OBJC_PR_weak) { 49 expectedLifetime = Qualifiers::OCL_Weak; 50 selector = 1; 51 } else if (propertyKind & (ObjCPropertyDecl::OBJC_PR_assign | 52 ObjCPropertyDecl::OBJC_PR_unsafe_unretained) && 53 property->getType()->isObjCRetainableType()) { 54 expectedLifetime = Qualifiers::OCL_ExplicitNone; 55 selector = 2; 56 } else { 57 // We have a lifetime qualifier but no dominating property 58 // attribute. That's okay. 59 return; 60 } 61 62 if (propertyLifetime == expectedLifetime) return; 63 64 property->setInvalidDecl(); 65 S.Diag(property->getLocation(), 66 diag::err_arc_inconsistent_property_ownership) 67 << property->getDeclName() 68 << selector 69 << propertyLifetime; 70} 71 |
|
27Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, 28 FieldDeclarator &FD, 29 ObjCDeclSpec &ODS, 30 Selector GetterSel, 31 Selector SetterSel, 32 Decl *ClassCategory, 33 bool *isOverridingProperty, 34 tok::ObjCKeywordKind MethodImplKind, 35 DeclContext *lexicalDC) { 36 unsigned Attributes = ODS.getPropertyAttributes(); | 72Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, 73 FieldDeclarator &FD, 74 ObjCDeclSpec &ODS, 75 Selector GetterSel, 76 Selector SetterSel, 77 Decl *ClassCategory, 78 bool *isOverridingProperty, 79 tok::ObjCKeywordKind MethodImplKind, 80 DeclContext *lexicalDC) { 81 unsigned Attributes = ODS.getPropertyAttributes(); |
82 TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S); 83 QualType T = TSI->getType(); 84 if ((getLangOptions().getGCMode() != LangOptions::NonGC && 85 T.isObjCGCWeak()) || 86 (getLangOptions().ObjCAutoRefCount && 87 T.getObjCLifetime() == Qualifiers::OCL_Weak)) 88 Attributes |= ObjCDeclSpec::DQ_PR_weak; 89 |
|
37 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) || 38 // default is readwrite! 39 !(Attributes & ObjCDeclSpec::DQ_PR_readonly)); 40 // property is defaulted to 'assign' if it is readwrite and is 41 // not retain or copy 42 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) || 43 (isReadWrite && 44 !(Attributes & ObjCDeclSpec::DQ_PR_retain) && | 90 bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) || 91 // default is readwrite! 92 !(Attributes & ObjCDeclSpec::DQ_PR_readonly)); 93 // property is defaulted to 'assign' if it is readwrite and is 94 // not retain or copy 95 bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) || 96 (isReadWrite && 97 !(Attributes & ObjCDeclSpec::DQ_PR_retain) && |
45 !(Attributes & ObjCDeclSpec::DQ_PR_copy))); | 98 !(Attributes & ObjCDeclSpec::DQ_PR_strong) && 99 !(Attributes & ObjCDeclSpec::DQ_PR_copy) && 100 !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) && 101 !(Attributes & ObjCDeclSpec::DQ_PR_weak))); |
46 | 102 |
47 TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S); 48 | |
49 // Proceed with constructing the ObjCPropertDecls. 50 ObjCContainerDecl *ClassDecl = 51 cast<ObjCContainerDecl>(ClassCategory); 52 53 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) 54 if (CDecl->IsClassExtension()) { 55 Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc, 56 FD, GetterSel, SetterSel, 57 isAssign, isReadWrite, 58 Attributes, 59 isOverridingProperty, TSI, 60 MethodImplKind); | 103 // Proceed with constructing the ObjCPropertDecls. 104 ObjCContainerDecl *ClassDecl = 105 cast<ObjCContainerDecl>(ClassCategory); 106 107 if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) 108 if (CDecl->IsClassExtension()) { 109 Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc, 110 FD, GetterSel, SetterSel, 111 isAssign, isReadWrite, 112 Attributes, 113 isOverridingProperty, TSI, 114 MethodImplKind); |
61 if (Res) | 115 if (Res) { |
62 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); | 116 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); |
117 if (getLangOptions().ObjCAutoRefCount) 118 checkARCPropertyDecl(*this, cast<ObjCPropertyDecl>(Res)); 119 } |
|
63 return Res; 64 } 65 | 120 return Res; 121 } 122 |
66 Decl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, FD, 67 GetterSel, SetterSel, 68 isAssign, isReadWrite, 69 Attributes, TSI, MethodImplKind); | 123 ObjCPropertyDecl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, FD, 124 GetterSel, SetterSel, 125 isAssign, isReadWrite, 126 Attributes, TSI, MethodImplKind); |
70 if (lexicalDC) 71 Res->setLexicalDeclContext(lexicalDC); 72 73 // Validate the attributes on the @property. 74 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); | 127 if (lexicalDC) 128 Res->setLexicalDeclContext(lexicalDC); 129 130 // Validate the attributes on the @property. 131 CheckObjCPropertyAttributes(Res, AtLoc, Attributes); |
132 133 if (getLangOptions().ObjCAutoRefCount) 134 checkARCPropertyDecl(*this, Res); 135 |
|
75 return Res; 76} 77 78Decl * 79Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl, 80 SourceLocation AtLoc, FieldDeclarator &FD, 81 Selector GetterSel, Selector SetterSel, 82 const bool isAssign, --- 30 unchanged lines hidden (view full) --- 113 PropertyId, AtLoc, T); 114 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 115 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 116 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 117 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 118 // Set setter/getter selector name. Needed later. 119 PDecl->setGetterName(GetterSel); 120 PDecl->setSetterName(SetterSel); | 136 return Res; 137} 138 139Decl * 140Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl, 141 SourceLocation AtLoc, FieldDeclarator &FD, 142 Selector GetterSel, Selector SetterSel, 143 const bool isAssign, --- 30 unchanged lines hidden (view full) --- 174 PropertyId, AtLoc, T); 175 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) 176 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 177 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 178 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 179 // Set setter/getter selector name. Needed later. 180 PDecl->setGetterName(GetterSel); 181 PDecl->setSetterName(SetterSel); |
182 ProcessDeclAttributes(S, PDecl, FD.D); |
|
121 DC->addDecl(PDecl); 122 123 // We need to look in the @interface to see if the @property was 124 // already declared. 125 if (!CCPrimary) { 126 Diag(CDecl->getLocation(), diag::err_continuation_class); 127 *isOverridingProperty = true; 128 return 0; --- 5 unchanged lines hidden (view full) --- 134 135 if (!PIDecl) { 136 // No matching property found in the primary class. Just fall thru 137 // and add property to continuation class's primary class. 138 ObjCPropertyDecl *PDecl = 139 CreatePropertyDecl(S, CCPrimary, AtLoc, 140 FD, GetterSel, SetterSel, isAssign, isReadWrite, 141 Attributes, T, MethodImplKind, DC); | 183 DC->addDecl(PDecl); 184 185 // We need to look in the @interface to see if the @property was 186 // already declared. 187 if (!CCPrimary) { 188 Diag(CDecl->getLocation(), diag::err_continuation_class); 189 *isOverridingProperty = true; 190 return 0; --- 5 unchanged lines hidden (view full) --- 196 197 if (!PIDecl) { 198 // No matching property found in the primary class. Just fall thru 199 // and add property to continuation class's primary class. 200 ObjCPropertyDecl *PDecl = 201 CreatePropertyDecl(S, CCPrimary, AtLoc, 202 FD, GetterSel, SetterSel, isAssign, isReadWrite, 203 Attributes, T, MethodImplKind, DC); |
142 // Mark written attribute as having no attribute because 143 // this is not a user-written property declaration in primary 144 // class. 145 PDecl->setPropertyAttributesAsWritten(ObjCPropertyDecl::OBJC_PR_noattr); | |
146 147 // A case of continuation class adding a new property in the class. This 148 // is not what it was meant for. However, gcc supports it and so should we. 149 // Make sure setter/getters are declared here. 150 ProcessPropertyDecl(PDecl, CCPrimary, /* redeclaredProperty = */ 0, 151 /* lexicalDC = */ CDecl); 152 return PDecl; 153 } 154 155 // The property 'PIDecl's readonly attribute will be over-ridden 156 // with continuation class's readwrite property attribute! 157 unsigned PIkind = PIDecl->getPropertyAttributesAsWritten(); 158 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { 159 unsigned retainCopyNonatomic = 160 (ObjCPropertyDecl::OBJC_PR_retain | | 204 205 // A case of continuation class adding a new property in the class. This 206 // is not what it was meant for. However, gcc supports it and so should we. 207 // Make sure setter/getters are declared here. 208 ProcessPropertyDecl(PDecl, CCPrimary, /* redeclaredProperty = */ 0, 209 /* lexicalDC = */ CDecl); 210 return PDecl; 211 } 212 213 // The property 'PIDecl's readonly attribute will be over-ridden 214 // with continuation class's readwrite property attribute! 215 unsigned PIkind = PIDecl->getPropertyAttributesAsWritten(); 216 if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { 217 unsigned retainCopyNonatomic = 218 (ObjCPropertyDecl::OBJC_PR_retain | |
219 ObjCPropertyDecl::OBJC_PR_strong | |
|
161 ObjCPropertyDecl::OBJC_PR_copy | 162 ObjCPropertyDecl::OBJC_PR_nonatomic); 163 if ((Attributes & retainCopyNonatomic) != 164 (PIkind & retainCopyNonatomic)) { 165 Diag(AtLoc, diag::warn_property_attr_mismatch); 166 Diag(PIDecl->getLocation(), diag::note_property_declare); 167 } 168 DeclContext *DC = cast<DeclContext>(CCPrimary); --- 15 unchanged lines hidden (view full) --- 184 CCPrimary, isOverridingProperty, 185 MethodImplKind, 186 /* lexicalDC = */ CDecl); 187 PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy); 188 } 189 PIDecl->makeitReadWriteAttribute(); 190 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 191 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); | 220 ObjCPropertyDecl::OBJC_PR_copy | 221 ObjCPropertyDecl::OBJC_PR_nonatomic); 222 if ((Attributes & retainCopyNonatomic) != 223 (PIkind & retainCopyNonatomic)) { 224 Diag(AtLoc, diag::warn_property_attr_mismatch); 225 Diag(PIDecl->getLocation(), diag::note_property_declare); 226 } 227 DeclContext *DC = cast<DeclContext>(CCPrimary); --- 15 unchanged lines hidden (view full) --- 243 CCPrimary, isOverridingProperty, 244 MethodImplKind, 245 /* lexicalDC = */ CDecl); 246 PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy); 247 } 248 PIDecl->makeitReadWriteAttribute(); 249 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 250 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); |
251 if (Attributes & ObjCDeclSpec::DQ_PR_strong) 252 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); |
|
192 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 193 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 194 PIDecl->setSetterName(SetterSel); 195 } else { 196 // Tailor the diagnostics for the common case where a readwrite 197 // property is declared both in the @interface and the continuation. 198 // This is a common error where the user often intended the original 199 // declaration to be readonly. --- 67 unchanged lines hidden (view full) --- 267 268 ProcessDeclAttributes(S, PDecl, FD.D); 269 270 // Regardless of setter/getter attribute, we save the default getter/setter 271 // selector names in anticipation of declaration of setter/getter methods. 272 PDecl->setGetterName(GetterSel); 273 PDecl->setSetterName(SetterSel); 274 | 253 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 254 PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 255 PIDecl->setSetterName(SetterSel); 256 } else { 257 // Tailor the diagnostics for the common case where a readwrite 258 // property is declared both in the @interface and the continuation. 259 // This is a common error where the user often intended the original 260 // declaration to be readonly. --- 67 unchanged lines hidden (view full) --- 328 329 ProcessDeclAttributes(S, PDecl, FD.D); 330 331 // Regardless of setter/getter attribute, we save the default getter/setter 332 // selector names in anticipation of declaration of setter/getter methods. 333 PDecl->setGetterName(GetterSel); 334 PDecl->setSetterName(SetterSel); 335 |
336 unsigned attributesAsWritten = 0; |
|
275 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) | 337 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) |
338 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readonly; 339 if (Attributes & ObjCDeclSpec::DQ_PR_readwrite) 340 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readwrite; 341 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 342 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_getter; 343 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 344 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_setter; 345 if (Attributes & ObjCDeclSpec::DQ_PR_assign) 346 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_assign; 347 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 348 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_retain; 349 if (Attributes & ObjCDeclSpec::DQ_PR_strong) 350 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_strong; 351 if (Attributes & ObjCDeclSpec::DQ_PR_weak) 352 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_weak; 353 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 354 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_copy; 355 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) 356 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_unsafe_unretained; 357 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 358 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_nonatomic; 359 if (Attributes & ObjCDeclSpec::DQ_PR_atomic) 360 attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_atomic; 361 362 PDecl->setPropertyAttributesAsWritten( 363 (ObjCPropertyDecl::PropertyAttributeKind)attributesAsWritten); 364 365 if (Attributes & ObjCDeclSpec::DQ_PR_readonly) |
|
276 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 277 278 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 279 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter); 280 281 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 282 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter); 283 284 if (isReadWrite) 285 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 286 287 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 288 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 289 | 366 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly); 367 368 if (Attributes & ObjCDeclSpec::DQ_PR_getter) 369 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter); 370 371 if (Attributes & ObjCDeclSpec::DQ_PR_setter) 372 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter); 373 374 if (isReadWrite) 375 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite); 376 377 if (Attributes & ObjCDeclSpec::DQ_PR_retain) 378 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); 379 |
380 if (Attributes & ObjCDeclSpec::DQ_PR_strong) 381 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong); 382 383 if (Attributes & ObjCDeclSpec::DQ_PR_weak) 384 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak); 385 |
|
290 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 291 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 292 | 386 if (Attributes & ObjCDeclSpec::DQ_PR_copy) 387 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy); 388 |
389 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) 390 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained); 391 |
|
293 if (isAssign) 294 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 295 296 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 297 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); 298 else if (Attributes & ObjCDeclSpec::DQ_PR_atomic) 299 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic); 300 | 392 if (isAssign) 393 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 394 395 if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic) 396 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic); 397 else if (Attributes & ObjCDeclSpec::DQ_PR_atomic) 398 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_atomic); 399 |
301 PDecl->setPropertyAttributesAsWritten(PDecl->getPropertyAttributes()); 302 | 400 // 'unsafe_unretained' is alias for 'assign'. 401 if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) 402 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign); 403 if (isAssign) 404 PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_unsafe_unretained); 405 |
303 if (MethodImplKind == tok::objc_required) 304 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required); 305 else if (MethodImplKind == tok::objc_optional) 306 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional); 307 308 return PDecl; 309} 310 | 406 if (MethodImplKind == tok::objc_required) 407 PDecl->setPropertyImplementation(ObjCPropertyDecl::Required); 408 else if (MethodImplKind == tok::objc_optional) 409 PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional); 410 411 return PDecl; 412} 413 |
414static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc, 415 ObjCPropertyDecl *property, 416 ObjCIvarDecl *ivar) { 417 if (property->isInvalidDecl() || ivar->isInvalidDecl()) return; |
|
311 | 418 |
419 QualType propertyType = property->getType(); 420 Qualifiers::ObjCLifetime propertyLifetime = propertyType.getObjCLifetime(); 421 ObjCPropertyDecl::PropertyAttributeKind propertyKind 422 = property->getPropertyAttributes(); 423 424 QualType ivarType = ivar->getType(); 425 Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime(); 426 427 // Case 1: strong properties. 428 if (propertyLifetime == Qualifiers::OCL_Strong || 429 (propertyKind & (ObjCPropertyDecl::OBJC_PR_retain | 430 ObjCPropertyDecl::OBJC_PR_strong | 431 ObjCPropertyDecl::OBJC_PR_copy))) { 432 switch (ivarLifetime) { 433 case Qualifiers::OCL_Strong: 434 // Okay. 435 return; 436 437 case Qualifiers::OCL_None: 438 case Qualifiers::OCL_Autoreleasing: 439 // These aren't valid lifetimes for object ivars; don't diagnose twice. 440 return; 441 442 case Qualifiers::OCL_ExplicitNone: 443 case Qualifiers::OCL_Weak: 444 S.Diag(propertyImplLoc, diag::err_arc_strong_property_ownership) 445 << property->getDeclName() 446 << ivar->getDeclName() 447 << ivarLifetime; 448 break; 449 } 450 451 // Case 2: weak properties. 452 } else if (propertyLifetime == Qualifiers::OCL_Weak || 453 (propertyKind & ObjCPropertyDecl::OBJC_PR_weak)) { 454 switch (ivarLifetime) { 455 case Qualifiers::OCL_Weak: 456 // Okay. 457 return; 458 459 case Qualifiers::OCL_None: 460 case Qualifiers::OCL_Autoreleasing: 461 // These aren't valid lifetimes for object ivars; don't diagnose twice. 462 return; 463 464 case Qualifiers::OCL_ExplicitNone: 465 case Qualifiers::OCL_Strong: 466 S.Diag(propertyImplLoc, diag::error_weak_property) 467 << property->getDeclName() 468 << ivar->getDeclName(); 469 break; 470 } 471 472 // Case 3: assign properties. 473 } else if ((propertyKind & ObjCPropertyDecl::OBJC_PR_assign) && 474 propertyType->isObjCRetainableType()) { 475 switch (ivarLifetime) { 476 case Qualifiers::OCL_ExplicitNone: 477 // Okay. 478 return; 479 480 case Qualifiers::OCL_None: 481 case Qualifiers::OCL_Autoreleasing: 482 // These aren't valid lifetimes for object ivars; don't diagnose twice. 483 return; 484 485 case Qualifiers::OCL_Weak: 486 case Qualifiers::OCL_Strong: 487 S.Diag(propertyImplLoc, diag::err_arc_assign_property_ownership) 488 << property->getDeclName() 489 << ivar->getDeclName(); 490 break; 491 } 492 493 // Any other property should be ignored. 494 } else { 495 return; 496 } 497 498 S.Diag(property->getLocation(), diag::note_property_declare); 499} 500 501 |
|
312/// ActOnPropertyImplDecl - This routine performs semantic checks and 313/// builds the AST node for a property implementation declaration; declared 314/// as @synthesize or @dynamic. 315/// 316Decl *Sema::ActOnPropertyImplDecl(Scope *S, 317 SourceLocation AtLoc, 318 SourceLocation PropertyLoc, 319 bool Synthesize, --- 71 unchanged lines hidden (view full) --- 391 } 392 } else { 393 Diag(AtLoc, diag::error_bad_property_context); 394 return 0; 395 } 396 ObjCIvarDecl *Ivar = 0; 397 // Check that we have a valid, previously declared ivar for @synthesize 398 if (Synthesize) { | 502/// ActOnPropertyImplDecl - This routine performs semantic checks and 503/// builds the AST node for a property implementation declaration; declared 504/// as @synthesize or @dynamic. 505/// 506Decl *Sema::ActOnPropertyImplDecl(Scope *S, 507 SourceLocation AtLoc, 508 SourceLocation PropertyLoc, 509 bool Synthesize, --- 71 unchanged lines hidden (view full) --- 581 } 582 } else { 583 Diag(AtLoc, diag::error_bad_property_context); 584 return 0; 585 } 586 ObjCIvarDecl *Ivar = 0; 587 // Check that we have a valid, previously declared ivar for @synthesize 588 if (Synthesize) { |
589 if (getLangOptions().ObjCAutoRefCount && 590 !property->hasWrittenStorageAttribute() && 591 property->getType()->isObjCRetainableType()) { 592 Diag(PropertyLoc, diag::err_arc_objc_property_default_assign_on_object); 593 Diag(property->getLocation(), diag::note_property_declare); 594 } 595 |
|
399 // @synthesize 400 if (!PropertyIvar) 401 PropertyIvar = PropertyId; | 596 // @synthesize 597 if (!PropertyIvar) 598 PropertyIvar = PropertyId; |
599 ObjCPropertyDecl::PropertyAttributeKind kind 600 = property->getPropertyAttributes(); |
|
402 QualType PropType = Context.getCanonicalType(property->getType()); 403 QualType PropertyIvarType = PropType; 404 if (PropType->isReferenceType()) 405 PropertyIvarType = cast<ReferenceType>(PropType)->getPointeeType(); 406 // Check that this is a previously declared 'ivar' in 'IDecl' interface 407 ObjCInterfaceDecl *ClassDeclared; 408 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared); 409 if (!Ivar) { | 601 QualType PropType = Context.getCanonicalType(property->getType()); 602 QualType PropertyIvarType = PropType; 603 if (PropType->isReferenceType()) 604 PropertyIvarType = cast<ReferenceType>(PropType)->getPointeeType(); 605 // Check that this is a previously declared 'ivar' in 'IDecl' interface 606 ObjCInterfaceDecl *ClassDeclared; 607 Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared); 608 if (!Ivar) { |
609 // In ARC, give the ivar a lifetime qualifier based on its 610 // property attributes. 611 if (getLangOptions().ObjCAutoRefCount && 612 !PropertyIvarType.getObjCLifetime()) { 613 614 // retain/copy have retaining lifetime. 615 if (kind & (ObjCPropertyDecl::OBJC_PR_retain | 616 ObjCPropertyDecl::OBJC_PR_strong | 617 ObjCPropertyDecl::OBJC_PR_copy)) { 618 Qualifiers qs; 619 qs.addObjCLifetime(Qualifiers::OCL_Strong); 620 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs); 621 } 622 else if (kind & ObjCPropertyDecl::OBJC_PR_weak) { 623 if (!getLangOptions().ObjCRuntimeHasWeak) { 624 Diag(PropertyLoc, diag::err_arc_weak_no_runtime); 625 Diag(property->getLocation(), diag::note_property_declare); 626 } 627 Qualifiers qs; 628 qs.addObjCLifetime(Qualifiers::OCL_Weak); 629 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs); 630 } 631 else if (kind & ObjCPropertyDecl::OBJC_PR_assign && 632 PropertyIvarType->isObjCRetainableType()) { 633 // assume that an 'assign' property synthesizes __unsafe_unretained 634 // ivar 635 Qualifiers qs; 636 qs.addObjCLifetime(Qualifiers::OCL_ExplicitNone); 637 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs); 638 } 639 } 640 641 if (kind & ObjCPropertyDecl::OBJC_PR_weak && 642 !getLangOptions().ObjCAutoRefCount && 643 getLangOptions().getGCMode() == LangOptions::NonGC) { 644 Diag(PropertyLoc, diag::error_synthesize_weak_non_arc_or_gc); 645 Diag(property->getLocation(), diag::note_property_declare); 646 } 647 |
|
410 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, 411 PropertyLoc, PropertyLoc, PropertyIvar, 412 PropertyIvarType, /*Dinfo=*/0, 413 ObjCIvarDecl::Private, 414 (Expr *)0, true); 415 ClassImpDecl->addDecl(Ivar); 416 IDecl->makeDeclVisibleInContext(Ivar, false); 417 property->setPropertyIvarDecl(Ivar); --- 12 unchanged lines hidden (view full) --- 430 // Note! I deliberately want it to fall thru so more errors are caught. 431 } 432 QualType IvarType = Context.getCanonicalType(Ivar->getType()); 433 434 // Check that type of property and its ivar are type compatible. 435 if (PropertyIvarType != IvarType) { 436 bool compat = false; 437 if (isa<ObjCObjectPointerType>(PropertyIvarType) | 648 Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, 649 PropertyLoc, PropertyLoc, PropertyIvar, 650 PropertyIvarType, /*Dinfo=*/0, 651 ObjCIvarDecl::Private, 652 (Expr *)0, true); 653 ClassImpDecl->addDecl(Ivar); 654 IDecl->makeDeclVisibleInContext(Ivar, false); 655 property->setPropertyIvarDecl(Ivar); --- 12 unchanged lines hidden (view full) --- 668 // Note! I deliberately want it to fall thru so more errors are caught. 669 } 670 QualType IvarType = Context.getCanonicalType(Ivar->getType()); 671 672 // Check that type of property and its ivar are type compatible. 673 if (PropertyIvarType != IvarType) { 674 bool compat = false; 675 if (isa<ObjCObjectPointerType>(PropertyIvarType) |
438 && isa<ObjCObjectPointerType>(IvarType)) | 676 && isa |
439 compat = 440 Context.canAssignObjCInterfaces( 441 PropertyIvarType->getAs<ObjCObjectPointerType>(), 442 IvarType->getAs<ObjCObjectPointerType>()); 443 else { 444 SourceLocation Loc = PropertyIvarLoc; 445 if (Loc.isInvalid()) 446 Loc = PropertyLoc; --- 18 unchanged lines hidden (view full) --- 465 lhsType->isArithmeticType()) { 466 Diag(PropertyLoc, diag::error_property_ivar_type) 467 << property->getDeclName() << PropType 468 << Ivar->getDeclName() << IvarType; 469 Diag(Ivar->getLocation(), diag::note_ivar_decl); 470 // Fall thru - see previous comment 471 } 472 // __weak is explicit. So it works on Canonical type. | 677 compat = 678 Context.canAssignObjCInterfaces( 679 PropertyIvarType->getAs<ObjCObjectPointerType>(), 680 IvarType->getAs<ObjCObjectPointerType>()); 681 else { 682 SourceLocation Loc = PropertyIvarLoc; 683 if (Loc.isInvalid()) 684 Loc = PropertyLoc; --- 18 unchanged lines hidden (view full) --- 703 lhsType->isArithmeticType()) { 704 Diag(PropertyLoc, diag::error_property_ivar_type) 705 << property->getDeclName() << PropType 706 << Ivar->getDeclName() << IvarType; 707 Diag(Ivar->getLocation(), diag::note_ivar_decl); 708 // Fall thru - see previous comment 709 } 710 // __weak is explicit. So it works on Canonical type. |
473 if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() && 474 getLangOptions().getGCMode() != LangOptions::NonGC) { | 711 if ((PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() && 712 getLangOptions().getGCMode() != LangOptions::NonGC)) { |
475 Diag(PropertyLoc, diag::error_weak_property) 476 << property->getDeclName() << Ivar->getDeclName(); 477 // Fall thru - see previous comment 478 } | 713 Diag(PropertyLoc, diag::error_weak_property) 714 << property->getDeclName() << Ivar->getDeclName(); 715 // Fall thru - see previous comment 716 } |
717 // Fall thru - see previous comment |
|
479 if ((property->getType()->isObjCObjectPointerType() || 480 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() && 481 getLangOptions().getGCMode() != LangOptions::NonGC) { 482 Diag(PropertyLoc, diag::error_strong_property) 483 << property->getDeclName() << Ivar->getDeclName(); 484 // Fall thru - see previous comment 485 } 486 } | 718 if ((property->getType()->isObjCObjectPointerType() || 719 PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() && 720 getLangOptions().getGCMode() != LangOptions::NonGC) { 721 Diag(PropertyLoc, diag::error_strong_property) 722 << property->getDeclName() << Ivar->getDeclName(); 723 // Fall thru - see previous comment 724 } 725 } |
726 if (getLangOptions().ObjCAutoRefCount) 727 checkARCPropertyImpl(*this, PropertyLoc, property, Ivar); |
|
487 } else if (PropertyIvar) 488 // @dynamic 489 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl); | 728 } else if (PropertyIvar) 729 // @dynamic 730 Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl); |
731 |
|
490 assert (property && "ActOnPropertyImplDecl - property declaration missing"); 491 ObjCPropertyImplDecl *PIDecl = 492 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, 493 property, 494 (Synthesize ? 495 ObjCPropertyImplDecl::Synthesize 496 : ObjCPropertyImplDecl::Dynamic), 497 Ivar, PropertyIvarLoc); --- 20 unchanged lines hidden (view full) --- 518 Owned(IvarRefExpr)); 519 if (!Res.isInvalid()) { 520 Expr *ResExpr = Res.takeAs<Expr>(); 521 if (ResExpr) 522 ResExpr = MaybeCreateExprWithCleanups(ResExpr); 523 PIDecl->setGetterCXXConstructor(ResExpr); 524 } 525 } | 732 assert (property && "ActOnPropertyImplDecl - property declaration missing"); 733 ObjCPropertyImplDecl *PIDecl = 734 ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc, 735 property, 736 (Synthesize ? 737 ObjCPropertyImplDecl::Synthesize 738 : ObjCPropertyImplDecl::Dynamic), 739 Ivar, PropertyIvarLoc); --- 20 unchanged lines hidden (view full) --- 760 Owned(IvarRefExpr)); 761 if (!Res.isInvalid()) { 762 Expr *ResExpr = Res.takeAs<Expr>(); 763 if (ResExpr) 764 ResExpr = MaybeCreateExprWithCleanups(ResExpr); 765 PIDecl->setGetterCXXConstructor(ResExpr); 766 } 767 } |
768 if (property->hasAttr<NSReturnsNotRetainedAttr>() && 769 !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) { 770 Diag(getterMethod->getLocation(), 771 diag::warn_property_getter_owning_mismatch); 772 Diag(property->getLocation(), diag::note_property_declare); 773 } |
|
526 } 527 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) { 528 setterMethod->createImplicitParams(Context, IDecl); 529 if (getLangOptions().CPlusPlus && Synthesize 530 && Ivar->getType()->isRecordType()) { 531 // FIXME. Eventually we want to do this for Objective-C as well. 532 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); 533 DeclRefExpr *SelfExpr = --- 93 unchanged lines hidden (view full) --- 627 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) 628 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) 629 Diag(Property->getLocation(), diag::warn_readonly_property) 630 << Property->getDeclName() << inheritedName; 631 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) 632 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) 633 Diag(Property->getLocation(), diag::warn_property_attribute) 634 << Property->getDeclName() << "copy" << inheritedName; | 774 } 775 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) { 776 setterMethod->createImplicitParams(Context, IDecl); 777 if (getLangOptions().CPlusPlus && Synthesize 778 && Ivar->getType()->isRecordType()) { 779 // FIXME. Eventually we want to do this for Objective-C as well. 780 ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); 781 DeclRefExpr *SelfExpr = --- 93 unchanged lines hidden (view full) --- 875 if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) 876 && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) 877 Diag(Property->getLocation(), diag::warn_readonly_property) 878 << Property->getDeclName() << inheritedName; 879 if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) 880 != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) 881 Diag(Property->getLocation(), diag::warn_property_attribute) 882 << Property->getDeclName() << "copy" << inheritedName; |
635 else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain) 636 != (SAttr & ObjCPropertyDecl::OBJC_PR_retain)) 637 Diag(Property->getLocation(), diag::warn_property_attribute) 638 << Property->getDeclName() << "retain" << inheritedName; | 883 else { 884 unsigned CAttrRetain = 885 (CAttr & 886 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 887 unsigned SAttrRetain = 888 (SAttr & 889 (ObjCPropertyDecl::OBJC_PR_retain | ObjCPropertyDecl::OBJC_PR_strong)); 890 bool CStrong = (CAttrRetain != 0); 891 bool SStrong = (SAttrRetain != 0); 892 if (CStrong != SStrong) 893 Diag(Property->getLocation(), diag::warn_property_attribute) 894 << Property->getDeclName() << "retain (or strong)" << inheritedName; 895 } |
639 640 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) 641 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) 642 Diag(Property->getLocation(), diag::warn_property_attribute) 643 << Property->getDeclName() << "atomic" << inheritedName; 644 if (Property->getSetterName() != SuperProperty->getSetterName()) 645 Diag(Property->getLocation(), diag::warn_property_attribute) 646 << Property->getDeclName() << "setter" << inheritedName; 647 if (Property->getGetterName() != SuperProperty->getGetterName()) 648 Diag(Property->getLocation(), diag::warn_property_attribute) 649 << Property->getDeclName() << "getter" << inheritedName; 650 651 QualType LHSType = 652 Context.getCanonicalType(SuperProperty->getType()); 653 QualType RHSType = 654 Context.getCanonicalType(Property->getType()); 655 | 896 897 if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) 898 != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) 899 Diag(Property->getLocation(), diag::warn_property_attribute) 900 << Property->getDeclName() << "atomic" << inheritedName; 901 if (Property->getSetterName() != SuperProperty->getSetterName()) 902 Diag(Property->getLocation(), diag::warn_property_attribute) 903 << Property->getDeclName() << "setter" << inheritedName; 904 if (Property->getGetterName() != SuperProperty->getGetterName()) 905 Diag(Property->getLocation(), diag::warn_property_attribute) 906 << Property->getDeclName() << "getter" << inheritedName; 907 908 QualType LHSType = 909 Context.getCanonicalType(SuperProperty->getType()); 910 QualType RHSType = 911 Context.getCanonicalType(Property->getType()); 912 |
656 if (!Context.typesAreCompatible(LHSType, RHSType)) { 657 // FIXME: Incorporate this test with typesAreCompatible. 658 if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType()) 659 if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false)) 660 return; 661 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) 662 << Property->getType() << SuperProperty->getType() << inheritedName; | 913 if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) { 914 // Do cases not handled in above. 915 // FIXME. For future support of covariant property types, revisit this. 916 bool IncompatibleObjC = false; 917 QualType ConvertedType; 918 if (!isObjCPointerConversion(RHSType, LHSType, 919 ConvertedType, IncompatibleObjC) || 920 IncompatibleObjC) 921 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible) 922 << Property->getType() << SuperProperty->getType() << inheritedName; |
663 } 664} 665 666bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, 667 ObjCMethodDecl *GetterMethod, 668 SourceLocation Loc) { 669 if (GetterMethod && 670 GetterMethod->getResultType() != property->getType()) { --- 374 unchanged lines hidden (view full) --- 1045 PropImplMap.insert((*I)->getPropertyDecl()); 1046 1047 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 1048 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1049 ObjCPropertyDecl *Prop = P->second; 1050 // Is there a matching propery synthesize/dynamic? 1051 if (Prop->isInvalidDecl() || 1052 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || | 923 } 924} 925 926bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, 927 ObjCMethodDecl *GetterMethod, 928 SourceLocation Loc) { 929 if (GetterMethod && 930 GetterMethod->getResultType() != property->getType()) { --- 374 unchanged lines hidden (view full) --- 1305 PropImplMap.insert((*I)->getPropertyDecl()); 1306 1307 for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator 1308 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { 1309 ObjCPropertyDecl *Prop = P->second; 1310 // Is there a matching propery synthesize/dynamic? 1311 if (Prop->isInvalidDecl() || 1312 Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional || |
1053 PropImplMap.count(Prop)) | 1313 PropImplMap.count(Prop) || Prop->hasAttr<UnavailableAttr>()) |
1054 continue; 1055 if (!InsMap.count(Prop->getGetterName())) { 1056 Diag(Prop->getLocation(), 1057 isa<ObjCCategoryDecl>(CDecl) ? 1058 diag::warn_setter_getter_impl_required_in_category : 1059 diag::warn_setter_getter_impl_required) 1060 << Prop->getDeclName() << Prop->getGetterName(); 1061 Diag(IMPDecl->getLocation(), --- 68 unchanged lines hidden (view full) --- 1130 Diag(MethodLoc, diag::warn_atomic_property_rule) 1131 << Property->getIdentifier(); 1132 Diag(Property->getLocation(), diag::note_property_declare); 1133 } 1134 } 1135 } 1136} 1137 | 1314 continue; 1315 if (!InsMap.count(Prop->getGetterName())) { 1316 Diag(Prop->getLocation(), 1317 isa<ObjCCategoryDecl>(CDecl) ? 1318 diag::warn_setter_getter_impl_required_in_category : 1319 diag::warn_setter_getter_impl_required) 1320 << Prop->getDeclName() << Prop->getGetterName(); 1321 Diag(IMPDecl->getLocation(), --- 68 unchanged lines hidden (view full) --- 1390 Diag(MethodLoc, diag::warn_atomic_property_rule) 1391 << Property->getIdentifier(); 1392 Diag(Property->getLocation(), diag::note_property_declare); 1393 } 1394 } 1395 } 1396} 1397 |
1398void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D) { 1399 if (getLangOptions().getGCMode() == LangOptions::GCOnly) 1400 return; 1401 1402 for (ObjCImplementationDecl::propimpl_iterator 1403 i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) { 1404 ObjCPropertyImplDecl *PID = *i; 1405 if (PID->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) 1406 continue; 1407 1408 const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 1409 if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() && 1410 !D->getInstanceMethod(PD->getGetterName())) { 1411 ObjCMethodDecl *method = PD->getGetterMethodDecl(); 1412 if (!method) 1413 continue; 1414 ObjCMethodFamily family = method->getMethodFamily(); 1415 if (family == OMF_alloc || family == OMF_copy || 1416 family == OMF_mutableCopy || family == OMF_new) { 1417 if (getLangOptions().ObjCAutoRefCount) 1418 Diag(PID->getLocation(), diag::err_ownin_getter_rule); 1419 else 1420 Diag(PID->getLocation(), diag::warn_ownin_getter_rule); 1421 Diag(PD->getLocation(), diag::note_property_declare); 1422 } 1423 } 1424 } 1425} 1426 |
|
1138/// AddPropertyAttrs - Propagates attributes from a property to the 1139/// implicitly-declared getter or setter for that property. 1140static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, 1141 ObjCPropertyDecl *Property) { 1142 // Should we just clone all attributes over? 1143 for (Decl::attr_iterator A = Property->attr_begin(), 1144 AEnd = Property->attr_end(); 1145 A != AEnd; ++A) { --- 63 unchanged lines hidden (view full) --- 1209 CD->addDecl(GetterMethod); 1210 1211 AddPropertyAttrs(*this, GetterMethod, property); 1212 1213 // FIXME: Eventually this shouldn't be needed, as the lexical context 1214 // and the real context should be the same. 1215 if (lexicalDC) 1216 GetterMethod->setLexicalDeclContext(lexicalDC); | 1427/// AddPropertyAttrs - Propagates attributes from a property to the 1428/// implicitly-declared getter or setter for that property. 1429static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, 1430 ObjCPropertyDecl *Property) { 1431 // Should we just clone all attributes over? 1432 for (Decl::attr_iterator A = Property->attr_begin(), 1433 AEnd = Property->attr_end(); 1434 A != AEnd; ++A) { --- 63 unchanged lines hidden (view full) --- 1498 CD->addDecl(GetterMethod); 1499 1500 AddPropertyAttrs(*this, GetterMethod, property); 1501 1502 // FIXME: Eventually this shouldn't be needed, as the lexical context 1503 // and the real context should be the same. 1504 if (lexicalDC) 1505 GetterMethod->setLexicalDeclContext(lexicalDC); |
1506 if (property->hasAttr<NSReturnsNotRetainedAttr>()) 1507 GetterMethod->addAttr( 1508 ::new (Context) NSReturnsNotRetainedAttr(Loc, Context)); |
|
1217 } else 1218 // A user declared getter will be synthesize when @synthesize of 1219 // the property with the same name is seen in the @implementation 1220 GetterMethod->setSynthesized(true); 1221 property->setGetterMethodDecl(GetterMethod); 1222 1223 // Skip setter if property is read-only. 1224 if (!property->isReadOnly()) { --- 15 unchanged lines hidden (view full) --- 1240 ObjCMethodDecl::Optional : 1241 ObjCMethodDecl::Required); 1242 1243 // Invent the arguments for the setter. We don't bother making a 1244 // nice name for the argument. 1245 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, 1246 Loc, Loc, 1247 property->getIdentifier(), | 1509 } else 1510 // A user declared getter will be synthesize when @synthesize of 1511 // the property with the same name is seen in the @implementation 1512 GetterMethod->setSynthesized(true); 1513 property->setGetterMethodDecl(GetterMethod); 1514 1515 // Skip setter if property is read-only. 1516 if (!property->isReadOnly()) { --- 15 unchanged lines hidden (view full) --- 1532 ObjCMethodDecl::Optional : 1533 ObjCMethodDecl::Required); 1534 1535 // Invent the arguments for the setter. We don't bother making a 1536 // nice name for the argument. 1537 ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod, 1538 Loc, Loc, 1539 property->getIdentifier(), |
1248 property->getType(), | 1540 property->getType().getUnqualifiedType(), |
1249 /*TInfo=*/0, 1250 SC_None, 1251 SC_None, 1252 0); 1253 SetterMethod->setMethodParams(Context, &Argument, 1, 1); 1254 1255 AddPropertyAttrs(*this, SetterMethod, property); 1256 --- 25 unchanged lines hidden (view full) --- 1282 if (SetterMethod) 1283 AddInstanceMethodToGlobalPool(SetterMethod); 1284} 1285 1286void Sema::CheckObjCPropertyAttributes(Decl *PDecl, 1287 SourceLocation Loc, 1288 unsigned &Attributes) { 1289 // FIXME: Improve the reported location. | 1541 /*TInfo=*/0, 1542 SC_None, 1543 SC_None, 1544 0); 1545 SetterMethod->setMethodParams(Context, &Argument, 1, 1); 1546 1547 AddPropertyAttrs(*this, SetterMethod, property); 1548 --- 25 unchanged lines hidden (view full) --- 1574 if (SetterMethod) 1575 AddInstanceMethodToGlobalPool(SetterMethod); 1576} 1577 1578void Sema::CheckObjCPropertyAttributes(Decl *PDecl, 1579 SourceLocation Loc, 1580 unsigned &Attributes) { 1581 // FIXME: Improve the reported location. |
1290 if (!PDecl) | 1582 if (!PDecl || PDecl->isInvalidDecl()) |
1291 return; 1292 1293 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 1294 QualType PropertyTy = PropertyDecl->getType(); 1295 1296 // readonly and readwrite/assign/retain/copy conflict. 1297 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1298 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 1299 ObjCDeclSpec::DQ_PR_assign | | 1583 return; 1584 1585 ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl); 1586 QualType PropertyTy = PropertyDecl->getType(); 1587 1588 // readonly and readwrite/assign/retain/copy conflict. 1589 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1590 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite | 1591 ObjCDeclSpec::DQ_PR_assign | |
1592 ObjCDeclSpec::DQ_PR_unsafe_unretained | |
|
1300 ObjCDeclSpec::DQ_PR_copy | | 1593 ObjCDeclSpec::DQ_PR_copy | |
1301 ObjCDeclSpec::DQ_PR_retain))) { | 1594 ObjCDeclSpec::DQ_PR_retain | 1595 ObjCDeclSpec::DQ_PR_strong))) { |
1302 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ? 1303 "readwrite" : 1304 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 1305 "assign" : | 1596 const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ? 1597 "readwrite" : 1598 (Attributes & ObjCDeclSpec::DQ_PR_assign) ? 1599 "assign" : |
1600 (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) ? 1601 "unsafe_unretained" : |
|
1306 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 1307 "copy" : "retain"; 1308 1309 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 1310 diag::err_objc_property_attr_mutually_exclusive : 1311 diag::warn_objc_property_attr_mutually_exclusive) 1312 << "readonly" << which; 1313 } 1314 1315 // Check for copy or retain on non-object types. | 1602 (Attributes & ObjCDeclSpec::DQ_PR_copy) ? 1603 "copy" : "retain"; 1604 1605 Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 1606 diag::err_objc_property_attr_mutually_exclusive : 1607 diag::warn_objc_property_attr_mutually_exclusive) 1608 << "readonly" << which; 1609 } 1610 1611 // Check for copy or retain on non-object types. |
1316 if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) && 1317 !PropertyTy->isObjCObjectPointerType() && 1318 !PropertyTy->isBlockPointerType() && 1319 !Context.isObjCNSObjectType(PropertyTy) && | 1612 if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 1613 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) && 1614 !PropertyTy->isObjCRetainableType() && |
1320 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { 1321 Diag(Loc, diag::err_objc_property_requires_object) | 1615 !PropertyDecl->getAttr<ObjCNSObjectAttr>()) { 1616 Diag(Loc, diag::err_objc_property_requires_object) |
1322 << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain"); 1323 Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain); | 1617 << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" : 1618 Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)"); 1619 Attributes &= ~(ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy | 1620 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong); |
1324 } 1325 1326 // Check for more than one of { assign, copy, retain }. 1327 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 1328 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1329 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1330 << "assign" << "copy"; 1331 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1332 } 1333 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1334 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1335 << "assign" << "retain"; 1336 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1337 } | 1621 } 1622 1623 // Check for more than one of { assign, copy, retain }. 1624 if (Attributes & ObjCDeclSpec::DQ_PR_assign) { 1625 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1626 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1627 << "assign" << "copy"; 1628 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1629 } 1630 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1631 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1632 << "assign" << "retain"; 1633 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1634 } |
1635 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 1636 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1637 << "assign" << "strong"; 1638 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 1639 } 1640 if (getLangOptions().ObjCAutoRefCount && 1641 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1642 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1643 << "assign" << "weak"; 1644 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1645 } 1646 } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) { 1647 if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1648 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1649 << "unsafe_unretained" << "copy"; 1650 Attributes &= ~ObjCDeclSpec::DQ_PR_copy; 1651 } 1652 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1653 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1654 << "unsafe_unretained" << "retain"; 1655 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1656 } 1657 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 1658 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1659 << "unsafe_unretained" << "strong"; 1660 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 1661 } 1662 if (getLangOptions().ObjCAutoRefCount && 1663 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1664 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1665 << "unsafe_unretained" << "weak"; 1666 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1667 } |
|
1338 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1339 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1340 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1341 << "copy" << "retain"; 1342 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1343 } | 1668 } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) { 1669 if (Attributes & ObjCDeclSpec::DQ_PR_retain) { 1670 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1671 << "copy" << "retain"; 1672 Attributes &= ~ObjCDeclSpec::DQ_PR_retain; 1673 } |
1674 if (Attributes & ObjCDeclSpec::DQ_PR_strong) { 1675 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1676 << "copy" << "strong"; 1677 Attributes &= ~ObjCDeclSpec::DQ_PR_strong; 1678 } 1679 if (Attributes & ObjCDeclSpec::DQ_PR_weak) { 1680 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1681 << "copy" << "weak"; 1682 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1683 } |
|
1344 } | 1684 } |
1685 else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) && 1686 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1687 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1688 << "retain" << "weak"; 1689 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1690 } 1691 else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) && 1692 (Attributes & ObjCDeclSpec::DQ_PR_weak)) { 1693 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) 1694 << "strong" << "weak"; 1695 Attributes &= ~ObjCDeclSpec::DQ_PR_weak; 1696 } |
|
1345 1346 // Warn if user supplied no assignment attribute, property is 1347 // readwrite, and this is an object type. 1348 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | | 1697 1698 // Warn if user supplied no assignment attribute, property is 1699 // readwrite, and this is an object type. 1700 if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy | |
1349 ObjCDeclSpec::DQ_PR_retain)) && | 1701 ObjCDeclSpec::DQ_PR_unsafe_unretained | 1702 ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong | 1703 ObjCDeclSpec::DQ_PR_weak)) && |
1350 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1351 PropertyTy->isObjCObjectPointerType()) { 1352 // Skip this warning in gc-only mode. 1353 if (getLangOptions().getGCMode() != LangOptions::GCOnly) 1354 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 1355 1356 // If non-gc code warn that this is likely inappropriate. 1357 if (getLangOptions().getGCMode() == LangOptions::NonGC) --- 14 unchanged lines hidden --- | 1704 !(Attributes & ObjCDeclSpec::DQ_PR_readonly) && 1705 PropertyTy->isObjCObjectPointerType()) { 1706 // Skip this warning in gc-only mode. 1707 if (getLangOptions().getGCMode() != LangOptions::GCOnly) 1708 Diag(Loc, diag::warn_objc_property_no_assignment_attribute); 1709 1710 // If non-gc code warn that this is likely inappropriate. 1711 if (getLangOptions().getGCMode() == LangOptions::NonGC) --- 14 unchanged lines hidden --- |