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