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