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