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