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