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