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