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