]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Sema/SemaObjCProperty.cpp
Update clang to r104832.
[FreeBSD/FreeBSD.git] / lib / Sema / SemaObjCProperty.cpp
1 //===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file implements semantic analysis for Objective C @property and
11 //  @synthesize declarations.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "Sema.h"
16 #include "SemaInit.h"
17 #include "clang/AST/ExprObjC.h"
18
19 using namespace clang;
20
21 //===----------------------------------------------------------------------===//
22 // Grammar actions.
23 //===----------------------------------------------------------------------===//
24
25 Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
26                                     FieldDeclarator &FD,
27                                     ObjCDeclSpec &ODS,
28                                     Selector GetterSel,
29                                     Selector SetterSel,
30                                     DeclPtrTy ClassCategory,
31                                     bool *isOverridingProperty,
32                                     tok::ObjCKeywordKind MethodImplKind) {
33   unsigned Attributes = ODS.getPropertyAttributes();
34   bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
35                       // default is readwrite!
36                       !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
37   // property is defaulted to 'assign' if it is readwrite and is
38   // not retain or copy
39   bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
40                    (isReadWrite &&
41                     !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
42                     !(Attributes & ObjCDeclSpec::DQ_PR_copy)));
43
44   QualType T = GetTypeForDeclarator(FD.D, S);
45   if (T->isReferenceType()) {
46     Diag(AtLoc, diag::error_reference_property);
47     return DeclPtrTy();
48   }
49   // Proceed with constructing the ObjCPropertDecls.
50   ObjCContainerDecl *ClassDecl =
51     cast<ObjCContainerDecl>(ClassCategory.getAs<Decl>());
52
53   if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
54     if (CDecl->IsClassExtension())
55       return HandlePropertyInClassExtension(S, CDecl, AtLoc,
56                                             FD, GetterSel, SetterSel,
57                                             isAssign, isReadWrite,
58                                             Attributes,
59                                             isOverridingProperty, T,
60                                             MethodImplKind);
61
62   DeclPtrTy Res =  DeclPtrTy::make(CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
63                                             GetterSel, SetterSel,
64                                             isAssign, isReadWrite,
65                                             Attributes, T, MethodImplKind));
66   // Validate the attributes on the @property.
67   CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
68   return Res;
69 }
70
71 Sema::DeclPtrTy
72 Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
73                                      SourceLocation AtLoc, FieldDeclarator &FD,
74                                      Selector GetterSel, Selector SetterSel,
75                                      const bool isAssign,
76                                      const bool isReadWrite,
77                                      const unsigned Attributes,
78                                      bool *isOverridingProperty,
79                                      QualType T,
80                                      tok::ObjCKeywordKind MethodImplKind) {
81
82   // Diagnose if this property is already in continuation class.
83   DeclContext *DC = cast<DeclContext>(CDecl);
84   IdentifierInfo *PropertyId = FD.D.getIdentifier();
85
86   if (ObjCPropertyDecl *prevDecl =
87         ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
88     Diag(AtLoc, diag::err_duplicate_property);
89     Diag(prevDecl->getLocation(), diag::note_property_declare);
90     return DeclPtrTy();
91   }
92
93   // Create a new ObjCPropertyDecl with the DeclContext being
94   // the class extension.
95   ObjCPropertyDecl *PDecl =
96     ObjCPropertyDecl::Create(Context, DC, FD.D.getIdentifierLoc(),
97                              PropertyId, AtLoc, T);
98   if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
99     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
100   if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
101     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
102
103   DC->addDecl(PDecl);
104
105   // We need to look in the @interface to see if the @property was
106   // already declared.
107   ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface();
108   if (!CCPrimary) {
109     Diag(CDecl->getLocation(), diag::err_continuation_class);
110     *isOverridingProperty = true;
111     return DeclPtrTy();
112   }
113
114   // Find the property in continuation class's primary class only.
115   ObjCPropertyDecl *PIDecl =
116     CCPrimary->FindPropertyVisibleInPrimaryClass(PropertyId);
117
118   if (!PIDecl) {
119     // No matching property found in the primary class. Just fall thru
120     // and add property to continuation class's primary class.
121     ObjCPropertyDecl *PDecl =
122       CreatePropertyDecl(S, CCPrimary, AtLoc,
123                          FD, GetterSel, SetterSel, isAssign, isReadWrite,
124                          Attributes, T, MethodImplKind, DC);
125
126     // A case of continuation class adding a new property in the class. This
127     // is not what it was meant for. However, gcc supports it and so should we.
128     // Make sure setter/getters are declared here.
129     ProcessPropertyDecl(PDecl, CCPrimary);
130     return DeclPtrTy::make(PDecl);
131
132   }
133
134   // The property 'PIDecl's readonly attribute will be over-ridden
135   // with continuation class's readwrite property attribute!
136   unsigned PIkind = PIDecl->getPropertyAttributes();
137   if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
138     unsigned retainCopyNonatomic =
139     (ObjCPropertyDecl::OBJC_PR_retain |
140      ObjCPropertyDecl::OBJC_PR_copy |
141      ObjCPropertyDecl::OBJC_PR_nonatomic);
142     if ((Attributes & retainCopyNonatomic) !=
143         (PIkind & retainCopyNonatomic)) {
144       Diag(AtLoc, diag::warn_property_attr_mismatch);
145       Diag(PIDecl->getLocation(), diag::note_property_declare);
146     }
147     DeclContext *DC = cast<DeclContext>(CCPrimary);
148     if (!ObjCPropertyDecl::findPropertyDecl(DC,
149                                  PIDecl->getDeclName().getAsIdentifierInfo())) {
150       // Protocol is not in the primary class. Must build one for it.
151       ObjCDeclSpec ProtocolPropertyODS;
152       // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind
153       // and ObjCPropertyDecl::PropertyAttributeKind have identical
154       // values.  Should consolidate both into one enum type.
155       ProtocolPropertyODS.
156       setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind)
157                             PIkind);
158
159       DeclPtrTy ProtocolPtrTy =
160         ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS,
161                       PIDecl->getGetterName(),
162                       PIDecl->getSetterName(),
163                       DeclPtrTy::make(CCPrimary), isOverridingProperty,
164                       MethodImplKind);
165       PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy.getAs<Decl>());
166     }
167     PIDecl->makeitReadWriteAttribute();
168     if (Attributes & ObjCDeclSpec::DQ_PR_retain)
169       PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
170     if (Attributes & ObjCDeclSpec::DQ_PR_copy)
171       PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
172     PIDecl->setSetterName(SetterSel);
173   } else {
174     Diag(AtLoc, diag::err_use_continuation_class)
175       << CCPrimary->getDeclName();
176     Diag(PIDecl->getLocation(), diag::note_property_declare);
177   }
178   *isOverridingProperty = true;
179   // Make sure setter decl is synthesized, and added to primary class's list.
180   ProcessPropertyDecl(PIDecl, CCPrimary);
181   return DeclPtrTy();
182 }
183
184 ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
185                                            ObjCContainerDecl *CDecl,
186                                            SourceLocation AtLoc,
187                                            FieldDeclarator &FD,
188                                            Selector GetterSel,
189                                            Selector SetterSel,
190                                            const bool isAssign,
191                                            const bool isReadWrite,
192                                            const unsigned Attributes,
193                                            QualType T,
194                                            tok::ObjCKeywordKind MethodImplKind,
195                                            DeclContext *lexicalDC){
196
197   IdentifierInfo *PropertyId = FD.D.getIdentifier();
198
199   // Issue a warning if property is 'assign' as default and its object, which is
200   // gc'able conforms to NSCopying protocol
201   if (getLangOptions().getGCMode() != LangOptions::NonGC &&
202       isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign))
203     if (const ObjCObjectPointerType *ObjPtrTy =
204           T->getAs<ObjCObjectPointerType>()) {
205       ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
206       if (IDecl)
207         if (ObjCProtocolDecl* PNSCopying =
208             LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc))
209           if (IDecl->ClassImplementsProtocol(PNSCopying, true))
210             Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
211     }
212   if (T->isObjCObjectType())
213     Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object);
214
215   DeclContext *DC = cast<DeclContext>(CDecl);
216   ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC,
217                                                      FD.D.getIdentifierLoc(),
218                                                      PropertyId, AtLoc, T);
219
220   if (ObjCPropertyDecl *prevDecl =
221         ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
222     Diag(PDecl->getLocation(), diag::err_duplicate_property);
223     Diag(prevDecl->getLocation(), diag::note_property_declare);
224     PDecl->setInvalidDecl();
225   }
226   else {
227     DC->addDecl(PDecl);
228     if (lexicalDC)
229       PDecl->setLexicalDeclContext(lexicalDC);
230   }
231
232   if (T->isArrayType() || T->isFunctionType()) {
233     Diag(AtLoc, diag::err_property_type) << T;
234     PDecl->setInvalidDecl();
235   }
236
237   ProcessDeclAttributes(S, PDecl, FD.D);
238
239   // Regardless of setter/getter attribute, we save the default getter/setter
240   // selector names in anticipation of declaration of setter/getter methods.
241   PDecl->setGetterName(GetterSel);
242   PDecl->setSetterName(SetterSel);
243
244   if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
245     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
246
247   if (Attributes & ObjCDeclSpec::DQ_PR_getter)
248     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_getter);
249
250   if (Attributes & ObjCDeclSpec::DQ_PR_setter)
251     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_setter);
252
253   if (isReadWrite)
254     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readwrite);
255
256   if (Attributes & ObjCDeclSpec::DQ_PR_retain)
257     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain);
258
259   if (Attributes & ObjCDeclSpec::DQ_PR_copy)
260     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
261
262   if (isAssign)
263     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_assign);
264
265   if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
266     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
267
268   if (MethodImplKind == tok::objc_required)
269     PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
270   else if (MethodImplKind == tok::objc_optional)
271     PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
272
273   return PDecl;
274 }
275
276
277 /// ActOnPropertyImplDecl - This routine performs semantic checks and
278 /// builds the AST node for a property implementation declaration; declared
279 /// as @synthesize or @dynamic.
280 ///
281 Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
282                                             SourceLocation AtLoc,
283                                             SourceLocation PropertyLoc,
284                                             bool Synthesize,
285                                             DeclPtrTy ClassCatImpDecl,
286                                             IdentifierInfo *PropertyId,
287                                             IdentifierInfo *PropertyIvar) {
288   ObjCContainerDecl *ClassImpDecl =
289     cast_or_null<ObjCContainerDecl>(ClassCatImpDecl.getAs<Decl>());
290   // Make sure we have a context for the property implementation declaration.
291   if (!ClassImpDecl) {
292     Diag(AtLoc, diag::error_missing_property_context);
293     return DeclPtrTy();
294   }
295   ObjCPropertyDecl *property = 0;
296   ObjCInterfaceDecl* IDecl = 0;
297   // Find the class or category class where this property must have
298   // a declaration.
299   ObjCImplementationDecl *IC = 0;
300   ObjCCategoryImplDecl* CatImplClass = 0;
301   if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
302     IDecl = IC->getClassInterface();
303     // We always synthesize an interface for an implementation
304     // without an interface decl. So, IDecl is always non-zero.
305     assert(IDecl &&
306            "ActOnPropertyImplDecl - @implementation without @interface");
307
308     // Look for this property declaration in the @implementation's @interface
309     property = IDecl->FindPropertyDeclaration(PropertyId);
310     if (!property) {
311       Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
312       return DeclPtrTy();
313     }
314     if (const ObjCCategoryDecl *CD =
315         dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
316       if (!CD->IsClassExtension()) {
317         Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName();
318         Diag(property->getLocation(), diag::note_property_declare);
319         return DeclPtrTy();
320       }
321     }
322   } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
323     if (Synthesize) {
324       Diag(AtLoc, diag::error_synthesize_category_decl);
325       return DeclPtrTy();
326     }
327     IDecl = CatImplClass->getClassInterface();
328     if (!IDecl) {
329       Diag(AtLoc, diag::error_missing_property_interface);
330       return DeclPtrTy();
331     }
332     ObjCCategoryDecl *Category =
333     IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
334
335     // If category for this implementation not found, it is an error which
336     // has already been reported eralier.
337     if (!Category)
338       return DeclPtrTy();
339     // Look for this property declaration in @implementation's category
340     property = Category->FindPropertyDeclaration(PropertyId);
341     if (!property) {
342       Diag(PropertyLoc, diag::error_bad_category_property_decl)
343       << Category->getDeclName();
344       return DeclPtrTy();
345     }
346   } else {
347     Diag(AtLoc, diag::error_bad_property_context);
348     return DeclPtrTy();
349   }
350   ObjCIvarDecl *Ivar = 0;
351   // Check that we have a valid, previously declared ivar for @synthesize
352   if (Synthesize) {
353     // @synthesize
354     if (!PropertyIvar)
355       PropertyIvar = PropertyId;
356     QualType PropType = Context.getCanonicalType(property->getType());
357     // Check that this is a previously declared 'ivar' in 'IDecl' interface
358     ObjCInterfaceDecl *ClassDeclared;
359     Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
360     if (!Ivar) {
361       Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc,
362                                   PropertyIvar, PropType, /*Dinfo=*/0,
363                                   ObjCIvarDecl::Protected,
364                                   (Expr *)0);
365       ClassImpDecl->addDecl(Ivar);
366       IDecl->makeDeclVisibleInContext(Ivar, false);
367       property->setPropertyIvarDecl(Ivar);
368
369       if (!getLangOptions().ObjCNonFragileABI)
370         Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId;
371       // Note! I deliberately want it to fall thru so, we have a
372       // a property implementation and to avoid future warnings.
373     } else if (getLangOptions().ObjCNonFragileABI &&
374                ClassDeclared != IDecl) {
375       Diag(PropertyLoc, diag::error_ivar_in_superclass_use)
376       << property->getDeclName() << Ivar->getDeclName()
377       << ClassDeclared->getDeclName();
378       Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
379       << Ivar << Ivar->getNameAsCString();
380       // Note! I deliberately want it to fall thru so more errors are caught.
381     }
382     QualType IvarType = Context.getCanonicalType(Ivar->getType());
383
384     // Check that type of property and its ivar are type compatible.
385     if (PropType != IvarType) {
386       bool compat = false;
387       if (isa<ObjCObjectPointerType>(PropType) 
388             && isa<ObjCObjectPointerType>(IvarType))
389         compat = 
390           Context.canAssignObjCInterfaces(
391                                   PropType->getAs<ObjCObjectPointerType>(),
392                                   IvarType->getAs<ObjCObjectPointerType>());
393       else 
394         compat = (CheckAssignmentConstraints(PropType, IvarType) == Compatible);
395       if (!compat) {
396         Diag(PropertyLoc, diag::error_property_ivar_type)
397           << property->getDeclName() << PropType
398           << Ivar->getDeclName() << IvarType;
399         Diag(Ivar->getLocation(), diag::note_ivar_decl);
400         // Note! I deliberately want it to fall thru so, we have a
401         // a property implementation and to avoid future warnings.
402       }
403
404       // FIXME! Rules for properties are somewhat different that those
405       // for assignments. Use a new routine to consolidate all cases;
406       // specifically for property redeclarations as well as for ivars.
407       QualType lhsType =Context.getCanonicalType(PropType).getUnqualifiedType();
408       QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
409       if (lhsType != rhsType &&
410           lhsType->isArithmeticType()) {
411         Diag(PropertyLoc, diag::error_property_ivar_type)
412           << property->getDeclName() << PropType
413           << Ivar->getDeclName() << IvarType;
414         Diag(Ivar->getLocation(), diag::note_ivar_decl);
415         // Fall thru - see previous comment
416       }
417       // __weak is explicit. So it works on Canonical type.
418       if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() &&
419           getLangOptions().getGCMode() != LangOptions::NonGC) {
420         Diag(PropertyLoc, diag::error_weak_property)
421         << property->getDeclName() << Ivar->getDeclName();
422         // Fall thru - see previous comment
423       }
424       if ((property->getType()->isObjCObjectPointerType() ||
425            PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() &&
426           getLangOptions().getGCMode() != LangOptions::NonGC) {
427         Diag(PropertyLoc, diag::error_strong_property)
428         << property->getDeclName() << Ivar->getDeclName();
429         // Fall thru - see previous comment
430       }
431     }
432   } else if (PropertyIvar)
433     // @dynamic
434     Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
435   assert (property && "ActOnPropertyImplDecl - property declaration missing");
436   ObjCPropertyImplDecl *PIDecl =
437   ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc,
438                                property,
439                                (Synthesize ?
440                                 ObjCPropertyImplDecl::Synthesize
441                                 : ObjCPropertyImplDecl::Dynamic),
442                                Ivar);
443   if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
444     getterMethod->createImplicitParams(Context, IDecl);
445     if (getLangOptions().CPlusPlus && Synthesize) {
446       // For Objective-C++, need to synthesize the AST for the IVAR object to be
447       // returned by the getter as it must conform to C++'s copy-return rules.
448       // FIXME. Eventually we want to do this for Objective-C as well.
449       ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
450       DeclRefExpr *SelfExpr = 
451         new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(),
452                                   SourceLocation());
453       Expr *IvarRefExpr =
454         new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
455                                       SelfExpr, true, true);
456       OwningExprResult Res = 
457         PerformCopyInitialization(InitializedEntity::InitializeResult(
458                                     SourceLocation(),
459                                     getterMethod->getResultType(),
460                                     /*NRVO=*/false),
461                                   SourceLocation(),
462                                   Owned(IvarRefExpr));
463       if (!Res.isInvalid()) {
464         Expr *ResExpr = Res.takeAs<Expr>();
465         if (ResExpr)
466           ResExpr = MaybeCreateCXXExprWithTemporaries(ResExpr);
467         PIDecl->setGetterCXXConstructor(ResExpr);
468       }
469     }
470   }
471   if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
472     setterMethod->createImplicitParams(Context, IDecl);
473     if (getLangOptions().CPlusPlus && Synthesize) {
474       // FIXME. Eventually we want to do this for Objective-C as well.
475       ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
476       DeclRefExpr *SelfExpr = 
477         new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(),
478                                   SourceLocation());
479       Expr *lhs =
480         new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
481                                       SelfExpr, true, true);
482       ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
483       ParmVarDecl *Param = (*P);
484       Expr *rhs = new (Context) DeclRefExpr(Param,Param->getType(),
485                                             SourceLocation());
486       OwningExprResult Res = BuildBinOp(S, SourceLocation(), 
487                                         BinaryOperator::Assign, lhs, rhs);
488       PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
489     }
490   }
491   
492   if (IC) {
493     if (Synthesize)
494       if (ObjCPropertyImplDecl *PPIDecl =
495           IC->FindPropertyImplIvarDecl(PropertyIvar)) {
496         Diag(PropertyLoc, diag::error_duplicate_ivar_use)
497         << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
498         << PropertyIvar;
499         Diag(PPIDecl->getLocation(), diag::note_previous_use);
500       }
501
502     if (ObjCPropertyImplDecl *PPIDecl
503         = IC->FindPropertyImplDecl(PropertyId)) {
504       Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
505       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
506       return DeclPtrTy();
507     }
508     IC->addPropertyImplementation(PIDecl);
509   } else {
510     if (Synthesize)
511       if (ObjCPropertyImplDecl *PPIDecl =
512           CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
513         Diag(PropertyLoc, diag::error_duplicate_ivar_use)
514         << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
515         << PropertyIvar;
516         Diag(PPIDecl->getLocation(), diag::note_previous_use);
517       }
518
519     if (ObjCPropertyImplDecl *PPIDecl =
520         CatImplClass->FindPropertyImplDecl(PropertyId)) {
521       Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
522       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
523       return DeclPtrTy();
524     }
525     CatImplClass->addPropertyImplementation(PIDecl);
526   }
527
528   return DeclPtrTy::make(PIDecl);
529 }
530
531 //===----------------------------------------------------------------------===//
532 // Helper methods.
533 //===----------------------------------------------------------------------===//
534
535 /// DiagnosePropertyMismatch - Compares two properties for their
536 /// attributes and types and warns on a variety of inconsistencies.
537 ///
538 void
539 Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
540                                ObjCPropertyDecl *SuperProperty,
541                                const IdentifierInfo *inheritedName) {
542   ObjCPropertyDecl::PropertyAttributeKind CAttr =
543   Property->getPropertyAttributes();
544   ObjCPropertyDecl::PropertyAttributeKind SAttr =
545   SuperProperty->getPropertyAttributes();
546   if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly)
547       && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite))
548     Diag(Property->getLocation(), diag::warn_readonly_property)
549       << Property->getDeclName() << inheritedName;
550   if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
551       != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
552     Diag(Property->getLocation(), diag::warn_property_attribute)
553       << Property->getDeclName() << "copy" << inheritedName;
554   else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain)
555            != (SAttr & ObjCPropertyDecl::OBJC_PR_retain))
556     Diag(Property->getLocation(), diag::warn_property_attribute)
557       << Property->getDeclName() << "retain" << inheritedName;
558
559   if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)
560       != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic))
561     Diag(Property->getLocation(), diag::warn_property_attribute)
562       << Property->getDeclName() << "atomic" << inheritedName;
563   if (Property->getSetterName() != SuperProperty->getSetterName())
564     Diag(Property->getLocation(), diag::warn_property_attribute)
565       << Property->getDeclName() << "setter" << inheritedName;
566   if (Property->getGetterName() != SuperProperty->getGetterName())
567     Diag(Property->getLocation(), diag::warn_property_attribute)
568       << Property->getDeclName() << "getter" << inheritedName;
569
570   QualType LHSType =
571     Context.getCanonicalType(SuperProperty->getType());
572   QualType RHSType =
573     Context.getCanonicalType(Property->getType());
574
575   if (!Context.typesAreCompatible(LHSType, RHSType)) {
576     // FIXME: Incorporate this test with typesAreCompatible.
577     if (LHSType->isObjCQualifiedIdType() && RHSType->isObjCQualifiedIdType())
578       if (Context.ObjCQualifiedIdTypesAreCompatible(LHSType, RHSType, false))
579         return;
580     Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
581       << Property->getType() << SuperProperty->getType() << inheritedName;
582   }
583 }
584
585 bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property,
586                                             ObjCMethodDecl *GetterMethod,
587                                             SourceLocation Loc) {
588   if (GetterMethod &&
589       GetterMethod->getResultType() != property->getType()) {
590     AssignConvertType result = Incompatible;
591     if (property->getType()->isObjCObjectPointerType())
592       result = CheckAssignmentConstraints(GetterMethod->getResultType(),
593                                           property->getType());
594     if (result != Compatible) {
595       Diag(Loc, diag::warn_accessor_property_type_mismatch)
596       << property->getDeclName()
597       << GetterMethod->getSelector();
598       Diag(GetterMethod->getLocation(), diag::note_declared_at);
599       return true;
600     }
601   }
602   return false;
603 }
604
605 /// ComparePropertiesInBaseAndSuper - This routine compares property
606 /// declarations in base and its super class, if any, and issues
607 /// diagnostics in a variety of inconsistant situations.
608 ///
609 void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
610   ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
611   if (!SDecl)
612     return;
613   // FIXME: O(N^2)
614   for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(),
615        E = SDecl->prop_end(); S != E; ++S) {
616     ObjCPropertyDecl *SuperPDecl = (*S);
617     // Does property in super class has declaration in current class?
618     for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(),
619          E = IDecl->prop_end(); I != E; ++I) {
620       ObjCPropertyDecl *PDecl = (*I);
621       if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
622           DiagnosePropertyMismatch(PDecl, SuperPDecl,
623                                    SDecl->getIdentifier());
624     }
625   }
626 }
627
628 /// MatchOneProtocolPropertiesInClass - This routine goes thru the list
629 /// of properties declared in a protocol and compares their attribute against
630 /// the same property declared in the class or category.
631 void
632 Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl,
633                                           ObjCProtocolDecl *PDecl) {
634   ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
635   if (!IDecl) {
636     // Category
637     ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
638     assert (CatDecl && "MatchOneProtocolPropertiesInClass");
639     if (!CatDecl->IsClassExtension())
640       for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
641            E = PDecl->prop_end(); P != E; ++P) {
642         ObjCPropertyDecl *Pr = (*P);
643         ObjCCategoryDecl::prop_iterator CP, CE;
644         // Is this property already in  category's list of properties?
645         for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP!=CE; ++CP)
646           if ((*CP)->getIdentifier() == Pr->getIdentifier())
647             break;
648         if (CP != CE)
649           // Property protocol already exist in class. Diagnose any mismatch.
650           DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier());
651       }
652     return;
653   }
654   for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
655        E = PDecl->prop_end(); P != E; ++P) {
656     ObjCPropertyDecl *Pr = (*P);
657     ObjCInterfaceDecl::prop_iterator CP, CE;
658     // Is this property already in  class's list of properties?
659     for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP)
660       if ((*CP)->getIdentifier() == Pr->getIdentifier())
661         break;
662     if (CP != CE)
663       // Property protocol already exist in class. Diagnose any mismatch.
664       DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifier());
665     }
666 }
667
668 /// CompareProperties - This routine compares properties
669 /// declared in 'ClassOrProtocol' objects (which can be a class or an
670 /// inherited protocol with the list of properties for class/category 'CDecl'
671 ///
672 void Sema::CompareProperties(Decl *CDecl,
673                              DeclPtrTy ClassOrProtocol) {
674   Decl *ClassDecl = ClassOrProtocol.getAs<Decl>();
675   ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
676
677   if (!IDecl) {
678     // Category
679     ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
680     assert (CatDecl && "CompareProperties");
681     if (ObjCCategoryDecl *MDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
682       for (ObjCCategoryDecl::protocol_iterator P = MDecl->protocol_begin(),
683            E = MDecl->protocol_end(); P != E; ++P)
684       // Match properties of category with those of protocol (*P)
685       MatchOneProtocolPropertiesInClass(CatDecl, *P);
686
687       // Go thru the list of protocols for this category and recursively match
688       // their properties with those in the category.
689       for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(),
690            E = CatDecl->protocol_end(); P != E; ++P)
691         CompareProperties(CatDecl, DeclPtrTy::make(*P));
692     } else {
693       ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
694       for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
695            E = MD->protocol_end(); P != E; ++P)
696         MatchOneProtocolPropertiesInClass(CatDecl, *P);
697     }
698     return;
699   }
700
701   if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
702     for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
703          E = MDecl->protocol_end(); P != E; ++P)
704       // Match properties of class IDecl with those of protocol (*P).
705       MatchOneProtocolPropertiesInClass(IDecl, *P);
706
707     // Go thru the list of protocols for this class and recursively match
708     // their properties with those declared in the class.
709     for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
710          E = IDecl->protocol_end(); P != E; ++P)
711       CompareProperties(IDecl, DeclPtrTy::make(*P));
712   } else {
713     ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
714     for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
715          E = MD->protocol_end(); P != E; ++P)
716       MatchOneProtocolPropertiesInClass(IDecl, *P);
717   }
718 }
719
720 /// isPropertyReadonly - Return true if property is readonly, by searching
721 /// for the property in the class and in its categories and implementations
722 ///
723 bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
724                               ObjCInterfaceDecl *IDecl) {
725   // by far the most common case.
726   if (!PDecl->isReadOnly())
727     return false;
728   // Even if property is ready only, if interface has a user defined setter,
729   // it is not considered read only.
730   if (IDecl->getInstanceMethod(PDecl->getSetterName()))
731     return false;
732
733   // Main class has the property as 'readonly'. Must search
734   // through the category list to see if the property's
735   // attribute has been over-ridden to 'readwrite'.
736   for (ObjCCategoryDecl *Category = IDecl->getCategoryList();
737        Category; Category = Category->getNextClassCategory()) {
738     // Even if property is ready only, if a category has a user defined setter,
739     // it is not considered read only.
740     if (Category->getInstanceMethod(PDecl->getSetterName()))
741       return false;
742     ObjCPropertyDecl *P =
743       Category->FindPropertyDeclaration(PDecl->getIdentifier());
744     if (P && !P->isReadOnly())
745       return false;
746   }
747
748   // Also, check for definition of a setter method in the implementation if
749   // all else failed.
750   if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) {
751     if (ObjCImplementationDecl *IMD =
752         dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) {
753       if (IMD->getInstanceMethod(PDecl->getSetterName()))
754         return false;
755     } else if (ObjCCategoryImplDecl *CIMD =
756                dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
757       if (CIMD->getInstanceMethod(PDecl->getSetterName()))
758         return false;
759     }
760   }
761   // Lastly, look through the implementation (if one is in scope).
762   if (ObjCImplementationDecl *ImpDecl = IDecl->getImplementation())
763     if (ImpDecl->getInstanceMethod(PDecl->getSetterName()))
764       return false;
765   // If all fails, look at the super class.
766   if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass())
767     return isPropertyReadonly(PDecl, SIDecl);
768   return true;
769 }
770
771 /// CollectImmediateProperties - This routine collects all properties in
772 /// the class and its conforming protocols; but not those it its super class.
773 void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
774                 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) {
775   if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
776     for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
777          E = IDecl->prop_end(); P != E; ++P) {
778       ObjCPropertyDecl *Prop = (*P);
779       PropMap[Prop->getIdentifier()] = Prop;
780     }
781     // scan through class's protocols.
782     for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
783          E = IDecl->protocol_end(); PI != E; ++PI)
784       // Exclude property for protocols which conform to class's super-class, 
785       // as super-class has to implement the property.
786       if (!ProtocolConformsToSuperClass(IDecl, (*PI)))
787         CollectImmediateProperties((*PI), PropMap);
788   }
789   if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
790     if (!CATDecl->IsClassExtension())
791       for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(),
792            E = CATDecl->prop_end(); P != E; ++P) {
793         ObjCPropertyDecl *Prop = (*P);
794         PropMap[Prop->getIdentifier()] = Prop;
795       }
796     // scan through class's protocols.
797     for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
798          E = CATDecl->protocol_end(); PI != E; ++PI)
799       CollectImmediateProperties((*PI), PropMap);
800   }
801   else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
802     for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
803          E = PDecl->prop_end(); P != E; ++P) {
804       ObjCPropertyDecl *Prop = (*P);
805       ObjCPropertyDecl *&PropEntry = PropMap[Prop->getIdentifier()];
806       if (!PropEntry)
807         PropEntry = Prop;
808     }
809     // scan through protocol's protocols.
810     for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
811          E = PDecl->protocol_end(); PI != E; ++PI)
812       CollectImmediateProperties((*PI), PropMap);
813   }
814 }
815
816 /// CollectClassPropertyImplementations - This routine collects list of
817 /// properties to be implemented in the class. This includes, class's
818 /// and its conforming protocols' properties.
819 static void CollectClassPropertyImplementations(ObjCContainerDecl *CDecl,
820                 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) {
821   if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
822     for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
823          E = IDecl->prop_end(); P != E; ++P) {
824       ObjCPropertyDecl *Prop = (*P);
825       PropMap[Prop->getIdentifier()] = Prop;
826     }
827     for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
828          E = IDecl->protocol_end(); PI != E; ++PI)
829       CollectClassPropertyImplementations((*PI), PropMap);
830   }
831   else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
832     for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
833          E = PDecl->prop_end(); P != E; ++P) {
834       ObjCPropertyDecl *Prop = (*P);
835       PropMap[Prop->getIdentifier()] = Prop;
836     }
837     // scan through protocol's protocols.
838     for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
839          E = PDecl->protocol_end(); PI != E; ++PI)
840       CollectClassPropertyImplementations((*PI), PropMap);
841   }
842 }
843
844 /// CollectSuperClassPropertyImplementations - This routine collects list of
845 /// properties to be implemented in super class(s) and also coming from their
846 /// conforming protocols.
847 static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl,
848                 llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap) {
849   if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) {
850     while (SDecl) {
851       CollectClassPropertyImplementations(SDecl, PropMap);
852       SDecl = SDecl->getSuperClass();
853     }
854   }
855 }
856
857 /// ProtocolConformsToSuperClass - Returns true if class's given protocol
858 /// conforms to one of its super class's protocols.
859 bool Sema::ProtocolConformsToSuperClass(const ObjCInterfaceDecl *IDecl,
860                                         const ObjCProtocolDecl *PDecl) {
861   if (const ObjCInterfaceDecl *CDecl = IDecl->getSuperClass()) {
862     for (ObjCInterfaceDecl::protocol_iterator PI = CDecl->protocol_begin(),
863          E = CDecl->protocol_end(); PI != E; ++PI) {
864       if (ProtocolConformsToProtocol((*PI), PDecl))
865         return true;
866       return ProtocolConformsToSuperClass(CDecl, PDecl);
867     }
868   }
869   return false;
870 }
871
872 bool Sema::ProtocolConformsToProtocol(const ObjCProtocolDecl *NestedProtocol,
873                                       const ObjCProtocolDecl *PDecl) {
874   if (PDecl->getIdentifier() == NestedProtocol->getIdentifier())
875     return true;
876   // scan through protocol's protocols.
877   for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
878        E = PDecl->protocol_end(); PI != E; ++PI)
879     if (ProtocolConformsToProtocol(NestedProtocol, (*PI)))
880       return true;
881   return false;
882 }
883
884 /// LookupPropertyDecl - Looks up a property in the current class and all
885 /// its protocols.
886 ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl,
887                                      IdentifierInfo *II) {
888   if (const ObjCInterfaceDecl *IDecl =
889         dyn_cast<ObjCInterfaceDecl>(CDecl)) {
890     for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
891          E = IDecl->prop_end(); P != E; ++P) {
892       ObjCPropertyDecl *Prop = (*P);
893       if (Prop->getIdentifier() == II)
894         return Prop;
895     }
896     // scan through class's protocols.
897     for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
898          E = IDecl->protocol_end(); PI != E; ++PI) {
899       ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
900       if (Prop)
901         return Prop;
902     }
903   }
904   else if (const ObjCProtocolDecl *PDecl =
905             dyn_cast<ObjCProtocolDecl>(CDecl)) {
906     for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
907          E = PDecl->prop_end(); P != E; ++P) {
908       ObjCPropertyDecl *Prop = (*P);
909       if (Prop->getIdentifier() == II)
910         return Prop;
911     }
912     // scan through protocol's protocols.
913     for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
914          E = PDecl->protocol_end(); PI != E; ++PI) {
915       ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
916       if (Prop)
917         return Prop;
918     }
919   }
920   return 0;
921 }
922
923 /// DefaultSynthesizeProperties - This routine default synthesizes all
924 /// properties which must be synthesized in class's @implementation.
925 void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
926                                         ObjCInterfaceDecl *IDecl) {
927   
928   llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
929   CollectClassPropertyImplementations(IDecl, PropMap);
930   if (PropMap.empty())
931     return;
932   llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> SuperPropMap;
933   CollectSuperClassPropertyImplementations(IDecl, SuperPropMap);
934   
935   for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator
936        P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
937     ObjCPropertyDecl *Prop = P->second;
938     // If property to be implemented in the super class, ignore.
939     if (SuperPropMap[Prop->getIdentifier()])
940       continue;
941     // Is there a matching propery synthesize/dynamic?
942     if (Prop->isInvalidDecl() ||
943         Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
944         IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier()))
945       continue;
946     ActOnPropertyImplDecl(S, IMPDecl->getLocation(), IMPDecl->getLocation(),
947                           true, DeclPtrTy::make(IMPDecl),
948                           Prop->getIdentifier(), Prop->getIdentifier());
949   }    
950 }
951
952 void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
953                                       ObjCContainerDecl *CDecl,
954                                       const llvm::DenseSet<Selector>& InsMap) {
955   llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
956   CollectImmediateProperties(CDecl, PropMap);
957   if (PropMap.empty())
958     return;
959
960   llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;
961   for (ObjCImplDecl::propimpl_iterator
962        I = IMPDecl->propimpl_begin(),
963        EI = IMPDecl->propimpl_end(); I != EI; ++I)
964     PropImplMap.insert((*I)->getPropertyDecl());
965
966   for (llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>::iterator
967        P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
968     ObjCPropertyDecl *Prop = P->second;
969     // Is there a matching propery synthesize/dynamic?
970     if (Prop->isInvalidDecl() ||
971         Prop->getPropertyImplementation() == ObjCPropertyDecl::Optional ||
972         PropImplMap.count(Prop))
973       continue;
974     if (!InsMap.count(Prop->getGetterName())) {
975       Diag(Prop->getLocation(),
976            isa<ObjCCategoryDecl>(CDecl) ?
977             diag::warn_setter_getter_impl_required_in_category :
978             diag::warn_setter_getter_impl_required)
979       << Prop->getDeclName() << Prop->getGetterName();
980       Diag(IMPDecl->getLocation(),
981            diag::note_property_impl_required);
982     }
983
984     if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) {
985       Diag(Prop->getLocation(),
986            isa<ObjCCategoryDecl>(CDecl) ?
987            diag::warn_setter_getter_impl_required_in_category :
988            diag::warn_setter_getter_impl_required)
989       << Prop->getDeclName() << Prop->getSetterName();
990       Diag(IMPDecl->getLocation(),
991            diag::note_property_impl_required);
992     }
993   }
994 }
995
996 void
997 Sema::AtomicPropertySetterGetterRules (ObjCImplDecl* IMPDecl,
998                                        ObjCContainerDecl* IDecl) {
999   // Rules apply in non-GC mode only
1000   if (getLangOptions().getGCMode() != LangOptions::NonGC)
1001     return;
1002   for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(),
1003        E = IDecl->prop_end();
1004        I != E; ++I) {
1005     ObjCPropertyDecl *Property = (*I);
1006     unsigned Attributes = Property->getPropertyAttributes();
1007     // We only care about readwrite atomic property.
1008     if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) ||
1009         !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite))
1010       continue;
1011     if (const ObjCPropertyImplDecl *PIDecl
1012          = IMPDecl->FindPropertyImplDecl(Property->getIdentifier())) {
1013       if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
1014         continue;
1015       ObjCMethodDecl *GetterMethod =
1016         IMPDecl->getInstanceMethod(Property->getGetterName());
1017       ObjCMethodDecl *SetterMethod =
1018         IMPDecl->getInstanceMethod(Property->getSetterName());
1019       if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) {
1020         SourceLocation MethodLoc =
1021           (GetterMethod ? GetterMethod->getLocation()
1022                         : SetterMethod->getLocation());
1023         Diag(MethodLoc, diag::warn_atomic_property_rule)
1024           << Property->getIdentifier();
1025         Diag(Property->getLocation(), diag::note_property_declare);
1026       }
1027     }
1028   }
1029 }
1030
1031 /// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods
1032 /// have the property type and issue diagnostics if they don't.
1033 /// Also synthesize a getter/setter method if none exist (and update the
1034 /// appropriate lookup tables. FIXME: Should reconsider if adding synthesized
1035 /// methods is the "right" thing to do.
1036 void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
1037                                ObjCContainerDecl *CD) {
1038   ObjCMethodDecl *GetterMethod, *SetterMethod;
1039
1040   GetterMethod = CD->getInstanceMethod(property->getGetterName());
1041   SetterMethod = CD->getInstanceMethod(property->getSetterName());
1042   DiagnosePropertyAccessorMismatch(property, GetterMethod,
1043                                    property->getLocation());
1044
1045   if (SetterMethod) {
1046     ObjCPropertyDecl::PropertyAttributeKind CAttr =
1047       property->getPropertyAttributes();
1048     if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) &&
1049         Context.getCanonicalType(SetterMethod->getResultType()) !=
1050           Context.VoidTy)
1051       Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
1052     if (SetterMethod->param_size() != 1 ||
1053         ((*SetterMethod->param_begin())->getType() != property->getType())) {
1054       Diag(property->getLocation(),
1055            diag::warn_accessor_property_type_mismatch)
1056         << property->getDeclName()
1057         << SetterMethod->getSelector();
1058       Diag(SetterMethod->getLocation(), diag::note_declared_at);
1059     }
1060   }
1061
1062   // Synthesize getter/setter methods if none exist.
1063   // Find the default getter and if one not found, add one.
1064   // FIXME: The synthesized property we set here is misleading. We almost always
1065   // synthesize these methods unless the user explicitly provided prototypes
1066   // (which is odd, but allowed). Sema should be typechecking that the
1067   // declarations jive in that situation (which it is not currently).
1068   if (!GetterMethod) {
1069     // No instance method of same name as property getter name was found.
1070     // Declare a getter method and add it to the list of methods
1071     // for this class.
1072     GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
1073                              property->getLocation(), property->getGetterName(),
1074                              property->getType(), 0, CD, true, false, true,
1075                              (property->getPropertyImplementation() ==
1076                               ObjCPropertyDecl::Optional) ?
1077                              ObjCMethodDecl::Optional :
1078                              ObjCMethodDecl::Required);
1079     CD->addDecl(GetterMethod);
1080     // FIXME: Eventually this shouldn't be needed, as the lexical context
1081     // and the real context should be the same.
1082     if (DeclContext *lexicalDC = property->getLexicalDeclContext())
1083       GetterMethod->setLexicalDeclContext(lexicalDC);
1084
1085   } else
1086     // A user declared getter will be synthesize when @synthesize of
1087     // the property with the same name is seen in the @implementation
1088     GetterMethod->setSynthesized(true);
1089   property->setGetterMethodDecl(GetterMethod);
1090
1091   // Skip setter if property is read-only.
1092   if (!property->isReadOnly()) {
1093     // Find the default setter and if one not found, add one.
1094     if (!SetterMethod) {
1095       // No instance method of same name as property setter name was found.
1096       // Declare a setter method and add it to the list of methods
1097       // for this class.
1098       SetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
1099                                property->getLocation(),
1100                                property->getSetterName(),
1101                                Context.VoidTy, 0, CD, true, false, true,
1102                                (property->getPropertyImplementation() ==
1103                                 ObjCPropertyDecl::Optional) ?
1104                                ObjCMethodDecl::Optional :
1105                                ObjCMethodDecl::Required);
1106       // Invent the arguments for the setter. We don't bother making a
1107       // nice name for the argument.
1108       ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod,
1109                                                   property->getLocation(),
1110                                                   property->getIdentifier(),
1111                                                   property->getType(),
1112                                                   /*TInfo=*/0,
1113                                                   VarDecl::None,
1114                                                   VarDecl::None,
1115                                                   0);
1116       SetterMethod->setMethodParams(Context, &Argument, 1, 1);
1117       CD->addDecl(SetterMethod);
1118       // FIXME: Eventually this shouldn't be needed, as the lexical context
1119       // and the real context should be the same.
1120       if (DeclContext *lexicalDC = property->getLexicalDeclContext())
1121         SetterMethod->setLexicalDeclContext(lexicalDC);
1122     } else
1123       // A user declared setter will be synthesize when @synthesize of
1124       // the property with the same name is seen in the @implementation
1125       SetterMethod->setSynthesized(true);
1126     property->setSetterMethodDecl(SetterMethod);
1127   }
1128   // Add any synthesized methods to the global pool. This allows us to
1129   // handle the following, which is supported by GCC (and part of the design).
1130   //
1131   // @interface Foo
1132   // @property double bar;
1133   // @end
1134   //
1135   // void thisIsUnfortunate() {
1136   //   id foo;
1137   //   double bar = [foo bar];
1138   // }
1139   //
1140   if (GetterMethod)
1141     AddInstanceMethodToGlobalPool(GetterMethod);
1142   if (SetterMethod)
1143     AddInstanceMethodToGlobalPool(SetterMethod);
1144 }
1145
1146 void Sema::CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy,
1147                                        SourceLocation Loc,
1148                                        unsigned &Attributes) {
1149   // FIXME: Improve the reported location.
1150   Decl *PDecl = PropertyPtrTy.getAs<Decl>();
1151   if (!PDecl)
1152     return;
1153
1154   ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl);
1155   QualType PropertyTy = PropertyDecl->getType(); 
1156
1157   // readonly and readwrite/assign/retain/copy conflict.
1158   if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1159       (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
1160                      ObjCDeclSpec::DQ_PR_assign |
1161                      ObjCDeclSpec::DQ_PR_copy |
1162                      ObjCDeclSpec::DQ_PR_retain))) {
1163     const char * which = (Attributes & ObjCDeclSpec::DQ_PR_readwrite) ?
1164                           "readwrite" :
1165                          (Attributes & ObjCDeclSpec::DQ_PR_assign) ?
1166                           "assign" :
1167                          (Attributes & ObjCDeclSpec::DQ_PR_copy) ?
1168                           "copy" : "retain";
1169
1170     Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ?
1171                  diag::err_objc_property_attr_mutually_exclusive :
1172                  diag::warn_objc_property_attr_mutually_exclusive)
1173       << "readonly" << which;
1174   }
1175
1176   // Check for copy or retain on non-object types.
1177   if ((Attributes & (ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain)) &&
1178       !PropertyTy->isObjCObjectPointerType() &&
1179       !PropertyTy->isBlockPointerType() &&
1180       !Context.isObjCNSObjectType(PropertyTy) &&
1181       !PropertyDecl->getAttr<ObjCNSObjectAttr>()) {
1182     Diag(Loc, diag::err_objc_property_requires_object)
1183       << (Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain");
1184     Attributes &= ~(ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain);
1185   }
1186
1187   // Check for more than one of { assign, copy, retain }.
1188   if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
1189     if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1190       Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1191         << "assign" << "copy";
1192       Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
1193     }
1194     if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1195       Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1196         << "assign" << "retain";
1197       Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
1198     }
1199   } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
1200     if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
1201       Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
1202         << "copy" << "retain";
1203       Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
1204     }
1205   }
1206
1207   // Warn if user supplied no assignment attribute, property is
1208   // readwrite, and this is an object type.
1209   if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
1210                       ObjCDeclSpec::DQ_PR_retain)) &&
1211       !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
1212       PropertyTy->isObjCObjectPointerType()) {
1213     // Skip this warning in gc-only mode.
1214     if (getLangOptions().getGCMode() != LangOptions::GCOnly)
1215       Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
1216
1217     // If non-gc code warn that this is likely inappropriate.
1218     if (getLangOptions().getGCMode() == LangOptions::NonGC)
1219       Diag(Loc, diag::warn_objc_property_default_assign_on_object);
1220
1221     // FIXME: Implement warning dependent on NSCopying being
1222     // implemented. See also:
1223     // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496>
1224     // (please trim this list while you are at it).
1225   }
1226
1227   if (!(Attributes & ObjCDeclSpec::DQ_PR_copy)
1228       && getLangOptions().getGCMode() == LangOptions::GCOnly
1229       && PropertyTy->isBlockPointerType())
1230     Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
1231 }