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