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