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