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