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