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