clang  10.0.0git
SemaObjCProperty.cpp
Go to the documentation of this file.
1 //===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements semantic analysis for Objective C @property and
10 // @synthesize declarations.
11 //
12 //===----------------------------------------------------------------------===//
13 
16 #include "clang/AST/DeclObjC.h"
17 #include "clang/AST/ExprCXX.h"
18 #include "clang/AST/ExprObjC.h"
20 #include "clang/Lex/Lexer.h"
21 #include "clang/Lex/Preprocessor.h"
23 #include "llvm/ADT/DenseSet.h"
24 #include "llvm/ADT/SmallString.h"
25 
26 using namespace clang;
27 
28 //===----------------------------------------------------------------------===//
29 // Grammar actions.
30 //===----------------------------------------------------------------------===//
31 
32 /// getImpliedARCOwnership - Given a set of property attributes and a
33 /// type, infer an expected lifetime. The type's ownership qualification
34 /// is not considered.
35 ///
36 /// Returns OCL_None if the attributes as stated do not imply an ownership.
37 /// Never returns OCL_Autoreleasing.
40  QualType type) {
41  // retain, strong, copy, weak, and unsafe_unretained are only legal
42  // on properties of retainable pointer type.
47  } else if (attrs & ObjCPropertyDecl::OBJC_PR_weak) {
48  return Qualifiers::OCL_Weak;
51  }
52 
53  // assign can appear on other types, so we have to check the
54  // property type.
56  type->isObjCRetainableType()) {
58  }
59 
60  return Qualifiers::OCL_None;
61 }
62 
63 /// Check the internal consistency of a property declaration with
64 /// an explicit ownership qualifier.
66  ObjCPropertyDecl *property) {
67  if (property->isInvalidDecl()) return;
68 
70  = property->getPropertyAttributes();
71  Qualifiers::ObjCLifetime propertyLifetime
72  = property->getType().getObjCLifetime();
73 
74  assert(propertyLifetime != Qualifiers::OCL_None);
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 /// 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  // In GC mode, just look for the __weak qualifier.
132  if (S.getLangOpts().getGC() != LangOptions::NonGC) {
133  if (T.isObjCGCWeak()) return ObjCDeclSpec::DQ_PR_weak;
134 
135  // In ARC/MRC, look for an explicit ownership qualifier.
136  // For some reason, this only applies to __weak.
137  } else if (auto ownership = T.getObjCLifetime()) {
138  switch (ownership) {
147  return 0;
148  }
149  llvm_unreachable("bad qualifier");
150  }
151 
152  return 0;
153 }
154 
155 static const unsigned OwnershipMask =
162 
163 static unsigned getOwnershipRule(unsigned attr) {
164  unsigned result = attr & OwnershipMask;
165 
166  // From an ownership perspective, assign and unsafe_unretained are
167  // identical; make sure one also implies the other.
168  if (result & (ObjCPropertyDecl::OBJC_PR_assign |
172  }
173 
174  return result;
175 }
176 
178  SourceLocation LParenLoc,
179  FieldDeclarator &FD,
180  ObjCDeclSpec &ODS,
181  Selector GetterSel,
182  Selector SetterSel,
183  tok::ObjCKeywordKind MethodImplKind,
184  DeclContext *lexicalDC) {
185  unsigned Attributes = ODS.getPropertyAttributes();
186  FD.D.setObjCWeakProperty((Attributes & ObjCDeclSpec::DQ_PR_weak) != 0);
187  TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S);
188  QualType T = TSI->getType();
189  if (!getOwnershipRule(Attributes)) {
190  Attributes |= deducePropertyOwnershipFromType(*this, T);
191  }
192  bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
193  // default is readwrite!
194  !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
195 
196  // Proceed with constructing the ObjCPropertyDecls.
197  ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext);
198  ObjCPropertyDecl *Res = nullptr;
199  if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
200  if (CDecl->IsClassExtension()) {
201  Res = HandlePropertyInClassExtension(S, AtLoc, LParenLoc,
202  FD,
203  GetterSel, ODS.getGetterNameLoc(),
204  SetterSel, ODS.getSetterNameLoc(),
205  isReadWrite, Attributes,
206  ODS.getPropertyAttributes(),
207  T, TSI, MethodImplKind);
208  if (!Res)
209  return nullptr;
210  }
211  }
212 
213  if (!Res) {
214  Res = CreatePropertyDecl(S, ClassDecl, AtLoc, LParenLoc, FD,
215  GetterSel, ODS.getGetterNameLoc(), SetterSel,
216  ODS.getSetterNameLoc(), isReadWrite, Attributes,
217  ODS.getPropertyAttributes(), T, TSI,
218  MethodImplKind);
219  if (lexicalDC)
220  Res->setLexicalDeclContext(lexicalDC);
221  }
222 
223  // Validate the attributes on the @property.
224  CheckObjCPropertyAttributes(Res, AtLoc, Attributes,
225  (isa<ObjCInterfaceDecl>(ClassDecl) ||
226  isa<ObjCProtocolDecl>(ClassDecl)));
227 
228  // Check consistency if the type has explicit ownership qualification.
229  if (Res->getType().getObjCLifetime())
230  checkPropertyDeclWithOwnership(*this, Res);
231 
232  llvm::SmallPtrSet<ObjCProtocolDecl *, 16> KnownProtos;
233  if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
234  // For a class, compare the property against a property in our superclass.
235  bool FoundInSuper = false;
236  ObjCInterfaceDecl *CurrentInterfaceDecl = IFace;
237  while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) {
238  DeclContext::lookup_result R = Super->lookup(Res->getDeclName());
239  for (unsigned I = 0, N = R.size(); I != N; ++I) {
240  if (ObjCPropertyDecl *SuperProp = dyn_cast<ObjCPropertyDecl>(R[I])) {
241  DiagnosePropertyMismatch(Res, SuperProp, Super->getIdentifier(), false);
242  FoundInSuper = true;
243  break;
244  }
245  }
246  if (FoundInSuper)
247  break;
248  else
249  CurrentInterfaceDecl = Super;
250  }
251 
252  if (FoundInSuper) {
253  // Also compare the property against a property in our protocols.
254  for (auto *P : CurrentInterfaceDecl->protocols()) {
255  CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
256  }
257  } else {
258  // Slower path: look in all protocols we referenced.
259  for (auto *P : IFace->all_referenced_protocols()) {
260  CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
261  }
262  }
263  } else if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
264  // We don't check if class extension. Because properties in class extension
265  // are meant to override some of the attributes and checking has already done
266  // when property in class extension is constructed.
267  if (!Cat->IsClassExtension())
268  for (auto *P : Cat->protocols())
269  CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
270  } else {
271  ObjCProtocolDecl *Proto = cast<ObjCProtocolDecl>(ClassDecl);
272  for (auto *P : Proto->protocols())
273  CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
274  }
275 
277  return Res;
278 }
279 
281 makePropertyAttributesAsWritten(unsigned Attributes) {
282  unsigned attributesAsWritten = 0;
283  if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
284  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readonly;
285  if (Attributes & ObjCDeclSpec::DQ_PR_readwrite)
286  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_readwrite;
287  if (Attributes & ObjCDeclSpec::DQ_PR_getter)
288  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_getter;
289  if (Attributes & ObjCDeclSpec::DQ_PR_setter)
290  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_setter;
291  if (Attributes & ObjCDeclSpec::DQ_PR_assign)
292  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_assign;
293  if (Attributes & ObjCDeclSpec::DQ_PR_retain)
294  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_retain;
295  if (Attributes & ObjCDeclSpec::DQ_PR_strong)
296  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_strong;
297  if (Attributes & ObjCDeclSpec::DQ_PR_weak)
298  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_weak;
299  if (Attributes & ObjCDeclSpec::DQ_PR_copy)
300  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_copy;
301  if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
302  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
303  if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
304  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_nonatomic;
305  if (Attributes & ObjCDeclSpec::DQ_PR_atomic)
306  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_atomic;
307  if (Attributes & ObjCDeclSpec::DQ_PR_class)
308  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_class;
309  if (Attributes & ObjCDeclSpec::DQ_PR_direct)
310  attributesAsWritten |= ObjCPropertyDecl::OBJC_PR_direct;
311 
312  return (ObjCPropertyDecl::PropertyAttributeKind)attributesAsWritten;
313 }
314 
315 static bool LocPropertyAttribute( ASTContext &Context, const char *attrName,
316  SourceLocation LParenLoc, SourceLocation &Loc) {
317  if (LParenLoc.isMacroID())
318  return false;
319 
320  SourceManager &SM = Context.getSourceManager();
321  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(LParenLoc);
322  // Try to load the file buffer.
323  bool invalidTemp = false;
324  StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
325  if (invalidTemp)
326  return false;
327  const char *tokenBegin = file.data() + locInfo.second;
328 
329  // Lex from the start of the given location.
330  Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
331  Context.getLangOpts(),
332  file.begin(), tokenBegin, file.end());
333  Token Tok;
334  do {
335  lexer.LexFromRawLexer(Tok);
336  if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == attrName) {
337  Loc = Tok.getLocation();
338  return true;
339  }
340  } while (Tok.isNot(tok::r_paren));
341  return false;
342 }
343 
344 /// Check for a mismatch in the atomicity of the given properties.
346  ObjCPropertyDecl *OldProperty,
347  ObjCPropertyDecl *NewProperty,
348  bool PropagateAtomicity) {
349  // If the atomicity of both matches, we're done.
350  bool OldIsAtomic =
352  == 0;
353  bool NewIsAtomic =
355  == 0;
356  if (OldIsAtomic == NewIsAtomic) return;
357 
358  // Determine whether the given property is readonly and implicitly
359  // atomic.
360  auto isImplicitlyReadonlyAtomic = [](ObjCPropertyDecl *Property) -> bool {
361  // Is it readonly?
362  auto Attrs = Property->getPropertyAttributes();
363  if ((Attrs & ObjCPropertyDecl::OBJC_PR_readonly) == 0) return false;
364 
365  // Is it nonatomic?
366  if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) return false;
367 
368  // Was 'atomic' specified directly?
369  if (Property->getPropertyAttributesAsWritten() &
371  return false;
372 
373  return true;
374  };
375 
376  // If we're allowed to propagate atomicity, and the new property did
377  // not specify atomicity at all, propagate.
378  const unsigned AtomicityMask =
380  if (PropagateAtomicity &&
381  ((NewProperty->getPropertyAttributesAsWritten() & AtomicityMask) == 0)) {
382  unsigned Attrs = NewProperty->getPropertyAttributes();
383  Attrs = Attrs & ~AtomicityMask;
384  if (OldIsAtomic)
386  else
388 
389  NewProperty->overwritePropertyAttributes(Attrs);
390  return;
391  }
392 
393  // One of the properties is atomic; if it's a readonly property, and
394  // 'atomic' wasn't explicitly specified, we're okay.
395  if ((OldIsAtomic && isImplicitlyReadonlyAtomic(OldProperty)) ||
396  (NewIsAtomic && isImplicitlyReadonlyAtomic(NewProperty)))
397  return;
398 
399  // Diagnose the conflict.
400  const IdentifierInfo *OldContextName;
401  auto *OldDC = OldProperty->getDeclContext();
402  if (auto Category = dyn_cast<ObjCCategoryDecl>(OldDC))
403  OldContextName = Category->getClassInterface()->getIdentifier();
404  else
405  OldContextName = cast<ObjCContainerDecl>(OldDC)->getIdentifier();
406 
407  S.Diag(NewProperty->getLocation(), diag::warn_property_attribute)
408  << NewProperty->getDeclName() << "atomic"
409  << OldContextName;
410  S.Diag(OldProperty->getLocation(), diag::note_property_declare);
411 }
412 
415  SourceLocation AtLoc,
416  SourceLocation LParenLoc,
417  FieldDeclarator &FD,
418  Selector GetterSel,
419  SourceLocation GetterNameLoc,
420  Selector SetterSel,
421  SourceLocation SetterNameLoc,
422  const bool isReadWrite,
423  unsigned &Attributes,
424  const unsigned AttributesAsWritten,
425  QualType T,
426  TypeSourceInfo *TSI,
427  tok::ObjCKeywordKind MethodImplKind) {
428  ObjCCategoryDecl *CDecl = cast<ObjCCategoryDecl>(CurContext);
429  // Diagnose if this property is already in continuation class.
430  DeclContext *DC = CurContext;
431  IdentifierInfo *PropertyId = FD.D.getIdentifier();
432  ObjCInterfaceDecl *CCPrimary = CDecl->getClassInterface();
433 
434  // We need to look in the @interface to see if the @property was
435  // already declared.
436  if (!CCPrimary) {
437  Diag(CDecl->getLocation(), diag::err_continuation_class);
438  return nullptr;
439  }
440 
441  bool isClassProperty = (AttributesAsWritten & ObjCDeclSpec::DQ_PR_class) ||
442  (Attributes & ObjCDeclSpec::DQ_PR_class);
443 
444  // Find the property in the extended class's primary class or
445  // extensions.
447  PropertyId, ObjCPropertyDecl::getQueryKind(isClassProperty));
448 
449  // If we found a property in an extension, complain.
450  if (PIDecl && isa<ObjCCategoryDecl>(PIDecl->getDeclContext())) {
451  Diag(AtLoc, diag::err_duplicate_property);
452  Diag(PIDecl->getLocation(), diag::note_property_declare);
453  return nullptr;
454  }
455 
456  // Check for consistency with the previous declaration, if there is one.
457  if (PIDecl) {
458  // A readonly property declared in the primary class can be refined
459  // by adding a readwrite property within an extension.
460  // Anything else is an error.
461  if (!(PIDecl->isReadOnly() && isReadWrite)) {
462  // Tailor the diagnostics for the common case where a readwrite
463  // property is declared both in the @interface and the continuation.
464  // This is a common error where the user often intended the original
465  // declaration to be readonly.
466  unsigned diag =
467  (Attributes & ObjCDeclSpec::DQ_PR_readwrite) &&
468  (PIDecl->getPropertyAttributesAsWritten() &
470  ? diag::err_use_continuation_class_redeclaration_readwrite
471  : diag::err_use_continuation_class;
472  Diag(AtLoc, diag)
473  << CCPrimary->getDeclName();
474  Diag(PIDecl->getLocation(), diag::note_property_declare);
475  return nullptr;
476  }
477 
478  // Check for consistency of getters.
479  if (PIDecl->getGetterName() != GetterSel) {
480  // If the getter was written explicitly, complain.
481  if (AttributesAsWritten & ObjCDeclSpec::DQ_PR_getter) {
482  Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)
483  << PIDecl->getGetterName() << GetterSel;
484  Diag(PIDecl->getLocation(), diag::note_property_declare);
485  }
486 
487  // Always adopt the getter from the original declaration.
488  GetterSel = PIDecl->getGetterName();
489  Attributes |= ObjCDeclSpec::DQ_PR_getter;
490  }
491 
492  // Check consistency of ownership.
493  unsigned ExistingOwnership
495  unsigned NewOwnership = getOwnershipRule(Attributes);
496  if (ExistingOwnership && NewOwnership != ExistingOwnership) {
497  // If the ownership was written explicitly, complain.
498  if (getOwnershipRule(AttributesAsWritten)) {
499  Diag(AtLoc, diag::warn_property_attr_mismatch);
500  Diag(PIDecl->getLocation(), diag::note_property_declare);
501  }
502 
503  // Take the ownership from the original property.
504  Attributes = (Attributes & ~OwnershipMask) | ExistingOwnership;
505  }
506 
507  // If the redeclaration is 'weak' but the original property is not,
508  if ((Attributes & ObjCPropertyDecl::OBJC_PR_weak) &&
511  PIDecl->getType()->getAs<ObjCObjectPointerType>() &&
513  Diag(AtLoc, diag::warn_property_implicitly_mismatched);
514  Diag(PIDecl->getLocation(), diag::note_property_declare);
515  }
516  }
517 
518  // Create a new ObjCPropertyDecl with the DeclContext being
519  // the class extension.
520  ObjCPropertyDecl *PDecl = CreatePropertyDecl(S, CDecl, AtLoc, LParenLoc,
521  FD, GetterSel, GetterNameLoc,
522  SetterSel, SetterNameLoc,
523  isReadWrite,
524  Attributes, AttributesAsWritten,
525  T, TSI, MethodImplKind, DC);
526 
527  // If there was no declaration of a property with the same name in
528  // the primary class, we're done.
529  if (!PIDecl) {
530  ProcessPropertyDecl(PDecl);
531  return PDecl;
532  }
533 
534  if (!Context.hasSameType(PIDecl->getType(), PDecl->getType())) {
535  bool IncompatibleObjC = false;
536  QualType ConvertedType;
537  // Relax the strict type matching for property type in continuation class.
538  // Allow property object type of continuation class to be different as long
539  // as it narrows the object type in its primary class property. Note that
540  // this conversion is safe only because the wider type is for a 'readonly'
541  // property in primary class and 'narrowed' type for a 'readwrite' property
542  // in continuation class.
543  QualType PrimaryClassPropertyT = Context.getCanonicalType(PIDecl->getType());
544  QualType ClassExtPropertyT = Context.getCanonicalType(PDecl->getType());
545  if (!isa<ObjCObjectPointerType>(PrimaryClassPropertyT) ||
546  !isa<ObjCObjectPointerType>(ClassExtPropertyT) ||
547  (!isObjCPointerConversion(ClassExtPropertyT, PrimaryClassPropertyT,
548  ConvertedType, IncompatibleObjC))
549  || IncompatibleObjC) {
550  Diag(AtLoc,
551  diag::err_type_mismatch_continuation_class) << PDecl->getType();
552  Diag(PIDecl->getLocation(), diag::note_property_declare);
553  return nullptr;
554  }
555  }
556 
557  // Check that atomicity of property in class extension matches the previous
558  // declaration.
559  checkAtomicPropertyMismatch(*this, PIDecl, PDecl, true);
560 
561  // Make sure getter/setter are appropriately synthesized.
562  ProcessPropertyDecl(PDecl);
563  return PDecl;
564 }
565 
567  ObjCContainerDecl *CDecl,
568  SourceLocation AtLoc,
569  SourceLocation LParenLoc,
570  FieldDeclarator &FD,
571  Selector GetterSel,
572  SourceLocation GetterNameLoc,
573  Selector SetterSel,
574  SourceLocation SetterNameLoc,
575  const bool isReadWrite,
576  const unsigned Attributes,
577  const unsigned AttributesAsWritten,
578  QualType T,
579  TypeSourceInfo *TInfo,
580  tok::ObjCKeywordKind MethodImplKind,
581  DeclContext *lexicalDC){
582  IdentifierInfo *PropertyId = FD.D.getIdentifier();
583 
584  // Property defaults to 'assign' if it is readwrite, unless this is ARC
585  // and the type is retainable.
586  bool isAssign;
587  if (Attributes & (ObjCDeclSpec::DQ_PR_assign |
589  isAssign = true;
590  } else if (getOwnershipRule(Attributes) || !isReadWrite) {
591  isAssign = false;
592  } else {
593  isAssign = (!getLangOpts().ObjCAutoRefCount ||
594  !T->isObjCRetainableType());
595  }
596 
597  // Issue a warning if property is 'assign' as default and its
598  // object, which is gc'able conforms to NSCopying protocol
599  if (getLangOpts().getGC() != LangOptions::NonGC &&
600  isAssign && !(Attributes & ObjCDeclSpec::DQ_PR_assign)) {
601  if (const ObjCObjectPointerType *ObjPtrTy =
603  ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
604  if (IDecl)
605  if (ObjCProtocolDecl* PNSCopying =
606  LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc))
607  if (IDecl->ClassImplementsProtocol(PNSCopying, true))
608  Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
609  }
610  }
611 
612  if (T->isObjCObjectType()) {
613  SourceLocation StarLoc = TInfo->getTypeLoc().getEndLoc();
614  StarLoc = getLocForEndOfToken(StarLoc);
615  Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object)
616  << FixItHint::CreateInsertion(StarLoc, "*");
618  SourceLocation TLoc = TInfo->getTypeLoc().getBeginLoc();
619  TInfo = Context.getTrivialTypeSourceInfo(T, TLoc);
620  }
621 
622  DeclContext *DC = CDecl;
624  FD.D.getIdentifierLoc(),
625  PropertyId, AtLoc,
626  LParenLoc, T, TInfo);
627 
628  bool isClassProperty = (AttributesAsWritten & ObjCDeclSpec::DQ_PR_class) ||
629  (Attributes & ObjCDeclSpec::DQ_PR_class);
630  // Class property and instance property can have the same name.
632  DC, PropertyId, ObjCPropertyDecl::getQueryKind(isClassProperty))) {
633  Diag(PDecl->getLocation(), diag::err_duplicate_property);
634  Diag(prevDecl->getLocation(), diag::note_property_declare);
635  PDecl->setInvalidDecl();
636  }
637  else {
638  DC->addDecl(PDecl);
639  if (lexicalDC)
640  PDecl->setLexicalDeclContext(lexicalDC);
641  }
642 
643  if (T->isArrayType() || T->isFunctionType()) {
644  Diag(AtLoc, diag::err_property_type) << T;
645  PDecl->setInvalidDecl();
646  }
647 
648  ProcessDeclAttributes(S, PDecl, FD.D);
649 
650  // Regardless of setter/getter attribute, we save the default getter/setter
651  // selector names in anticipation of declaration of setter/getter methods.
652  PDecl->setGetterName(GetterSel, GetterNameLoc);
653  PDecl->setSetterName(SetterSel, SetterNameLoc);
655  makePropertyAttributesAsWritten(AttributesAsWritten));
656 
657  if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
659 
660  if (Attributes & ObjCDeclSpec::DQ_PR_getter)
662 
663  if (Attributes & ObjCDeclSpec::DQ_PR_setter)
665 
666  if (isReadWrite)
668 
669  if (Attributes & ObjCDeclSpec::DQ_PR_retain)
671 
672  if (Attributes & ObjCDeclSpec::DQ_PR_strong)
674 
675  if (Attributes & ObjCDeclSpec::DQ_PR_weak)
677 
678  if (Attributes & ObjCDeclSpec::DQ_PR_copy)
680 
681  if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
683 
684  if (isAssign)
686 
687  // In the semantic attributes, one of nonatomic or atomic is always set.
688  if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
690  else
692 
693  // 'unsafe_unretained' is alias for 'assign'.
694  if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained)
696  if (isAssign)
698 
699  if (MethodImplKind == tok::objc_required)
701  else if (MethodImplKind == tok::objc_optional)
703 
704  if (Attributes & ObjCDeclSpec::DQ_PR_nullability)
706 
707  if (Attributes & ObjCDeclSpec::DQ_PR_null_resettable)
709 
710  if (Attributes & ObjCDeclSpec::DQ_PR_class)
712 
713  if ((Attributes & ObjCDeclSpec::DQ_PR_direct) ||
714  CDecl->hasAttr<ObjCDirectMembersAttr>()) {
715  if (isa<ObjCProtocolDecl>(CDecl)) {
716  Diag(PDecl->getLocation(), diag::err_objc_direct_on_protocol) << true;
719  } else {
720  Diag(PDecl->getLocation(), diag::warn_objc_direct_property_ignored)
721  << PDecl->getDeclName();
722  }
723  }
724 
725  return PDecl;
726 }
727 
728 static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc,
729  ObjCPropertyDecl *property,
730  ObjCIvarDecl *ivar) {
731  if (property->isInvalidDecl() || ivar->isInvalidDecl()) return;
732 
733  QualType ivarType = ivar->getType();
734  Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime();
735 
736  // The lifetime implied by the property's attributes.
737  Qualifiers::ObjCLifetime propertyLifetime =
739  property->getType());
740 
741  // We're fine if they match.
742  if (propertyLifetime == ivarLifetime) return;
743 
744  // None isn't a valid lifetime for an object ivar in ARC, and
745  // __autoreleasing is never valid; don't diagnose twice.
746  if ((ivarLifetime == Qualifiers::OCL_None &&
747  S.getLangOpts().ObjCAutoRefCount) ||
748  ivarLifetime == Qualifiers::OCL_Autoreleasing)
749  return;
750 
751  // If the ivar is private, and it's implicitly __unsafe_unretained
752  // because of its type, then pretend it was actually implicitly
753  // __strong. This is only sound because we're processing the
754  // property implementation before parsing any method bodies.
755  if (ivarLifetime == Qualifiers::OCL_ExplicitNone &&
756  propertyLifetime == Qualifiers::OCL_Strong &&
758  SplitQualType split = ivarType.split();
759  if (split.Quals.hasObjCLifetime()) {
760  assert(ivarType->isObjCARCImplicitlyUnretainedType());
762  ivarType = S.Context.getQualifiedType(split);
763  ivar->setType(ivarType);
764  return;
765  }
766  }
767 
768  switch (propertyLifetime) {
770  S.Diag(ivar->getLocation(), diag::err_arc_strong_property_ownership)
771  << property->getDeclName()
772  << ivar->getDeclName()
773  << ivarLifetime;
774  break;
775 
777  S.Diag(ivar->getLocation(), diag::err_weak_property)
778  << property->getDeclName()
779  << ivar->getDeclName();
780  break;
781 
783  S.Diag(ivar->getLocation(), diag::err_arc_assign_property_ownership)
784  << property->getDeclName()
785  << ivar->getDeclName()
786  << ((property->getPropertyAttributesAsWritten()
788  break;
789 
791  llvm_unreachable("properties cannot be autoreleasing");
792 
794  // Any other property should be ignored.
795  return;
796  }
797 
798  S.Diag(property->getLocation(), diag::note_property_declare);
799  if (propertyImplLoc.isValid())
800  S.Diag(propertyImplLoc, diag::note_property_synthesize);
801 }
802 
803 /// setImpliedPropertyAttributeForReadOnlyProperty -
804 /// This routine evaludates life-time attributes for a 'readonly'
805 /// property with no known lifetime of its own, using backing
806 /// 'ivar's attribute, if any. If no backing 'ivar', property's
807 /// life-time is assumed 'strong'.
809  ObjCPropertyDecl *property, ObjCIvarDecl *ivar) {
810  Qualifiers::ObjCLifetime propertyLifetime =
812  property->getType());
813  if (propertyLifetime != Qualifiers::OCL_None)
814  return;
815 
816  if (!ivar) {
817  // if no backing ivar, make property 'strong'.
818  property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
819  return;
820  }
821  // property assumes owenership of backing ivar.
822  QualType ivarType = ivar->getType();
823  Qualifiers::ObjCLifetime ivarLifetime = ivarType.getObjCLifetime();
824  if (ivarLifetime == Qualifiers::OCL_Strong)
825  property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
826  else if (ivarLifetime == Qualifiers::OCL_Weak)
827  property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak);
828 }
829 
830 static bool
831 isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2,
833  return (Attr1 & Kind) != (Attr2 & Kind);
834 }
835 
836 static bool areIncompatiblePropertyAttributes(unsigned Attr1, unsigned Attr2,
837  unsigned Kinds) {
838  return ((Attr1 & Kinds) != 0) != ((Attr2 & Kinds) != 0);
839 }
840 
841 /// SelectPropertyForSynthesisFromProtocols - Finds the most appropriate
842 /// property declaration that should be synthesised in all of the inherited
843 /// protocols. It also diagnoses properties declared in inherited protocols with
844 /// mismatched types or attributes, since any of them can be candidate for
845 /// synthesis.
846 static ObjCPropertyDecl *
848  ObjCInterfaceDecl *ClassDecl,
850  assert(isa<ObjCProtocolDecl>(Property->getDeclContext()) &&
851  "Expected a property from a protocol");
854  for (const auto *PI : ClassDecl->all_referenced_protocols()) {
855  if (const ObjCProtocolDecl *PDecl = PI->getDefinition())
856  PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
857  Properties);
858  }
859  if (ObjCInterfaceDecl *SDecl = ClassDecl->getSuperClass()) {
860  while (SDecl) {
861  for (const auto *PI : SDecl->all_referenced_protocols()) {
862  if (const ObjCProtocolDecl *PDecl = PI->getDefinition())
863  PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
864  Properties);
865  }
866  SDecl = SDecl->getSuperClass();
867  }
868  }
869 
870  if (Properties.empty())
871  return Property;
872 
873  ObjCPropertyDecl *OriginalProperty = Property;
874  size_t SelectedIndex = 0;
875  for (const auto &Prop : llvm::enumerate(Properties)) {
876  // Select the 'readwrite' property if such property exists.
877  if (Property->isReadOnly() && !Prop.value()->isReadOnly()) {
878  Property = Prop.value();
879  SelectedIndex = Prop.index();
880  }
881  }
882  if (Property != OriginalProperty) {
883  // Check that the old property is compatible with the new one.
884  Properties[SelectedIndex] = OriginalProperty;
885  }
886 
887  QualType RHSType = S.Context.getCanonicalType(Property->getType());
888  unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
889  enum MismatchKind {
890  IncompatibleType = 0,
891  HasNoExpectedAttribute,
892  HasUnexpectedAttribute,
893  DifferentGetter,
894  DifferentSetter
895  };
896  // Represents a property from another protocol that conflicts with the
897  // selected declaration.
898  struct MismatchingProperty {
899  const ObjCPropertyDecl *Prop;
900  MismatchKind Kind;
901  StringRef AttributeName;
902  };
904  for (ObjCPropertyDecl *Prop : Properties) {
905  // Verify the property attributes.
906  unsigned Attr = Prop->getPropertyAttributesAsWritten();
907  if (Attr != OriginalAttributes) {
908  auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {
909  MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
910  : HasUnexpectedAttribute;
911  Mismatches.push_back({Prop, Kind, AttributeName});
912  };
913  // The ownership might be incompatible unless the property has no explicit
914  // ownership.
915  bool HasOwnership = (Attr & (ObjCPropertyDecl::OBJC_PR_retain |
921  if (HasOwnership &&
922  isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
924  Diag(OriginalAttributes & ObjCPropertyDecl::OBJC_PR_copy, "copy");
925  continue;
926  }
927  if (HasOwnership && areIncompatiblePropertyAttributes(
928  OriginalAttributes, Attr,
931  Diag(OriginalAttributes & (ObjCPropertyDecl::OBJC_PR_retain |
933  "retain (or strong)");
934  continue;
935  }
936  if (isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
938  Diag(OriginalAttributes & ObjCPropertyDecl::OBJC_PR_atomic, "atomic");
939  continue;
940  }
941  }
942  if (Property->getGetterName() != Prop->getGetterName()) {
943  Mismatches.push_back({Prop, DifferentGetter, ""});
944  continue;
945  }
946  if (!Property->isReadOnly() && !Prop->isReadOnly() &&
947  Property->getSetterName() != Prop->getSetterName()) {
948  Mismatches.push_back({Prop, DifferentSetter, ""});
949  continue;
950  }
951  QualType LHSType = S.Context.getCanonicalType(Prop->getType());
952  if (!S.Context.propertyTypesAreCompatible(LHSType, RHSType)) {
953  bool IncompatibleObjC = false;
954  QualType ConvertedType;
955  if (!S.isObjCPointerConversion(RHSType, LHSType, ConvertedType, IncompatibleObjC)
956  || IncompatibleObjC) {
957  Mismatches.push_back({Prop, IncompatibleType, ""});
958  continue;
959  }
960  }
961  }
962 
963  if (Mismatches.empty())
964  return Property;
965 
966  // Diagnose incompability.
967  {
968  bool HasIncompatibleAttributes = false;
969  for (const auto &Note : Mismatches)
970  HasIncompatibleAttributes =
971  Note.Kind != IncompatibleType ? true : HasIncompatibleAttributes;
972  // Promote the warning to an error if there are incompatible attributes or
973  // incompatible types together with readwrite/readonly incompatibility.
974  auto Diag = S.Diag(Property->getLocation(),
975  Property != OriginalProperty || HasIncompatibleAttributes
976  ? diag::err_protocol_property_mismatch
977  : diag::warn_protocol_property_mismatch);
978  Diag << Mismatches[0].Kind;
979  switch (Mismatches[0].Kind) {
980  case IncompatibleType:
981  Diag << Property->getType();
982  break;
983  case HasNoExpectedAttribute:
984  case HasUnexpectedAttribute:
985  Diag << Mismatches[0].AttributeName;
986  break;
987  case DifferentGetter:
988  Diag << Property->getGetterName();
989  break;
990  case DifferentSetter:
991  Diag << Property->getSetterName();
992  break;
993  }
994  }
995  for (const auto &Note : Mismatches) {
996  auto Diag =
997  S.Diag(Note.Prop->getLocation(), diag::note_protocol_property_declare)
998  << Note.Kind;
999  switch (Note.Kind) {
1000  case IncompatibleType:
1001  Diag << Note.Prop->getType();
1002  break;
1003  case HasNoExpectedAttribute:
1004  case HasUnexpectedAttribute:
1005  Diag << Note.AttributeName;
1006  break;
1007  case DifferentGetter:
1008  Diag << Note.Prop->getGetterName();
1009  break;
1010  case DifferentSetter:
1011  Diag << Note.Prop->getSetterName();
1012  break;
1013  }
1014  }
1015  if (AtLoc.isValid())
1016  S.Diag(AtLoc, diag::note_property_synthesize);
1017 
1018  return Property;
1019 }
1020 
1021 /// Determine whether any storage attributes were written on the property.
1023  ObjCPropertyQueryKind QueryKind) {
1024  if (Prop->getPropertyAttributesAsWritten() & OwnershipMask) return true;
1025 
1026  // If this is a readwrite property in a class extension that refines
1027  // a readonly property in the original class definition, check it as
1028  // well.
1029 
1030  // If it's a readonly property, we're not interested.
1031  if (Prop->isReadOnly()) return false;
1032 
1033  // Is it declared in an extension?
1034  auto Category = dyn_cast<ObjCCategoryDecl>(Prop->getDeclContext());
1035  if (!Category || !Category->IsClassExtension()) return false;
1036 
1037  // Find the corresponding property in the primary class definition.
1038  auto OrigClass = Category->getClassInterface();
1039  for (auto Found : OrigClass->lookup(Prop->getDeclName())) {
1040  if (ObjCPropertyDecl *OrigProp = dyn_cast<ObjCPropertyDecl>(Found))
1041  return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;
1042  }
1043 
1044  // Look through all of the protocols.
1045  for (const auto *Proto : OrigClass->all_referenced_protocols()) {
1046  if (ObjCPropertyDecl *OrigProp = Proto->FindPropertyDeclaration(
1047  Prop->getIdentifier(), QueryKind))
1048  return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;
1049  }
1050 
1051  return false;
1052 }
1053 
1054 /// Create a synthesized property accessor stub inside the \@implementation.
1055 static ObjCMethodDecl *
1057  ObjCMethodDecl *AccessorDecl, SourceLocation AtLoc,
1058  SourceLocation PropertyLoc) {
1059  ObjCMethodDecl *Decl = AccessorDecl;
1061  Context, AtLoc.isValid() ? AtLoc : Decl->getBeginLoc(),
1062  PropertyLoc.isValid() ? PropertyLoc : Decl->getEndLoc(),
1063  Decl->getSelector(), Decl->getReturnType(),
1064  Decl->getReturnTypeSourceInfo(), Impl, Decl->isInstanceMethod(),
1065  Decl->isVariadic(), Decl->isPropertyAccessor(),
1066  /* isSynthesized*/ true, Decl->isImplicit(), Decl->isDefined(),
1068  ImplDecl->getMethodFamily();
1069  if (Decl->hasAttrs())
1070  ImplDecl->setAttrs(Decl->getAttrs());
1071  ImplDecl->setSelfDecl(Decl->getSelfDecl());
1072  ImplDecl->setCmdDecl(Decl->getCmdDecl());
1074  Decl->getSelectorLocs(SelLocs);
1075  ImplDecl->setMethodParams(Context, Decl->parameters(), SelLocs);
1076  ImplDecl->setLexicalDeclContext(Impl);
1077  ImplDecl->setDefined(false);
1078  return ImplDecl;
1079 }
1080 
1081 /// ActOnPropertyImplDecl - This routine performs semantic checks and
1082 /// builds the AST node for a property implementation declaration; declared
1083 /// as \@synthesize or \@dynamic.
1084 ///
1086  SourceLocation AtLoc,
1087  SourceLocation PropertyLoc,
1088  bool Synthesize,
1089  IdentifierInfo *PropertyId,
1090  IdentifierInfo *PropertyIvar,
1091  SourceLocation PropertyIvarLoc,
1092  ObjCPropertyQueryKind QueryKind) {
1093  ObjCContainerDecl *ClassImpDecl =
1094  dyn_cast<ObjCContainerDecl>(CurContext);
1095  // Make sure we have a context for the property implementation declaration.
1096  if (!ClassImpDecl) {
1097  Diag(AtLoc, diag::err_missing_property_context);
1098  return nullptr;
1099  }
1100  if (PropertyIvarLoc.isInvalid())
1101  PropertyIvarLoc = PropertyLoc;
1102  SourceLocation PropertyDiagLoc = PropertyLoc;
1103  if (PropertyDiagLoc.isInvalid())
1104  PropertyDiagLoc = ClassImpDecl->getBeginLoc();
1105  ObjCPropertyDecl *property = nullptr;
1106  ObjCInterfaceDecl *IDecl = nullptr;
1107  // Find the class or category class where this property must have
1108  // a declaration.
1109  ObjCImplementationDecl *IC = nullptr;
1110  ObjCCategoryImplDecl *CatImplClass = nullptr;
1111  if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
1112  IDecl = IC->getClassInterface();
1113  // We always synthesize an interface for an implementation
1114  // without an interface decl. So, IDecl is always non-zero.
1115  assert(IDecl &&
1116  "ActOnPropertyImplDecl - @implementation without @interface");
1117 
1118  // Look for this property declaration in the @implementation's @interface
1119  property = IDecl->FindPropertyDeclaration(PropertyId, QueryKind);
1120  if (!property) {
1121  Diag(PropertyLoc, diag::err_bad_property_decl) << IDecl->getDeclName();
1122  return nullptr;
1123  }
1124  if (property->isClassProperty() && Synthesize) {
1125  Diag(PropertyLoc, diag::err_synthesize_on_class_property) << PropertyId;
1126  return nullptr;
1127  }
1128  unsigned PIkind = property->getPropertyAttributesAsWritten();
1129  if ((PIkind & (ObjCPropertyDecl::OBJC_PR_atomic |
1131  if (AtLoc.isValid())
1132  Diag(AtLoc, diag::warn_implicit_atomic_property);
1133  else
1134  Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property);
1135  Diag(property->getLocation(), diag::note_property_declare);
1136  }
1137 
1138  if (const ObjCCategoryDecl *CD =
1139  dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
1140  if (!CD->IsClassExtension()) {
1141  Diag(PropertyLoc, diag::err_category_property) << CD->getDeclName();
1142  Diag(property->getLocation(), diag::note_property_declare);
1143  return nullptr;
1144  }
1145  }
1146  if (Synthesize&&
1148  property->hasAttr<IBOutletAttr>() &&
1149  !AtLoc.isValid()) {
1150  bool ReadWriteProperty = false;
1151  // Search into the class extensions and see if 'readonly property is
1152  // redeclared 'readwrite', then no warning is to be issued.
1153  for (auto *Ext : IDecl->known_extensions()) {
1154  DeclContext::lookup_result R = Ext->lookup(property->getDeclName());
1155  if (!R.empty())
1156  if (ObjCPropertyDecl *ExtProp = dyn_cast<ObjCPropertyDecl>(R[0])) {
1157  PIkind = ExtProp->getPropertyAttributesAsWritten();
1158  if (PIkind & ObjCPropertyDecl::OBJC_PR_readwrite) {
1159  ReadWriteProperty = true;
1160  break;
1161  }
1162  }
1163  }
1164 
1165  if (!ReadWriteProperty) {
1166  Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property)
1167  << property;
1168  SourceLocation readonlyLoc;
1169  if (LocPropertyAttribute(Context, "readonly",
1170  property->getLParenLoc(), readonlyLoc)) {
1171  SourceLocation endLoc =
1172  readonlyLoc.getLocWithOffset(strlen("readonly")-1);
1173  SourceRange ReadonlySourceRange(readonlyLoc, endLoc);
1174  Diag(property->getLocation(),
1175  diag::note_auto_readonly_iboutlet_fixup_suggest) <<
1176  FixItHint::CreateReplacement(ReadonlySourceRange, "readwrite");
1177  }
1178  }
1179  }
1180  if (Synthesize && isa<ObjCProtocolDecl>(property->getDeclContext()))
1181  property = SelectPropertyForSynthesisFromProtocols(*this, AtLoc, IDecl,
1182  property);
1183 
1184  } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
1185  if (Synthesize) {
1186  Diag(AtLoc, diag::err_synthesize_category_decl);
1187  return nullptr;
1188  }
1189  IDecl = CatImplClass->getClassInterface();
1190  if (!IDecl) {
1191  Diag(AtLoc, diag::err_missing_property_interface);
1192  return nullptr;
1193  }
1195  IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
1196 
1197  // If category for this implementation not found, it is an error which
1198  // has already been reported eralier.
1199  if (!Category)
1200  return nullptr;
1201  // Look for this property declaration in @implementation's category
1202  property = Category->FindPropertyDeclaration(PropertyId, QueryKind);
1203  if (!property) {
1204  Diag(PropertyLoc, diag::err_bad_category_property_decl)
1205  << Category->getDeclName();
1206  return nullptr;
1207  }
1208  } else {
1209  Diag(AtLoc, diag::err_bad_property_context);
1210  return nullptr;
1211  }
1212  ObjCIvarDecl *Ivar = nullptr;
1213  bool CompleteTypeErr = false;
1214  bool compat = true;
1215  // Check that we have a valid, previously declared ivar for @synthesize
1216  if (Synthesize) {
1217  // @synthesize
1218  if (!PropertyIvar)
1219  PropertyIvar = PropertyId;
1220  // Check that this is a previously declared 'ivar' in 'IDecl' interface
1221  ObjCInterfaceDecl *ClassDeclared;
1222  Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
1223  QualType PropType = property->getType();
1224  QualType PropertyIvarType = PropType.getNonReferenceType();
1225 
1226  if (RequireCompleteType(PropertyDiagLoc, PropertyIvarType,
1227  diag::err_incomplete_synthesized_property,
1228  property->getDeclName())) {
1229  Diag(property->getLocation(), diag::note_property_declare);
1230  CompleteTypeErr = true;
1231  }
1232 
1233  if (getLangOpts().ObjCAutoRefCount &&
1234  (property->getPropertyAttributesAsWritten() &
1236  PropertyIvarType->isObjCRetainableType()) {
1238  }
1239 
1241  = property->getPropertyAttributes();
1242 
1243  bool isARCWeak = false;
1244  if (kind & ObjCPropertyDecl::OBJC_PR_weak) {
1245  // Add GC __weak to the ivar type if the property is weak.
1246  if (getLangOpts().getGC() != LangOptions::NonGC) {
1247  assert(!getLangOpts().ObjCAutoRefCount);
1248  if (PropertyIvarType.isObjCGCStrong()) {
1249  Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);
1250  Diag(property->getLocation(), diag::note_property_declare);
1251  } else {
1252  PropertyIvarType =
1253  Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak);
1254  }
1255 
1256  // Otherwise, check whether ARC __weak is enabled and works with
1257  // the property type.
1258  } else {
1259  if (!getLangOpts().ObjCWeak) {
1260  // Only complain here when synthesizing an ivar.
1261  if (!Ivar) {
1262  Diag(PropertyDiagLoc,
1263  getLangOpts().ObjCWeakRuntime
1264  ? diag::err_synthesizing_arc_weak_property_disabled
1265  : diag::err_synthesizing_arc_weak_property_no_runtime);
1266  Diag(property->getLocation(), diag::note_property_declare);
1267  }
1268  CompleteTypeErr = true; // suppress later diagnostics about the ivar
1269  } else {
1270  isARCWeak = true;
1271  if (const ObjCObjectPointerType *ObjT =
1272  PropertyIvarType->getAs<ObjCObjectPointerType>()) {
1273  const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl();
1274  if (ObjI && ObjI->isArcWeakrefUnavailable()) {
1275  Diag(property->getLocation(),
1276  diag::err_arc_weak_unavailable_property)
1277  << PropertyIvarType;
1278  Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class)
1279  << ClassImpDecl->getName();
1280  }
1281  }
1282  }
1283  }
1284  }
1285 
1286  if (AtLoc.isInvalid()) {
1287  // Check when default synthesizing a property that there is
1288  // an ivar matching property name and issue warning; since this
1289  // is the most common case of not using an ivar used for backing
1290  // property in non-default synthesis case.
1291  ObjCInterfaceDecl *ClassDeclared=nullptr;
1292  ObjCIvarDecl *originalIvar =
1293  IDecl->lookupInstanceVariable(property->getIdentifier(),
1294  ClassDeclared);
1295  if (originalIvar) {
1296  Diag(PropertyDiagLoc,
1297  diag::warn_autosynthesis_property_ivar_match)
1298  << PropertyId << (Ivar == nullptr) << PropertyIvar
1299  << originalIvar->getIdentifier();
1300  Diag(property->getLocation(), diag::note_property_declare);
1301  Diag(originalIvar->getLocation(), diag::note_ivar_decl);
1302  }
1303  }
1304 
1305  if (!Ivar) {
1306  // In ARC, give the ivar a lifetime qualifier based on the
1307  // property attributes.
1308  if ((getLangOpts().ObjCAutoRefCount || isARCWeak) &&
1309  !PropertyIvarType.getObjCLifetime() &&
1310  PropertyIvarType->isObjCRetainableType()) {
1311 
1312  // It's an error if we have to do this and the user didn't
1313  // explicitly write an ownership attribute on the property.
1314  if (!hasWrittenStorageAttribute(property, QueryKind) &&
1316  Diag(PropertyDiagLoc,
1317  diag::err_arc_objc_property_default_assign_on_object);
1318  Diag(property->getLocation(), diag::note_property_declare);
1319  } else {
1320  Qualifiers::ObjCLifetime lifetime =
1321  getImpliedARCOwnership(kind, PropertyIvarType);
1322  assert(lifetime && "no lifetime for property?");
1323 
1324  Qualifiers qs;
1325  qs.addObjCLifetime(lifetime);
1326  PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);
1327  }
1328  }
1329 
1330  Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl,
1331  PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,
1332  PropertyIvarType, /*TInfo=*/nullptr,
1334  (Expr *)nullptr, true);
1335  if (RequireNonAbstractType(PropertyIvarLoc,
1336  PropertyIvarType,
1337  diag::err_abstract_type_in_decl,
1339  Diag(property->getLocation(), diag::note_property_declare);
1340  // An abstract type is as bad as an incomplete type.
1341  CompleteTypeErr = true;
1342  }
1343  if (!CompleteTypeErr) {
1344  const RecordType *RecordTy = PropertyIvarType->getAs<RecordType>();
1345  if (RecordTy && RecordTy->getDecl()->hasFlexibleArrayMember()) {
1346  Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)
1347  << PropertyIvarType;
1348  CompleteTypeErr = true; // suppress later diagnostics about the ivar
1349  }
1350  }
1351  if (CompleteTypeErr)
1352  Ivar->setInvalidDecl();
1353  ClassImpDecl->addDecl(Ivar);
1354  IDecl->makeDeclVisibleInContext(Ivar);
1355 
1357  Diag(PropertyDiagLoc, diag::err_missing_property_ivar_decl)
1358  << PropertyId;
1359  // Note! I deliberately want it to fall thru so, we have a
1360  // a property implementation and to avoid future warnings.
1361  } else if (getLangOpts().ObjCRuntime.isNonFragile() &&
1362  !declaresSameEntity(ClassDeclared, IDecl)) {
1363  Diag(PropertyDiagLoc, diag::err_ivar_in_superclass_use)
1364  << property->getDeclName() << Ivar->getDeclName()
1365  << ClassDeclared->getDeclName();
1366  Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
1367  << Ivar << Ivar->getName();
1368  // Note! I deliberately want it to fall thru so more errors are caught.
1369  }
1370  property->setPropertyIvarDecl(Ivar);
1371 
1372  QualType IvarType = Context.getCanonicalType(Ivar->getType());
1373 
1374  // Check that type of property and its ivar are type compatible.
1375  if (!Context.hasSameType(PropertyIvarType, IvarType)) {
1376  if (isa<ObjCObjectPointerType>(PropertyIvarType)
1377  && isa<ObjCObjectPointerType>(IvarType))
1378  compat =
1380  PropertyIvarType->getAs<ObjCObjectPointerType>(),
1381  IvarType->getAs<ObjCObjectPointerType>());
1382  else {
1383  compat = (CheckAssignmentConstraints(PropertyIvarLoc, PropertyIvarType,
1384  IvarType)
1385  == Compatible);
1386  }
1387  if (!compat) {
1388  Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1389  << property->getDeclName() << PropType
1390  << Ivar->getDeclName() << IvarType;
1391  Diag(Ivar->getLocation(), diag::note_ivar_decl);
1392  // Note! I deliberately want it to fall thru so, we have a
1393  // a property implementation and to avoid future warnings.
1394  }
1395  else {
1396  // FIXME! Rules for properties are somewhat different that those
1397  // for assignments. Use a new routine to consolidate all cases;
1398  // specifically for property redeclarations as well as for ivars.
1399  QualType lhsType =Context.getCanonicalType(PropertyIvarType).getUnqualifiedType();
1400  QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
1401  if (lhsType != rhsType &&
1402  lhsType->isArithmeticType()) {
1403  Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1404  << property->getDeclName() << PropType
1405  << Ivar->getDeclName() << IvarType;
1406  Diag(Ivar->getLocation(), diag::note_ivar_decl);
1407  // Fall thru - see previous comment
1408  }
1409  }
1410  // __weak is explicit. So it works on Canonical type.
1411  if ((PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak() &&
1412  getLangOpts().getGC() != LangOptions::NonGC)) {
1413  Diag(PropertyDiagLoc, diag::err_weak_property)
1414  << property->getDeclName() << Ivar->getDeclName();
1415  Diag(Ivar->getLocation(), diag::note_ivar_decl);
1416  // Fall thru - see previous comment
1417  }
1418  // Fall thru - see previous comment
1419  if ((property->getType()->isObjCObjectPointerType() ||
1420  PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak() &&
1421  getLangOpts().getGC() != LangOptions::NonGC) {
1422  Diag(PropertyDiagLoc, diag::err_strong_property)
1423  << property->getDeclName() << Ivar->getDeclName();
1424  // Fall thru - see previous comment
1425  }
1426  }
1427  if (getLangOpts().ObjCAutoRefCount || isARCWeak ||
1428  Ivar->getType().getObjCLifetime())
1429  checkARCPropertyImpl(*this, PropertyLoc, property, Ivar);
1430  } else if (PropertyIvar)
1431  // @dynamic
1432  Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);
1433 
1434  assert (property && "ActOnPropertyImplDecl - property declaration missing");
1435  ObjCPropertyImplDecl *PIDecl =
1436  ObjCPropertyImplDecl::Create(Context, CurContext, AtLoc, PropertyLoc,
1437  property,
1438  (Synthesize ?
1441  Ivar, PropertyIvarLoc);
1442 
1443  if (CompleteTypeErr || !compat)
1444  PIDecl->setInvalidDecl();
1445 
1446  if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
1447  getterMethod->createImplicitParams(Context, IDecl);
1448 
1449  // Redeclare the getter within the implementation as DeclContext.
1450  if (Synthesize) {
1451  // If the method hasn't been overridden, create a synthesized implementation.
1452  ObjCMethodDecl *OMD = ClassImpDecl->getMethod(
1453  getterMethod->getSelector(), getterMethod->isInstanceMethod());
1454  if (!OMD)
1455  OMD = RedeclarePropertyAccessor(Context, IC, getterMethod, AtLoc,
1456  PropertyLoc);
1457  PIDecl->setGetterMethodDecl(OMD);
1458  }
1459 
1460  if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr &&
1461  Ivar->getType()->isRecordType()) {
1462  // For Objective-C++, need to synthesize the AST for the IVAR object to be
1463  // returned by the getter as it must conform to C++'s copy-return rules.
1464  // FIXME. Eventually we want to do this for Objective-C as well.
1465  SynthesizedFunctionScope Scope(*this, getterMethod);
1466  ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
1467  DeclRefExpr *SelfExpr = new (Context)
1468  DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
1469  PropertyDiagLoc);
1470  MarkDeclRefReferenced(SelfExpr);
1471  Expr *LoadSelfExpr =
1473  CK_LValueToRValue, SelfExpr, nullptr,
1474  VK_RValue);
1475  Expr *IvarRefExpr =
1476  new (Context) ObjCIvarRefExpr(Ivar,
1477  Ivar->getUsageType(SelfDecl->getType()),
1478  PropertyDiagLoc,
1479  Ivar->getLocation(),
1480  LoadSelfExpr, true, true);
1482  InitializedEntity::InitializeResult(PropertyDiagLoc,
1483  getterMethod->getReturnType(),
1484  /*NRVO=*/false),
1485  PropertyDiagLoc, IvarRefExpr);
1486  if (!Res.isInvalid()) {
1487  Expr *ResExpr = Res.getAs<Expr>();
1488  if (ResExpr)
1489  ResExpr = MaybeCreateExprWithCleanups(ResExpr);
1490  PIDecl->setGetterCXXConstructor(ResExpr);
1491  }
1492  }
1493  if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
1494  !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
1495  Diag(getterMethod->getLocation(),
1496  diag::warn_property_getter_owning_mismatch);
1497  Diag(property->getLocation(), diag::note_property_declare);
1498  }
1499  if (getLangOpts().ObjCAutoRefCount && Synthesize)
1500  switch (getterMethod->getMethodFamily()) {
1501  case OMF_retain:
1502  case OMF_retainCount:
1503  case OMF_release:
1504  case OMF_autorelease:
1505  Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def)
1506  << 1 << getterMethod->getSelector();
1507  break;
1508  default:
1509  break;
1510  }
1511  }
1512 
1513  if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
1514  setterMethod->createImplicitParams(Context, IDecl);
1515 
1516  // Redeclare the setter within the implementation as DeclContext.
1517  if (Synthesize) {
1518  ObjCMethodDecl *OMD = ClassImpDecl->getMethod(
1519  setterMethod->getSelector(), setterMethod->isInstanceMethod());
1520  if (!OMD)
1521  OMD = RedeclarePropertyAccessor(Context, IC, setterMethod,
1522  AtLoc, PropertyLoc);
1523  PIDecl->setSetterMethodDecl(OMD);
1524  }
1525 
1526  if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr &&
1527  Ivar->getType()->isRecordType()) {
1528  // FIXME. Eventually we want to do this for Objective-C as well.
1529  SynthesizedFunctionScope Scope(*this, setterMethod);
1530  ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
1531  DeclRefExpr *SelfExpr = new (Context)
1532  DeclRefExpr(Context, SelfDecl, false, SelfDecl->getType(), VK_LValue,
1533  PropertyDiagLoc);
1534  MarkDeclRefReferenced(SelfExpr);
1535  Expr *LoadSelfExpr =
1537  CK_LValueToRValue, SelfExpr, nullptr,
1538  VK_RValue);
1539  Expr *lhs =
1540  new (Context) ObjCIvarRefExpr(Ivar,
1541  Ivar->getUsageType(SelfDecl->getType()),
1542  PropertyDiagLoc,
1543  Ivar->getLocation(),
1544  LoadSelfExpr, true, true);
1545  ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
1546  ParmVarDecl *Param = (*P);
1547  QualType T = Param->getType().getNonReferenceType();
1548  DeclRefExpr *rhs = new (Context)
1549  DeclRefExpr(Context, Param, false, T, VK_LValue, PropertyDiagLoc);
1550  MarkDeclRefReferenced(rhs);
1551  ExprResult Res = BuildBinOp(S, PropertyDiagLoc,
1552  BO_Assign, lhs, rhs);
1553  if (property->getPropertyAttributes() &
1555  Expr *callExpr = Res.getAs<Expr>();
1556  if (const CXXOperatorCallExpr *CXXCE =
1557  dyn_cast_or_null<CXXOperatorCallExpr>(callExpr))
1558  if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
1559  if (!FuncDecl->isTrivial())
1560  if (property->getType()->isReferenceType()) {
1561  Diag(PropertyDiagLoc,
1562  diag::err_atomic_property_nontrivial_assign_op)
1563  << property->getType();
1564  Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
1565  << FuncDecl;
1566  }
1567  }
1568  PIDecl->setSetterCXXAssignment(Res.getAs<Expr>());
1569  }
1570  }
1571 
1572  if (IC) {
1573  if (Synthesize)
1574  if (ObjCPropertyImplDecl *PPIDecl =
1575  IC->FindPropertyImplIvarDecl(PropertyIvar)) {
1576  Diag(PropertyLoc, diag::err_duplicate_ivar_use)
1577  << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1578  << PropertyIvar;
1579  Diag(PPIDecl->getLocation(), diag::note_previous_use);
1580  }
1581 
1582  if (ObjCPropertyImplDecl *PPIDecl
1583  = IC->FindPropertyImplDecl(PropertyId, QueryKind)) {
1584  Diag(PropertyLoc, diag::err_property_implemented) << PropertyId;
1585  Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1586  return nullptr;
1587  }
1588  IC->addPropertyImplementation(PIDecl);
1589  if (getLangOpts().ObjCDefaultSynthProperties &&
1591  !IDecl->isObjCRequiresPropertyDefs()) {
1592  // Diagnose if an ivar was lazily synthesdized due to a previous
1593  // use and if 1) property is @dynamic or 2) property is synthesized
1594  // but it requires an ivar of different name.
1595  ObjCInterfaceDecl *ClassDeclared=nullptr;
1596  ObjCIvarDecl *Ivar = nullptr;
1597  if (!Synthesize)
1598  Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
1599  else {
1600  if (PropertyIvar && PropertyIvar != PropertyId)
1601  Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
1602  }
1603  // Issue diagnostics only if Ivar belongs to current class.
1604  if (Ivar && Ivar->getSynthesize() &&
1605  declaresSameEntity(IC->getClassInterface(), ClassDeclared)) {
1606  Diag(Ivar->getLocation(), diag::err_undeclared_var_use)
1607  << PropertyId;
1608  Ivar->setInvalidDecl();
1609  }
1610  }
1611  } else {
1612  if (Synthesize)
1613  if (ObjCPropertyImplDecl *PPIDecl =
1614  CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
1615  Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)
1616  << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1617  << PropertyIvar;
1618  Diag(PPIDecl->getLocation(), diag::note_previous_use);
1619  }
1620 
1621  if (ObjCPropertyImplDecl *PPIDecl =
1622  CatImplClass->FindPropertyImplDecl(PropertyId, QueryKind)) {
1623  Diag(PropertyDiagLoc, diag::err_property_implemented) << PropertyId;
1624  Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1625  return nullptr;
1626  }
1627  CatImplClass->addPropertyImplementation(PIDecl);
1628  }
1629 
1630  return PIDecl;
1631 }
1632 
1633 //===----------------------------------------------------------------------===//
1634 // Helper methods.
1635 //===----------------------------------------------------------------------===//
1636 
1637 /// DiagnosePropertyMismatch - Compares two properties for their
1638 /// attributes and types and warns on a variety of inconsistencies.
1639 ///
1640 void
1642  ObjCPropertyDecl *SuperProperty,
1643  const IdentifierInfo *inheritedName,
1644  bool OverridingProtocolProperty) {
1646  Property->getPropertyAttributes();
1648  SuperProperty->getPropertyAttributes();
1649 
1650  // We allow readonly properties without an explicit ownership
1651  // (assign/unsafe_unretained/weak/retain/strong/copy) in super class
1652  // to be overridden by a property with any explicit ownership in the subclass.
1653  if (!OverridingProtocolProperty &&
1654  !getOwnershipRule(SAttr) && getOwnershipRule(CAttr))
1655  ;
1656  else {
1659  Diag(Property->getLocation(), diag::warn_readonly_property)
1660  << Property->getDeclName() << inheritedName;
1661  if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy)
1662  != (SAttr & ObjCPropertyDecl::OBJC_PR_copy))
1663  Diag(Property->getLocation(), diag::warn_property_attribute)
1664  << Property->getDeclName() << "copy" << inheritedName;
1665  else if (!(SAttr & ObjCPropertyDecl::OBJC_PR_readonly)){
1666  unsigned CAttrRetain =
1667  (CAttr &
1669  unsigned SAttrRetain =
1670  (SAttr &
1672  bool CStrong = (CAttrRetain != 0);
1673  bool SStrong = (SAttrRetain != 0);
1674  if (CStrong != SStrong)
1675  Diag(Property->getLocation(), diag::warn_property_attribute)
1676  << Property->getDeclName() << "retain (or strong)" << inheritedName;
1677  }
1678  }
1679 
1680  // Check for nonatomic; note that nonatomic is effectively
1681  // meaningless for readonly properties, so don't diagnose if the
1682  // atomic property is 'readonly'.
1683  checkAtomicPropertyMismatch(*this, SuperProperty, Property, false);
1684  // Readonly properties from protocols can be implemented as "readwrite"
1685  // with a custom setter name.
1686  if (Property->getSetterName() != SuperProperty->getSetterName() &&
1687  !(SuperProperty->isReadOnly() &&
1688  isa<ObjCProtocolDecl>(SuperProperty->getDeclContext()))) {
1689  Diag(Property->getLocation(), diag::warn_property_attribute)
1690  << Property->getDeclName() << "setter" << inheritedName;
1691  Diag(SuperProperty->getLocation(), diag::note_property_declare);
1692  }
1693  if (Property->getGetterName() != SuperProperty->getGetterName()) {
1694  Diag(Property->getLocation(), diag::warn_property_attribute)
1695  << Property->getDeclName() << "getter" << inheritedName;
1696  Diag(SuperProperty->getLocation(), diag::note_property_declare);
1697  }
1698 
1699  QualType LHSType =
1700  Context.getCanonicalType(SuperProperty->getType());
1701  QualType RHSType =
1702  Context.getCanonicalType(Property->getType());
1703 
1704  if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) {
1705  // Do cases not handled in above.
1706  // FIXME. For future support of covariant property types, revisit this.
1707  bool IncompatibleObjC = false;
1708  QualType ConvertedType;
1709  if (!isObjCPointerConversion(RHSType, LHSType,
1710  ConvertedType, IncompatibleObjC) ||
1711  IncompatibleObjC) {
1712  Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
1713  << Property->getType() << SuperProperty->getType() << inheritedName;
1714  Diag(SuperProperty->getLocation(), diag::note_property_declare);
1715  }
1716  }
1717 }
1718 
1720  ObjCMethodDecl *GetterMethod,
1721  SourceLocation Loc) {
1722  if (!GetterMethod)
1723  return false;
1724  QualType GetterType = GetterMethod->getReturnType().getNonReferenceType();
1725  QualType PropertyRValueType =
1726  property->getType().getNonReferenceType().getAtomicUnqualifiedType();
1727  bool compat = Context.hasSameType(PropertyRValueType, GetterType);
1728  if (!compat) {
1729  const ObjCObjectPointerType *propertyObjCPtr = nullptr;
1730  const ObjCObjectPointerType *getterObjCPtr = nullptr;
1731  if ((propertyObjCPtr =
1732  PropertyRValueType->getAs<ObjCObjectPointerType>()) &&
1733  (getterObjCPtr = GetterType->getAs<ObjCObjectPointerType>()))
1734  compat = Context.canAssignObjCInterfaces(getterObjCPtr, propertyObjCPtr);
1735  else if (CheckAssignmentConstraints(Loc, GetterType, PropertyRValueType)
1736  != Compatible) {
1737  Diag(Loc, diag::err_property_accessor_type)
1738  << property->getDeclName() << PropertyRValueType
1739  << GetterMethod->getSelector() << GetterType;
1740  Diag(GetterMethod->getLocation(), diag::note_declared_at);
1741  return true;
1742  } else {
1743  compat = true;
1744  QualType lhsType = Context.getCanonicalType(PropertyRValueType);
1745  QualType rhsType =Context.getCanonicalType(GetterType).getUnqualifiedType();
1746  if (lhsType != rhsType && lhsType->isArithmeticType())
1747  compat = false;
1748  }
1749  }
1750 
1751  if (!compat) {
1752  Diag(Loc, diag::warn_accessor_property_type_mismatch)
1753  << property->getDeclName()
1754  << GetterMethod->getSelector();
1755  Diag(GetterMethod->getLocation(), diag::note_declared_at);
1756  return true;
1757  }
1758 
1759  return false;
1760 }
1761 
1762 /// CollectImmediateProperties - This routine collects all properties in
1763 /// the class and its conforming protocols; but not those in its super class.
1764 static void
1767  ObjCContainerDecl::PropertyMap &SuperPropMap,
1768  bool CollectClassPropsOnly = false,
1769  bool IncludeProtocols = true) {
1770  if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
1771  for (auto *Prop : IDecl->properties()) {
1772  if (CollectClassPropsOnly && !Prop->isClassProperty())
1773  continue;
1774  PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1775  Prop;
1776  }
1777 
1778  // Collect the properties from visible extensions.
1779  for (auto *Ext : IDecl->visible_extensions())
1780  CollectImmediateProperties(Ext, PropMap, SuperPropMap,
1781  CollectClassPropsOnly, IncludeProtocols);
1782 
1783  if (IncludeProtocols) {
1784  // Scan through class's protocols.
1785  for (auto *PI : IDecl->all_referenced_protocols())
1786  CollectImmediateProperties(PI, PropMap, SuperPropMap,
1787  CollectClassPropsOnly);
1788  }
1789  }
1790  if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
1791  for (auto *Prop : CATDecl->properties()) {
1792  if (CollectClassPropsOnly && !Prop->isClassProperty())
1793  continue;
1794  PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1795  Prop;
1796  }
1797  if (IncludeProtocols) {
1798  // Scan through class's protocols.
1799  for (auto *PI : CATDecl->protocols())
1800  CollectImmediateProperties(PI, PropMap, SuperPropMap,
1801  CollectClassPropsOnly);
1802  }
1803  }
1804  else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
1805  for (auto *Prop : PDecl->properties()) {
1806  if (CollectClassPropsOnly && !Prop->isClassProperty())
1807  continue;
1808  ObjCPropertyDecl *PropertyFromSuper =
1809  SuperPropMap[std::make_pair(Prop->getIdentifier(),
1810  Prop->isClassProperty())];
1811  // Exclude property for protocols which conform to class's super-class,
1812  // as super-class has to implement the property.
1813  if (!PropertyFromSuper ||
1814  PropertyFromSuper->getIdentifier() != Prop->getIdentifier()) {
1815  ObjCPropertyDecl *&PropEntry =
1816  PropMap[std::make_pair(Prop->getIdentifier(),
1817  Prop->isClassProperty())];
1818  if (!PropEntry)
1819  PropEntry = Prop;
1820  }
1821  }
1822  // Scan through protocol's protocols.
1823  for (auto *PI : PDecl->protocols())
1824  CollectImmediateProperties(PI, PropMap, SuperPropMap,
1825  CollectClassPropsOnly);
1826  }
1827 }
1828 
1829 /// CollectSuperClassPropertyImplementations - This routine collects list of
1830 /// properties to be implemented in super class(s) and also coming from their
1831 /// conforming protocols.
1833  ObjCInterfaceDecl::PropertyMap &PropMap) {
1834  if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) {
1836  while (SDecl) {
1837  SDecl->collectPropertiesToImplement(PropMap, PO);
1838  SDecl = SDecl->getSuperClass();
1839  }
1840  }
1841 }
1842 
1843 /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is
1844 /// an ivar synthesized for 'Method' and 'Method' is a property accessor
1845 /// declared in class 'IFace'.
1846 bool
1848  ObjCMethodDecl *Method, ObjCIvarDecl *IV) {
1849  if (!IV->getSynthesize())
1850  return false;
1851  ObjCMethodDecl *IMD = IFace->lookupMethod(Method->getSelector(),
1852  Method->isInstanceMethod());
1853  if (!IMD || !IMD->isPropertyAccessor())
1854  return false;
1855 
1856  // look up a property declaration whose one of its accessors is implemented
1857  // by this method.
1858  for (const auto *Property : IFace->instance_properties()) {
1859  if ((Property->getGetterName() == IMD->getSelector() ||
1860  Property->getSetterName() == IMD->getSelector()) &&
1861  (Property->getPropertyIvarDecl() == IV))
1862  return true;
1863  }
1864  // Also look up property declaration in class extension whose one of its
1865  // accessors is implemented by this method.
1866  for (const auto *Ext : IFace->known_extensions())
1867  for (const auto *Property : Ext->instance_properties())
1868  if ((Property->getGetterName() == IMD->getSelector() ||
1869  Property->getSetterName() == IMD->getSelector()) &&
1870  (Property->getPropertyIvarDecl() == IV))
1871  return true;
1872  return false;
1873 }
1874 
1876  ObjCPropertyDecl *Prop) {
1877  bool SuperClassImplementsGetter = false;
1878  bool SuperClassImplementsSetter = false;
1880  SuperClassImplementsSetter = true;
1881 
1882  while (IDecl->getSuperClass()) {
1883  ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
1884  if (!SuperClassImplementsGetter && SDecl->getInstanceMethod(Prop->getGetterName()))
1885  SuperClassImplementsGetter = true;
1886 
1887  if (!SuperClassImplementsSetter && SDecl->getInstanceMethod(Prop->getSetterName()))
1888  SuperClassImplementsSetter = true;
1889  if (SuperClassImplementsGetter && SuperClassImplementsSetter)
1890  return true;
1891  IDecl = IDecl->getSuperClass();
1892  }
1893  return false;
1894 }
1895 
1896 /// Default synthesizes all properties which must be synthesized
1897 /// in class's \@implementation.
1899  ObjCInterfaceDecl *IDecl,
1900  SourceLocation AtEnd) {
1903  IDecl->collectPropertiesToImplement(PropMap, PropertyOrder);
1904  if (PropMap.empty())
1905  return;
1906  ObjCInterfaceDecl::PropertyMap SuperPropMap;
1907  CollectSuperClassPropertyImplementations(IDecl, SuperPropMap);
1908 
1909  for (unsigned i = 0, e = PropertyOrder.size(); i != e; i++) {
1910  ObjCPropertyDecl *Prop = PropertyOrder[i];
1911  // Is there a matching property synthesize/dynamic?
1912  if (Prop->isInvalidDecl() ||
1913  Prop->isClassProperty() ||
1915  continue;
1916  // Property may have been synthesized by user.
1917  if (IMPDecl->FindPropertyImplDecl(
1918  Prop->getIdentifier(), Prop->getQueryKind()))
1919  continue;
1920  ObjCMethodDecl *ImpMethod = IMPDecl->getInstanceMethod(Prop->getGetterName());
1921  if (ImpMethod && !ImpMethod->getBody()) {
1923  continue;
1924  ImpMethod = IMPDecl->getInstanceMethod(Prop->getSetterName());
1925  if (ImpMethod && !ImpMethod->getBody())
1926  continue;
1927  }
1928  if (ObjCPropertyImplDecl *PID =
1929  IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) {
1930  Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
1931  << Prop->getIdentifier();
1932  if (PID->getLocation().isValid())
1933  Diag(PID->getLocation(), diag::note_property_synthesize);
1934  continue;
1935  }
1936  ObjCPropertyDecl *PropInSuperClass =
1937  SuperPropMap[std::make_pair(Prop->getIdentifier(),
1938  Prop->isClassProperty())];
1939  if (ObjCProtocolDecl *Proto =
1940  dyn_cast<ObjCProtocolDecl>(Prop->getDeclContext())) {
1941  // We won't auto-synthesize properties declared in protocols.
1942  // Suppress the warning if class's superclass implements property's
1943  // getter and implements property's setter (if readwrite property).
1944  // Or, if property is going to be implemented in its super class.
1945  if (!SuperClassImplementsProperty(IDecl, Prop) && !PropInSuperClass) {
1946  Diag(IMPDecl->getLocation(),
1947  diag::warn_auto_synthesizing_protocol_property)
1948  << Prop << Proto;
1949  Diag(Prop->getLocation(), diag::note_property_declare);
1950  std::string FixIt =
1951  (Twine("@synthesize ") + Prop->getName() + ";\n\n").str();
1952  Diag(AtEnd, diag::note_add_synthesize_directive)
1953  << FixItHint::CreateInsertion(AtEnd, FixIt);
1954  }
1955  continue;
1956  }
1957  // If property to be implemented in the super class, ignore.
1958  if (PropInSuperClass) {
1960  (PropInSuperClass->getPropertyAttributes() &
1962  !IMPDecl->getInstanceMethod(Prop->getSetterName()) &&
1963  !IDecl->HasUserDeclaredSetterMethod(Prop)) {
1964  Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
1965  << Prop->getIdentifier();
1966  Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
1967  }
1968  else {
1969  Diag(Prop->getLocation(), diag::warn_autosynthesis_property_in_superclass)
1970  << Prop->getIdentifier();
1971  Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
1972  Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
1973  }
1974  continue;
1975  }
1976  // We use invalid SourceLocations for the synthesized ivars since they
1977  // aren't really synthesized at a particular location; they just exist.
1978  // Saying that they are located at the @implementation isn't really going
1979  // to help users.
1980  ObjCPropertyImplDecl *PIDecl = dyn_cast_or_null<ObjCPropertyImplDecl>(
1982  true,
1983  /* property = */ Prop->getIdentifier(),
1984  /* ivar = */ Prop->getDefaultSynthIvarName(Context),
1985  Prop->getLocation(), Prop->getQueryKind()));
1986  if (PIDecl && !Prop->isUnavailable()) {
1987  Diag(Prop->getLocation(), diag::warn_missing_explicit_synthesis);
1988  Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
1989  }
1990  }
1991 }
1992 
1994  SourceLocation AtEnd) {
1995  if (!LangOpts.ObjCDefaultSynthProperties || LangOpts.ObjCRuntime.isFragile())
1996  return;
1997  ObjCImplementationDecl *IC=dyn_cast_or_null<ObjCImplementationDecl>(D);
1998  if (!IC)
1999  return;
2000  if (ObjCInterfaceDecl* IDecl = IC->getClassInterface())
2001  if (!IDecl->isObjCRequiresPropertyDefs())
2002  DefaultSynthesizeProperties(S, IC, IDecl, AtEnd);
2003 }
2004 
2006  Sema &S, ObjCInterfaceDecl *PrimaryClass, Selector Method,
2007  ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, ObjCCategoryDecl *C,
2008  ObjCPropertyDecl *Prop,
2009  llvm::SmallPtrSet<const ObjCMethodDecl *, 8> &SMap) {
2010  // Check to see if we have a corresponding selector in SMap and with the
2011  // right method type.
2012  auto I = llvm::find_if(SMap, [&](const ObjCMethodDecl *x) {
2013  return x->getSelector() == Method &&
2014  x->isClassMethod() == Prop->isClassProperty();
2015  });
2016  // When reporting on missing property setter/getter implementation in
2017  // categories, do not report when they are declared in primary class,
2018  // class's protocol, or one of it super classes. This is because,
2019  // the class is going to implement them.
2020  if (I == SMap.end() &&
2021  (PrimaryClass == nullptr ||
2022  !PrimaryClass->lookupPropertyAccessor(Method, C,
2023  Prop->isClassProperty()))) {
2024  unsigned diag =
2025  isa<ObjCCategoryDecl>(CDecl)
2026  ? (Prop->isClassProperty()
2027  ? diag::warn_impl_required_in_category_for_class_property
2028  : diag::warn_setter_getter_impl_required_in_category)
2029  : (Prop->isClassProperty()
2030  ? diag::warn_impl_required_for_class_property
2031  : diag::warn_setter_getter_impl_required);
2032  S.Diag(IMPDecl->getLocation(), diag) << Prop->getDeclName() << Method;
2033  S.Diag(Prop->getLocation(), diag::note_property_declare);
2034  if (S.LangOpts.ObjCDefaultSynthProperties &&
2036  if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl))
2037  if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs())
2038  S.Diag(RID->getLocation(), diag::note_suppressed_class_declare);
2039  }
2040 }
2041 
2043  ObjCContainerDecl *CDecl,
2044  bool SynthesizeProperties) {
2046  ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
2047 
2048  // Since we don't synthesize class properties, we should emit diagnose even
2049  // if SynthesizeProperties is true.
2050  ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
2051  // Gather properties which need not be implemented in this class
2052  // or category.
2053  if (!IDecl)
2054  if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
2055  // For categories, no need to implement properties declared in
2056  // its primary class (and its super classes) if property is
2057  // declared in one of those containers.
2058  if ((IDecl = C->getClassInterface())) {
2060  IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO);
2061  }
2062  }
2063  if (IDecl)
2064  CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap);
2065 
2066  // When SynthesizeProperties is true, we only check class properties.
2067  CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap,
2068  SynthesizeProperties/*CollectClassPropsOnly*/);
2069 
2070  // Scan the @interface to see if any of the protocols it adopts
2071  // require an explicit implementation, via attribute
2072  // 'objc_protocol_requires_explicit_implementation'.
2073  if (IDecl) {
2074  std::unique_ptr<ObjCContainerDecl::PropertyMap> LazyMap;
2075 
2076  for (auto *PDecl : IDecl->all_referenced_protocols()) {
2077  if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
2078  continue;
2079  // Lazily construct a set of all the properties in the @interface
2080  // of the class, without looking at the superclass. We cannot
2081  // use the call to CollectImmediateProperties() above as that
2082  // utilizes information from the super class's properties as well
2083  // as scans the adopted protocols. This work only triggers for protocols
2084  // with the attribute, which is very rare, and only occurs when
2085  // analyzing the @implementation.
2086  if (!LazyMap) {
2087  ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
2088  LazyMap.reset(new ObjCContainerDecl::PropertyMap());
2089  CollectImmediateProperties(CDecl, *LazyMap, NoNeedToImplPropMap,
2090  /* CollectClassPropsOnly */ false,
2091  /* IncludeProtocols */ false);
2092  }
2093  // Add the properties of 'PDecl' to the list of properties that
2094  // need to be implemented.
2095  for (auto *PropDecl : PDecl->properties()) {
2096  if ((*LazyMap)[std::make_pair(PropDecl->getIdentifier(),
2097  PropDecl->isClassProperty())])
2098  continue;
2099  PropMap[std::make_pair(PropDecl->getIdentifier(),
2100  PropDecl->isClassProperty())] = PropDecl;
2101  }
2102  }
2103  }
2104 
2105  if (PropMap.empty())
2106  return;
2107 
2109  for (const auto *I : IMPDecl->property_impls())
2110  PropImplMap.insert(I->getPropertyDecl());
2111 
2112  llvm::SmallPtrSet<const ObjCMethodDecl *, 8> InsMap;
2113  // Collect property accessors implemented in current implementation.
2114  for (const auto *I : IMPDecl->methods())
2115  InsMap.insert(I);
2116 
2117  ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
2118  ObjCInterfaceDecl *PrimaryClass = nullptr;
2119  if (C && !C->IsClassExtension())
2120  if ((PrimaryClass = C->getClassInterface()))
2121  // Report unimplemented properties in the category as well.
2122  if (ObjCImplDecl *IMP = PrimaryClass->getImplementation()) {
2123  // When reporting on missing setter/getters, do not report when
2124  // setter/getter is implemented in category's primary class
2125  // implementation.
2126  for (const auto *I : IMP->methods())
2127  InsMap.insert(I);
2128  }
2129 
2130  for (ObjCContainerDecl::PropertyMap::iterator
2131  P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
2132  ObjCPropertyDecl *Prop = P->second;
2133  // Is there a matching property synthesize/dynamic?
2134  if (Prop->isInvalidDecl() ||
2136  PropImplMap.count(Prop) ||
2137  Prop->getAvailability() == AR_Unavailable)
2138  continue;
2139 
2140  // Diagnose unimplemented getters and setters.
2142  PrimaryClass, Prop->getGetterName(), IMPDecl, CDecl, C, Prop, InsMap);
2143  if (!Prop->isReadOnly())
2145  PrimaryClass, Prop->getSetterName(),
2146  IMPDecl, CDecl, C, Prop, InsMap);
2147  }
2148 }
2149 
2151  for (const auto *propertyImpl : impDecl->property_impls()) {
2152  const auto *property = propertyImpl->getPropertyDecl();
2153  // Warn about null_resettable properties with synthesized setters,
2154  // because the setter won't properly handle nil.
2155  if (propertyImpl->getPropertyImplementation()
2157  (property->getPropertyAttributes() &
2159  property->getGetterMethodDecl() &&
2160  property->getSetterMethodDecl()) {
2161  auto *getterImpl = propertyImpl->getGetterMethodDecl();
2162  auto *setterImpl = propertyImpl->getSetterMethodDecl();
2163  if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) &&
2164  (!setterImpl || setterImpl->isSynthesizedAccessorStub())) {
2165  SourceLocation loc = propertyImpl->getLocation();
2166  if (loc.isInvalid())
2167  loc = impDecl->getBeginLoc();
2168 
2169  Diag(loc, diag::warn_null_resettable_setter)
2170  << setterImpl->getSelector() << property->getDeclName();
2171  }
2172  }
2173  }
2174 }
2175 
2176 void
2178  ObjCInterfaceDecl* IDecl) {
2179  // Rules apply in non-GC mode only
2180  if (getLangOpts().getGC() != LangOptions::NonGC)
2181  return;
2183  for (auto *Prop : IDecl->properties())
2184  PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2185  for (const auto *Ext : IDecl->known_extensions())
2186  for (auto *Prop : Ext->properties())
2187  PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2188 
2189  for (ObjCContainerDecl::PropertyMap::iterator I = PM.begin(), E = PM.end();
2190  I != E; ++I) {
2191  const ObjCPropertyDecl *Property = I->second;
2192  ObjCMethodDecl *GetterMethod = nullptr;
2193  ObjCMethodDecl *SetterMethod = nullptr;
2194 
2195  unsigned Attributes = Property->getPropertyAttributes();
2196  unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten();
2197 
2198  if (!(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic) &&
2199  !(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_nonatomic)) {
2200  GetterMethod = Property->isClassProperty() ?
2201  IMPDecl->getClassMethod(Property->getGetterName()) :
2202  IMPDecl->getInstanceMethod(Property->getGetterName());
2203  SetterMethod = Property->isClassProperty() ?
2204  IMPDecl->getClassMethod(Property->getSetterName()) :
2205  IMPDecl->getInstanceMethod(Property->getSetterName());
2206  if (GetterMethod && GetterMethod->isSynthesizedAccessorStub())
2207  GetterMethod = nullptr;
2208  if (SetterMethod && SetterMethod->isSynthesizedAccessorStub())
2209  SetterMethod = nullptr;
2210  if (GetterMethod) {
2211  Diag(GetterMethod->getLocation(),
2212  diag::warn_default_atomic_custom_getter_setter)
2213  << Property->getIdentifier() << 0;
2214  Diag(Property->getLocation(), diag::note_property_declare);
2215  }
2216  if (SetterMethod) {
2217  Diag(SetterMethod->getLocation(),
2218  diag::warn_default_atomic_custom_getter_setter)
2219  << Property->getIdentifier() << 1;
2220  Diag(Property->getLocation(), diag::note_property_declare);
2221  }
2222  }
2223 
2224  // We only care about readwrite atomic property.
2225  if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) ||
2226  !(Attributes & ObjCPropertyDecl::OBJC_PR_readwrite))
2227  continue;
2228  if (const ObjCPropertyImplDecl *PIDecl = IMPDecl->FindPropertyImplDecl(
2229  Property->getIdentifier(), Property->getQueryKind())) {
2230  if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
2231  continue;
2232  GetterMethod = PIDecl->getGetterMethodDecl();
2233  SetterMethod = PIDecl->getSetterMethodDecl();
2234  if (GetterMethod && GetterMethod->isSynthesizedAccessorStub())
2235  GetterMethod = nullptr;
2236  if (SetterMethod && SetterMethod->isSynthesizedAccessorStub())
2237  SetterMethod = nullptr;
2238  if ((bool)GetterMethod ^ (bool)SetterMethod) {
2239  SourceLocation MethodLoc =
2240  (GetterMethod ? GetterMethod->getLocation()
2241  : SetterMethod->getLocation());
2242  Diag(MethodLoc, diag::warn_atomic_property_rule)
2243  << Property->getIdentifier() << (GetterMethod != nullptr)
2244  << (SetterMethod != nullptr);
2245  // fixit stuff.
2246  if (Property->getLParenLoc().isValid() &&
2247  !(AttributesAsWritten & ObjCPropertyDecl::OBJC_PR_atomic)) {
2248  // @property () ... case.
2249  SourceLocation AfterLParen =
2250  getLocForEndOfToken(Property->getLParenLoc());
2251  StringRef NonatomicStr = AttributesAsWritten? "nonatomic, "
2252  : "nonatomic";
2253  Diag(Property->getLocation(),
2254  diag::note_atomic_property_fixup_suggest)
2255  << FixItHint::CreateInsertion(AfterLParen, NonatomicStr);
2256  } else if (Property->getLParenLoc().isInvalid()) {
2257  //@property id etc.
2258  SourceLocation startLoc =
2259  Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
2260  Diag(Property->getLocation(),
2261  diag::note_atomic_property_fixup_suggest)
2262  << FixItHint::CreateInsertion(startLoc, "(nonatomic) ");
2263  }
2264  else
2265  Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);
2266  Diag(Property->getLocation(), diag::note_property_declare);
2267  }
2268  }
2269  }
2270 }
2271 
2273  if (getLangOpts().getGC() == LangOptions::GCOnly)
2274  return;
2275 
2276  for (const auto *PID : D->property_impls()) {
2277  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
2278  if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() &&
2279  !PD->isClassProperty()) {
2280  ObjCMethodDecl *IM = PID->getGetterMethodDecl();
2281  if (IM && !IM->isSynthesizedAccessorStub())
2282  continue;
2283  ObjCMethodDecl *method = PD->getGetterMethodDecl();
2284  if (!method)
2285  continue;
2286  ObjCMethodFamily family = method->getMethodFamily();
2287  if (family == OMF_alloc || family == OMF_copy ||
2288  family == OMF_mutableCopy || family == OMF_new) {
2289  if (getLangOpts().ObjCAutoRefCount)
2290  Diag(PD->getLocation(), diag::err_cocoa_naming_owned_rule);
2291  else
2292  Diag(PD->getLocation(), diag::warn_cocoa_naming_owned_rule);
2293 
2294  // Look for a getter explicitly declared alongside the property.
2295  // If we find one, use its location for the note.
2296  SourceLocation noteLoc = PD->getLocation();
2297  SourceLocation fixItLoc;
2298  for (auto *getterRedecl : method->redecls()) {
2299  if (getterRedecl->isImplicit())
2300  continue;
2301  if (getterRedecl->getDeclContext() != PD->getDeclContext())
2302  continue;
2303  noteLoc = getterRedecl->getLocation();
2304  fixItLoc = getterRedecl->getEndLoc();
2305  }
2306 
2308  TokenValue tokens[] = {
2309  tok::kw___attribute, tok::l_paren, tok::l_paren,
2310  PP.getIdentifierInfo("objc_method_family"), tok::l_paren,
2311  PP.getIdentifierInfo("none"), tok::r_paren,
2312  tok::r_paren, tok::r_paren
2313  };
2314  StringRef spelling = "__attribute__((objc_method_family(none)))";
2315  StringRef macroName = PP.getLastMacroWithSpelling(noteLoc, tokens);
2316  if (!macroName.empty())
2317  spelling = macroName;
2318 
2319  auto noteDiag = Diag(noteLoc, diag::note_cocoa_naming_declare_family)
2320  << method->getDeclName() << spelling;
2321  if (fixItLoc.isValid()) {
2322  SmallString<64> fixItText(" ");
2323  fixItText += spelling;
2324  noteDiag << FixItHint::CreateInsertion(fixItLoc, fixItText);
2325  }
2326  }
2327  }
2328  }
2329 }
2330 
2332  const ObjCImplementationDecl *ImplD,
2333  const ObjCInterfaceDecl *IFD) {
2334  assert(IFD->hasDesignatedInitializers());
2335  const ObjCInterfaceDecl *SuperD = IFD->getSuperClass();
2336  if (!SuperD)
2337  return;
2338 
2339  SelectorSet InitSelSet;
2340  for (const auto *I : ImplD->instance_methods())
2341  if (I->getMethodFamily() == OMF_init)
2342  InitSelSet.insert(I->getSelector());
2343 
2345  SuperD->getDesignatedInitializers(DesignatedInits);
2347  I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
2348  const ObjCMethodDecl *MD = *I;
2349  if (!InitSelSet.count(MD->getSelector())) {
2350  // Don't emit a diagnostic if the overriding method in the subclass is
2351  // marked as unavailable.
2352  bool Ignore = false;
2353  if (auto *IMD = IFD->getInstanceMethod(MD->getSelector())) {
2354  Ignore = IMD->isUnavailable();
2355  } else {
2356  // Check the methods declared in the class extensions too.
2357  for (auto *Ext : IFD->visible_extensions())
2358  if (auto *IMD = Ext->getInstanceMethod(MD->getSelector())) {
2359  Ignore = IMD->isUnavailable();
2360  break;
2361  }
2362  }
2363  if (!Ignore) {
2364  Diag(ImplD->getLocation(),
2365  diag::warn_objc_implementation_missing_designated_init_override)
2366  << MD->getSelector();
2367  Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here);
2368  }
2369  }
2370  }
2371 }
2372 
2373 /// AddPropertyAttrs - Propagates attributes from a property to the
2374 /// implicitly-declared getter or setter for that property.
2375 static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod,
2377  // Should we just clone all attributes over?
2378  for (const auto *A : Property->attrs()) {
2379  if (isa<DeprecatedAttr>(A) ||
2380  isa<UnavailableAttr>(A) ||
2381  isa<AvailabilityAttr>(A))
2382  PropertyMethod->addAttr(A->clone(S.Context));
2383  }
2384 }
2385 
2386 /// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods
2387 /// have the property type and issue diagnostics if they don't.
2388 /// Also synthesize a getter/setter method if none exist (and update the
2389 /// appropriate lookup tables.
2391  ObjCMethodDecl *GetterMethod, *SetterMethod;
2392  ObjCContainerDecl *CD = cast<ObjCContainerDecl>(property->getDeclContext());
2393  if (CD->isInvalidDecl())
2394  return;
2395 
2396  bool IsClassProperty = property->isClassProperty();
2397  GetterMethod = IsClassProperty ?
2398  CD->getClassMethod(property->getGetterName()) :
2399  CD->getInstanceMethod(property->getGetterName());
2400 
2401  // if setter or getter is not found in class extension, it might be
2402  // in the primary class.
2403  if (!GetterMethod)
2404  if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CD))
2405  if (CatDecl->IsClassExtension())
2406  GetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
2407  getClassMethod(property->getGetterName()) :
2408  CatDecl->getClassInterface()->
2409  getInstanceMethod(property->getGetterName());
2410 
2411  SetterMethod = IsClassProperty ?
2412  CD->getClassMethod(property->getSetterName()) :
2413  CD->getInstanceMethod(property->getSetterName());
2414  if (!SetterMethod)
2415  if (const ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CD))
2416  if (CatDecl->IsClassExtension())
2417  SetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
2418  getClassMethod(property->getSetterName()) :
2419  CatDecl->getClassInterface()->
2420  getInstanceMethod(property->getSetterName());
2421  DiagnosePropertyAccessorMismatch(property, GetterMethod,
2422  property->getLocation());
2423 
2424  if (!property->isReadOnly() && SetterMethod) {
2425  if (Context.getCanonicalType(SetterMethod->getReturnType()) !=
2426  Context.VoidTy)
2427  Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
2428  if (SetterMethod->param_size() != 1 ||
2430  (*SetterMethod->param_begin())->getType().getNonReferenceType(),
2431  property->getType().getNonReferenceType())) {
2432  Diag(property->getLocation(),
2433  diag::warn_accessor_property_type_mismatch)
2434  << property->getDeclName()
2435  << SetterMethod->getSelector();
2436  Diag(SetterMethod->getLocation(), diag::note_declared_at);
2437  }
2438  }
2439 
2440  // Synthesize getter/setter methods if none exist.
2441  // Find the default getter and if one not found, add one.
2442  // FIXME: The synthesized property we set here is misleading. We almost always
2443  // synthesize these methods unless the user explicitly provided prototypes
2444  // (which is odd, but allowed). Sema should be typechecking that the
2445  // declarations jive in that situation (which it is not currently).
2446  if (!GetterMethod) {
2447  // No instance/class method of same name as property getter name was found.
2448  // Declare a getter method and add it to the list of methods
2449  // for this class.
2450  SourceLocation Loc = property->getLocation();
2451 
2452  // The getter returns the declared property type with all qualifiers
2453  // removed.
2454  QualType resultTy = property->getType().getAtomicUnqualifiedType();
2455 
2456  // If the property is null_resettable, the getter returns nonnull.
2457  if (property->getPropertyAttributes() &
2459  QualType modifiedTy = resultTy;
2460  if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
2461  if (*nullability == NullabilityKind::Unspecified)
2462  resultTy = Context.getAttributedType(attr::TypeNonNull,
2463  modifiedTy, modifiedTy);
2464  }
2465  }
2466 
2467  GetterMethod = ObjCMethodDecl::Create(
2468  Context, Loc, Loc, property->getGetterName(), resultTy, nullptr, CD,
2469  !IsClassProperty, /*isVariadic=*/false,
2470  /*isPropertyAccessor=*/true, /*isSynthesizedAccessorStub=*/false,
2471  /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
2472  (property->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2475  CD->addDecl(GetterMethod);
2476 
2477  AddPropertyAttrs(*this, GetterMethod, property);
2478 
2479  if (property->isDirectProperty())
2480  GetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2481 
2482  if (property->hasAttr<NSReturnsNotRetainedAttr>())
2483  GetterMethod->addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context,
2484  Loc));
2485 
2486  if (property->hasAttr<ObjCReturnsInnerPointerAttr>())
2487  GetterMethod->addAttr(
2488  ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc));
2489 
2490  if (const SectionAttr *SA = property->getAttr<SectionAttr>())
2491  GetterMethod->addAttr(SectionAttr::CreateImplicit(
2492  Context, SA->getName(), Loc, AttributeCommonInfo::AS_GNU,
2493  SectionAttr::GNU_section));
2494 
2495  if (getLangOpts().ObjCAutoRefCount)
2496  CheckARCMethodDecl(GetterMethod);
2497  } else
2498  // A user declared getter will be synthesize when @synthesize of
2499  // the property with the same name is seen in the @implementation
2500  GetterMethod->setPropertyAccessor(true);
2501 
2502  GetterMethod->createImplicitParams(Context,
2503  GetterMethod->getClassInterface());
2504  property->setGetterMethodDecl(GetterMethod);
2505 
2506  // Skip setter if property is read-only.
2507  if (!property->isReadOnly()) {
2508  // Find the default setter and if one not found, add one.
2509  if (!SetterMethod) {
2510  // No instance/class method of same name as property setter name was
2511  // found.
2512  // Declare a setter method and add it to the list of methods
2513  // for this class.
2514  SourceLocation Loc = property->getLocation();
2515 
2516  SetterMethod =
2517  ObjCMethodDecl::Create(Context, Loc, Loc,
2518  property->getSetterName(), Context.VoidTy,
2519  nullptr, CD, !IsClassProperty,
2520  /*isVariadic=*/false,
2521  /*isPropertyAccessor=*/true,
2522  /*isSynthesizedAccessorStub=*/false,
2523  /*isImplicitlyDeclared=*/true,
2524  /*isDefined=*/false,
2525  (property->getPropertyImplementation() ==
2529 
2530  // Remove all qualifiers from the setter's parameter type.
2531  QualType paramTy =
2532  property->getType().getUnqualifiedType().getAtomicUnqualifiedType();
2533 
2534  // If the property is null_resettable, the setter accepts a
2535  // nullable value.
2536  if (property->getPropertyAttributes() &
2538  QualType modifiedTy = paramTy;
2539  if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
2540  if (*nullability == NullabilityKind::Unspecified)
2541  paramTy = Context.getAttributedType(attr::TypeNullable,
2542  modifiedTy, modifiedTy);
2543  }
2544  }
2545 
2546  // Invent the arguments for the setter. We don't bother making a
2547  // nice name for the argument.
2548  ParmVarDecl *Argument = ParmVarDecl::Create(Context, SetterMethod,
2549  Loc, Loc,
2550  property->getIdentifier(),
2551  paramTy,
2552  /*TInfo=*/nullptr,
2553  SC_None,
2554  nullptr);
2555  SetterMethod->setMethodParams(Context, Argument, None);
2556 
2557  AddPropertyAttrs(*this, SetterMethod, property);
2558 
2559  if (property->isDirectProperty())
2560  SetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2561 
2562  CD->addDecl(SetterMethod);
2563  if (const SectionAttr *SA = property->getAttr<SectionAttr>())
2564  SetterMethod->addAttr(SectionAttr::CreateImplicit(
2565  Context, SA->getName(), Loc, AttributeCommonInfo::AS_GNU,
2566  SectionAttr::GNU_section));
2567  // It's possible for the user to have set a very odd custom
2568  // setter selector that causes it to have a method family.
2569  if (getLangOpts().ObjCAutoRefCount)
2570  CheckARCMethodDecl(SetterMethod);
2571  } else
2572  // A user declared setter will be synthesize when @synthesize of
2573  // the property with the same name is seen in the @implementation
2574  SetterMethod->setPropertyAccessor(true);
2575 
2576  SetterMethod->createImplicitParams(Context,
2577  SetterMethod->getClassInterface());
2578  property->setSetterMethodDecl(SetterMethod);
2579  }
2580  // Add any synthesized methods to the global pool. This allows us to
2581  // handle the following, which is supported by GCC (and part of the design).
2582  //
2583  // @interface Foo
2584  // @property double bar;
2585  // @end
2586  //
2587  // void thisIsUnfortunate() {
2588  // id foo;
2589  // double bar = [foo bar];
2590  // }
2591  //
2592  if (!IsClassProperty) {
2593  if (GetterMethod)
2594  AddInstanceMethodToGlobalPool(GetterMethod);
2595  if (SetterMethod)
2596  AddInstanceMethodToGlobalPool(SetterMethod);
2597  } else {
2598  if (GetterMethod)
2599  AddFactoryMethodToGlobalPool(GetterMethod);
2600  if (SetterMethod)
2601  AddFactoryMethodToGlobalPool(SetterMethod);
2602  }
2603 
2604  ObjCInterfaceDecl *CurrentClass = dyn_cast<ObjCInterfaceDecl>(CD);
2605  if (!CurrentClass) {
2606  if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CD))
2607  CurrentClass = Cat->getClassInterface();
2608  else if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(CD))
2609  CurrentClass = Impl->getClassInterface();
2610  }
2611  if (GetterMethod)
2612  CheckObjCMethodOverrides(GetterMethod, CurrentClass, Sema::RTC_Unknown);
2613  if (SetterMethod)
2614  CheckObjCMethodOverrides(SetterMethod, CurrentClass, Sema::RTC_Unknown);
2615 }
2616 
2618  SourceLocation Loc,
2619  unsigned &Attributes,
2620  bool propertyInPrimaryClass) {
2621  // FIXME: Improve the reported location.
2622  if (!PDecl || PDecl->isInvalidDecl())
2623  return;
2624 
2625  if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2626  (Attributes & ObjCDeclSpec::DQ_PR_readwrite))
2627  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2628  << "readonly" << "readwrite";
2629 
2630  ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl);
2631  QualType PropertyTy = PropertyDecl->getType();
2632 
2633  // Check for copy or retain on non-object types.
2634  if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
2636  !PropertyTy->isObjCRetainableType() &&
2637  !PropertyDecl->hasAttr<ObjCNSObjectAttr>()) {
2638  Diag(Loc, diag::err_objc_property_requires_object)
2639  << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" :
2640  Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)");
2643  PropertyDecl->setInvalidDecl();
2644  }
2645 
2646  // Check for assign on object types.
2647  if ((Attributes & ObjCDeclSpec::DQ_PR_assign) &&
2648  !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) &&
2649  PropertyTy->isObjCRetainableType() &&
2650  !PropertyTy->isObjCARCImplicitlyUnretainedType()) {
2651  Diag(Loc, diag::warn_objc_property_assign_on_object);
2652  }
2653 
2654  // Check for more than one of { assign, copy, retain }.
2655  if (Attributes & ObjCDeclSpec::DQ_PR_assign) {
2656  if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
2657  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2658  << "assign" << "copy";
2659  Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
2660  }
2661  if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
2662  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2663  << "assign" << "retain";
2664  Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
2665  }
2666  if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
2667  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2668  << "assign" << "strong";
2669  Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
2670  }
2671  if (getLangOpts().ObjCAutoRefCount &&
2672  (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
2673  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2674  << "assign" << "weak";
2675  Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
2676  }
2677  if (PropertyDecl->hasAttr<IBOutletCollectionAttr>())
2678  Diag(Loc, diag::warn_iboutletcollection_property_assign);
2679  } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) {
2680  if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
2681  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2682  << "unsafe_unretained" << "copy";
2683  Attributes &= ~ObjCDeclSpec::DQ_PR_copy;
2684  }
2685  if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
2686  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2687  << "unsafe_unretained" << "retain";
2688  Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
2689  }
2690  if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
2691  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2692  << "unsafe_unretained" << "strong";
2693  Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
2694  }
2695  if (getLangOpts().ObjCAutoRefCount &&
2696  (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
2697  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2698  << "unsafe_unretained" << "weak";
2699  Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
2700  }
2701  } else if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
2702  if (Attributes & ObjCDeclSpec::DQ_PR_retain) {
2703  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2704  << "copy" << "retain";
2705  Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
2706  }
2707  if (Attributes & ObjCDeclSpec::DQ_PR_strong) {
2708  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2709  << "copy" << "strong";
2710  Attributes &= ~ObjCDeclSpec::DQ_PR_strong;
2711  }
2712  if (Attributes & ObjCDeclSpec::DQ_PR_weak) {
2713  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2714  << "copy" << "weak";
2715  Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
2716  }
2717  }
2718  else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) &&
2719  (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
2720  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2721  << "retain" << "weak";
2722  Attributes &= ~ObjCDeclSpec::DQ_PR_retain;
2723  }
2724  else if ((Attributes & ObjCDeclSpec::DQ_PR_strong) &&
2725  (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
2726  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2727  << "strong" << "weak";
2728  Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
2729  }
2730 
2731  if (Attributes & ObjCDeclSpec::DQ_PR_weak) {
2732  // 'weak' and 'nonnull' are mutually exclusive.
2733  if (auto nullability = PropertyTy->getNullability(Context)) {
2734  if (*nullability == NullabilityKind::NonNull)
2735  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2736  << "nonnull" << "weak";
2737  }
2738  }
2739 
2740  if ((Attributes & ObjCDeclSpec::DQ_PR_atomic) &&
2741  (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)) {
2742  Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2743  << "atomic" << "nonatomic";
2744  Attributes &= ~ObjCDeclSpec::DQ_PR_atomic;
2745  }
2746 
2747  // Warn if user supplied no assignment attribute, property is
2748  // readwrite, and this is an object type.
2749  if (!getOwnershipRule(Attributes) && PropertyTy->isObjCRetainableType()) {
2750  if (Attributes & ObjCDeclSpec::DQ_PR_readonly) {
2751  // do nothing
2752  } else if (getLangOpts().ObjCAutoRefCount) {
2753  // With arc, @property definitions should default to strong when
2754  // not specified.
2756  } else if (PropertyTy->isObjCObjectPointerType()) {
2757  bool isAnyClassTy =
2758  (PropertyTy->isObjCClassType() ||
2759  PropertyTy->isObjCQualifiedClassType());
2760  // In non-gc, non-arc mode, 'Class' is treated as a 'void *' no need to
2761  // issue any warning.
2762  if (isAnyClassTy && getLangOpts().getGC() == LangOptions::NonGC)
2763  ;
2764  else if (propertyInPrimaryClass) {
2765  // Don't issue warning on property with no life time in class
2766  // extension as it is inherited from property in primary class.
2767  // Skip this warning in gc-only mode.
2768  if (getLangOpts().getGC() != LangOptions::GCOnly)
2769  Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
2770 
2771  // If non-gc code warn that this is likely inappropriate.
2772  if (getLangOpts().getGC() == LangOptions::NonGC)
2773  Diag(Loc, diag::warn_objc_property_default_assign_on_object);
2774  }
2775  }
2776 
2777  // FIXME: Implement warning dependent on NSCopying being
2778  // implemented. See also:
2779  // <rdar://5168496&4855821&5607453&5096644&4947311&5698469&4947014&5168496>
2780  // (please trim this list while you are at it).
2781  }
2782 
2783  if (!(Attributes & ObjCDeclSpec::DQ_PR_copy)
2784  &&!(Attributes & ObjCDeclSpec::DQ_PR_readonly)
2785  && getLangOpts().getGC() == LangOptions::GCOnly
2786  && PropertyTy->isBlockPointerType())
2787  Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
2788  else if ((Attributes & ObjCDeclSpec::DQ_PR_retain) &&
2789  !(Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2790  !(Attributes & ObjCDeclSpec::DQ_PR_strong) &&
2791  PropertyTy->isBlockPointerType())
2792  Diag(Loc, diag::warn_objc_property_retain_of_block);
2793 
2794  if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2795  (Attributes & ObjCDeclSpec::DQ_PR_setter))
2796  Diag(Loc, diag::warn_objc_readonly_property_has_setter);
2797 }
A call to an overloaded operator written using operator syntax.
Definition: ExprCXX.h:78
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
ObjCPropertyQueryKind getQueryKind() const
Definition: DeclObjC.h:895
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
bool isClassMethod() const
Definition: DeclObjC.h:431
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Represents a function declaration or definition.
Definition: Decl.h:1783
void setGetterMethodDecl(ObjCMethodDecl *MD)
Definition: DeclObjC.h:2869
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
Definition: Lexer.h:76
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
protocol_range protocols() const
Definition: DeclObjC.h:1380
Smart pointer class that efficiently represents Objective-C method names.
A (possibly-)qualified type.
Definition: Type.h:654
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2339
all_protocol_range all_referenced_protocols() const
Definition: DeclObjC.h:1438
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1155
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns &#39;true&#39; if &#39;IV&#39; is an ivar synthesized for &#39;Meth...
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC)
isObjCPointerConversion - Determines whether this is an Objective-C pointer conversion.
void setAttrs(const AttrVec &Attrs)
Definition: DeclBase.h:486
bool isArithmeticType() const
Definition: Type.cpp:2036
Decl * ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
Defines the SourceManager interface.
void ActOnDocumentableDecl(Decl *D)
Should be called on all declarations that might have attached documentation comments.
Definition: SemaDecl.cpp:13055
void setObjCLifetime(ObjCLifetime type)
Definition: Type.h:336
static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, ObjCInterfaceDecl::PropertyMap &PropMap)
CollectSuperClassPropertyImplementations - This routine collects list of properties to be implemented...
bool isRecordType() const
Definition: Type.h:6594
llvm::SmallVector< ObjCPropertyDecl *, 8 > PropertyDeclOrder
Definition: DeclObjC.h:1121
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:1958
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition: Sema.h:1411
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
void DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD)
void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, unsigned &Attributes, bool propertyInPrimaryClass)
Ensure attributes are consistent with type.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:421
Captures information about "declaration specifiers" specific to Objective-C.
Definition: DeclSpec.h:814
StringRef P
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 isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ImplementationControl impControl=None, bool HasRelatedResultType=false)
Definition: DeclObjC.cpp:808
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:6452
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:2244
void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
Definition: Sema.h:4025
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const
Return the name of the macro defined before Loc that has spelling Tokens.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition: Sema.cpp:49
void setPropertyImplementation(PropertyControl pc)
Definition: DeclObjC.h:943
A container of type source information.
Definition: Type.h:6227
void ProcessPropertyDecl(ObjCPropertyDecl *property)
Process the specified property declaration and create decls for the setters and getters as needed...
void setPropertyAccessor(bool isAccessor)
Definition: DeclObjC.h:437
SourceLocation getEndLoc() const
Get the end source location.
Definition: TypeLoc.cpp:228
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID)
createImplicitParams - Used to lazily create the self and cmd implict parameters. ...
Definition: DeclObjC.cpp:1134
static bool areIncompatiblePropertyAttributes(unsigned Attr1, unsigned Attr2, unsigned Kinds)
Decl * ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, SourceLocation PropertyLoc, bool ImplKind, IdentifierInfo *PropertyId, IdentifierInfo *PropertyIvar, SourceLocation PropertyIvarLoc, ObjCPropertyQueryKind QueryKind)
ActOnPropertyImplDecl - This routine performs semantic checks and builds the AST node for a property ...
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
RAII object to handle the state changes required to synthesize a function body.
Definition: Sema.h:840
bool allowsDirectDispatch() const
Does this runtime supports direct dispatch.
Definition: ObjCRuntime.h:450
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:7002
static unsigned getOwnershipRule(unsigned attr)
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:138
ObjCPropertyDecl * HandlePropertyInClassExtension(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, unsigned &Attributes, const unsigned AttributesAsWritten, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind)
Called by ActOnProperty to handle @property declarations in class extensions.
bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, bool lookupCategory, bool RHSIsQualifiedID=false)
ClassImplementsProtocol - Checks that &#39;lProto&#39; protocol has been implemented in IDecl class...
Definition: DeclObjC.cpp:1728
bool isInvalidDecl() const
Definition: DeclBase.h:553
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type, bool NRVO)
Create the initialization entity for the result of a function.
static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, ObjCPropertyQueryKind queryKind)
Lookup a property by name in the specified DeclContext.
Definition: DeclObjC.cpp:176
void setSelfDecl(ImplicitParamDecl *SD)
Definition: DeclObjC.h:416
protocol_range protocols() const
Definition: DeclObjC.h:2143
Represents a parameter to a function.
Definition: Decl.h:1595
Defines the clang::Expr interface and subclasses for C++ expressions.
Parse and apply any fixits to the source.
The collection of all-type qualifiers we support.
Definition: Type.h:143
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:244
static void CollectImmediateProperties(ObjCContainerDecl *CDecl, ObjCContainerDecl::PropertyMap &PropMap, ObjCContainerDecl::PropertyMap &SuperPropMap, bool CollectClassPropsOnly=false, bool IncludeProtocols=true)
CollectImmediateProperties - This routine collects all properties in the class and its conforming pro...
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:272
instprop_range instance_properties() const
Definition: DeclObjC.h:1017
One of these records is kept for each identifier that is lexed.
SourceLocation getSetterNameLoc() const
Definition: DeclSpec.h:909
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:168
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1195
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
Definition: DeclObjC.h:1106
ObjCMethodFamily
A family of Objective-C methods.
instmeth_range instance_methods() const
Definition: DeclObjC.h:1068
bool isDefined() const
Definition: DeclObjC.h:449
method_range methods() const
Definition: DeclObjC.h:1051
Token - This structure provides full information about a lexed token.
Definition: Token.h:34
prop_range properties() const
Definition: DeclObjC.h:1002
int Category
Definition: Format.cpp:1828
IdentifierTable & Idents
Definition: ASTContext.h:580
This little struct is used to capture information about structure field declarators, which is basically just a bitfield size.
Definition: DeclSpec.h:2577
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:125
bool isClassProperty() const
Definition: DeclObjC.h:892
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
Definition: DeclObjC.cpp:997
void collectPropertiesToImplement(PropertyMap &PM, PropertyDeclOrder &PO) const override
This routine collects list of properties to be implemented in the class.
Definition: DeclObjC.cpp:392
void setObjCWeakProperty(bool Val=true)
Definition: DeclSpec.h:2526
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
Definition: ObjCRuntime.h:81
bool isDirectProperty() const
Definition: DeclObjC.h:893
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:983
const FormatToken & Tok
static ObjCPropertyImplDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc)
Definition: DeclObjC.cpp:2272
AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, QualType LHSType, QualType RHSType)
CheckAssignmentConstraints - Perform type checking for assignment, argument passing, variable initialization, and function return values.
Definition: SemaExpr.cpp:8244
Whether values of this type can be null is (explicitly) unspecified.
PropertyAttributeKind getPropertyAttributes() const
Definition: DeclObjC.h:853
const ObjCInterfaceDecl * isObjCRequiresPropertyDefs() const
isObjCRequiresPropertyDefs - Checks that a class or one of its super classes must not be auto-synthes...
Definition: DeclObjC.cpp:422
void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base=nullptr)
Perform reference-marking and odr-use handling for a DeclRefExpr.
Definition: SemaExpr.cpp:17029
static void DiagnoseUnimplementedAccessor(Sema &S, ObjCInterfaceDecl *PrimaryClass, Selector Method, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, ObjCCategoryDecl *C, ObjCPropertyDecl *Prop, llvm::SmallPtrSet< const ObjCMethodDecl *, 8 > &SMap)
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
Definition: DeclObjC.h:876
Values of this type can never be null.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
Definition: DeclObjC.h:2224
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1166
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2078
Preprocessor & PP
Definition: Sema.h:384
const LangOptions & getLangOpts() const
Definition: Sema.h:1324
PropertyControl getPropertyImplementation() const
Definition: DeclObjC.h:947
Represents an ObjC class declaration.
Definition: DeclObjC.h:1186
ObjCPropertyDecl * CreatePropertyDecl(Scope *S, ObjCContainerDecl *CDecl, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, const unsigned Attributes, const unsigned AttributesAsWritten, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
Called by ActOnProperty and HandlePropertyInClassExtension to handle creating the ObjcPropertyDecl fo...
QualType getReturnType() const
Definition: DeclObjC.h:324
IdentifierInfo * getIdentifier() const
Definition: DeclSpec.h:2172
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl *> Params, ArrayRef< SourceLocation > SelLocs=llvm::None)
Sets the method&#39;s parameters and selector source locations.
Definition: DeclObjC.cpp:890
const LangOptions & LangOpts
Definition: Sema.h:383
This object can be modified without requiring retains or releases.
Definition: Type.h:164
void AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl)
AtomicPropertySetterGetterRules - This routine enforces the rule (via warning) when atomic property h...
void setGetterCXXConstructor(Expr *getterCXXConstructor)
Definition: DeclObjC.h:2878
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddInstanceMethodToGlobalPool - All instance methods in a translation unit are added to a global pool...
Definition: Sema.h:4020
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1612
void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ObjCInterfaceDecl *CurrentClass, ResultTypeCompatibilityKind RTC)
void getSelectorLocs(SmallVectorImpl< SourceLocation > &SelLocs) const
Definition: DeclObjC.cpp:884
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2773
bool hasAttr() const
Definition: DeclBase.h:542
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:336
static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, ObjCPropertyDecl *Property)
AddPropertyAttrs - Propagates attributes from a property to the implicitly-declared getter or setter ...
bool isFragile() const
The inverse of isNonFragile(): does this runtime follow the set of implied behaviors for a "fragile" ...
Definition: ObjCRuntime.h:96
visible_extensions_range visible_extensions() const
Definition: DeclObjC.h:1737
AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple(), StringRef *RealizedPlatform=nullptr) const
Determine the availability of the given declaration.
Definition: DeclBase.cpp:574
llvm::SmallPtrSet< Selector, 8 > SelectorSet
Definition: Sema.h:3835
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
Definition: Expr.cpp:1998
void addObjCLifetime(ObjCLifetime type)
Definition: Type.h:340
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclObjC.cpp:991
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type...
Definition: DeclObjC.cpp:1839
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.
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:191
bool isObjCGCStrong() const
true when Type is objc&#39;s strong.
Definition: Type.h:1075
This represents one expression.
Definition: Expr.h:108
known_extensions_range known_extensions() const
Definition: DeclObjC.h:1775
Selector getSetterName() const
Definition: DeclObjC.h:928
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const
This routine returns &#39;true&#39; if a user declared setter method was found in the class, its protocols, its super classes or categories.
Definition: DeclObjC.cpp:123
IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const
Get the default name of the synthesized ivar.
Definition: DeclObjC.cpp:224
bool isObjCARCImplicitlyUnretainedType() const
Determines if this type, which must satisfy isObjCLifetimeType(), is implicitly __unsafe_unretained r...
Definition: Type.cpp:4022
TypeSourceInfo * getTypeSourceInfo() const
Definition: DeclObjC.h:840
bool isObjCRetainableType() const
Definition: Type.cpp:4060
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver&#39;s type...
Definition: DeclObjC.h:258
static ObjCPropertyDecl::PropertyAttributeKind makePropertyAttributesAsWritten(unsigned Attributes)
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:132
static bool hasWrittenStorageAttribute(ObjCPropertyDecl *Prop, ObjCPropertyQueryKind QueryKind)
Determine whether any storage attributes were written on the property.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:558
Defines the clang::Preprocessor interface.
#define bool
Definition: stdbool.h:15
DeclContext * getDeclContext()
Definition: DeclBase.h:438
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:337
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD)
Stores token information for comparing actual tokens with predefined values.
Definition: Preprocessor.h:89
ObjCPropertyDecl * FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyVisibleInPrimaryClass - Finds declaration of the property with name &#39;PropertyId&#39; in the p...
Definition: DeclObjC.cpp:368
void setDefined(bool isDefined)
Definition: DeclObjC.h:450
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:7919
ParmVarDecl *const * param_iterator
Definition: DeclObjC.h:345
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Definition: Type.h:593
static Optional< NullabilityKind > stripOuterNullability(QualType &T)
Strip off the top-level nullability annotation on the given type, if it&#39;s there.
Definition: Type.cpp:3968
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Definition: DeclObjC.cpp:620
clang::ObjCRuntime ObjCRuntime
Definition: LangOptions.h:257
propimpl_range property_impls() const
Definition: DeclObjC.h:2481
Qualifiers Quals
The local qualifiers.
Definition: Type.h:598
llvm::SmallDenseSet< const ObjCProtocolDecl *, 8 > ProtocolPropertySet
Definition: DeclObjC.h:1120
bool isInvalid() const
Definition: Ownership.h:166
bool isInstanceMethod() const
Definition: DeclObjC.h:423
Preprocessor & getPreprocessor() const
Definition: Sema.h:1330
Selector getSelector() const
Definition: DeclObjC.h:322
ImplicitParamDecl * getSelfDecl() const
Definition: DeclObjC.h:415
QualType getType() const
Definition: DeclObjC.h:842
const SourceManager & SM
Definition: Format.cpp:1685
static StringRef getIdentifier(const Token &Tok)
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an &#39;@&#39;.
Definition: TokenKinds.h:40
AttrVec & getAttrs()
Definition: DeclBase.h:490
QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const
Return the uniqued reference to the type for an Objective-C gc-qualified type.
bool hasAttrs() const
Definition: DeclBase.h:484
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType)
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
Definition: Type.h:6264
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition: DeclObjC.h:338
RecordDecl * getDecl() const
Definition: Type.h:4505
bool isSynthesizedAccessorStub() const
Definition: DeclObjC.h:441
There is no lifetime qualification on this type.
Definition: Type.h:160
void makeDeclVisibleInContext(NamedDecl *D)
Makes a declaration visible within this context.
Definition: DeclBase.cpp:1802
Assigning into this object requires the old value to be released and the new value to be retained...
Definition: Type.h:171
Kind
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Definition: Ownership.h:153
Encodes a location in the source.
bool getSynthesize() const
Definition: DeclObjC.h:2005
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ObjCPropertyQueryKind
Definition: DeclObjC.h:729
void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal)
Definition: DeclObjC.h:869
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition: DeclObjC.cpp:855
void setSetterMethodDecl(ObjCMethodDecl *MD)
Definition: DeclObjC.h:2872
static Qualifiers::ObjCLifetime getImpliedARCOwnership(ObjCPropertyDecl::PropertyAttributeKind attrs, QualType type)
getImpliedARCOwnership - Given a set of property attributes and a type, infer an expected lifetime...
ObjCPropertyAttributeKind getPropertyAttributes() const
Definition: DeclSpec.h:869
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2294
CanQualType VoidTy
Definition: ASTContext.h:1016
void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, bool SynthesizeProperties)
DiagnoseUnimplementedProperties - This routine warns on those properties which must be implemented by...
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:741
ObjCMethodDecl * lookupPropertyAccessor(const Selector Sel, const ObjCCategoryDecl *Cat, bool IsClassProperty) const
Lookup a setter or getter in the class hierarchy, including in all categories except for category pas...
Definition: DeclObjC.h:1883
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=NotForRedeclaration)
Find the protocol with the given name, if any.
ObjCPropertyImplDecl * FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const
FindPropertyImplIvarDecl - This method lookup the ivar in the list of properties implemented in this ...
Definition: DeclObjC.cpp:2123
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
Definition: DeclObjC.h:761
Assigning into this object requires a lifetime extension.
Definition: Type.h:177
bool hasFlexibleArrayMember() const
Definition: Decl.h:3802
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2345
void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D)
void setSetterCXXAssignment(Expr *setterCXXAssignment)
Definition: DeclObjC.h:2886
static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc, ObjCPropertyDecl *property, ObjCIvarDecl *ivar)
bool isObjCGCWeak() const
true when Type is objc&#39;s weak.
Definition: Type.h:1070
bool propertyTypesAreCompatible(QualType, QualType)
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
Definition: SemaInit.cpp:9608
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2454
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: DeclBase.h:948
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition: Decl.cpp:2672
static void setImpliedPropertyAttributeForReadOnlyProperty(ObjCPropertyDecl *property, ObjCIvarDecl *ivar)
setImpliedPropertyAttributeForReadOnlyProperty - This routine evaludates life-time attributes for a &#39;...
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in &#39;PropertyId&#39; and return...
Definition: DeclObjC.cpp:235
void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)
Diagnose any null-resettable synthesized setters.
void setGetterName(Selector Sel, SourceLocation Loc=SourceLocation())
Definition: DeclObjC.h:923
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1271
static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl, ObjCPropertyDecl *Prop)
PropertyAttributeKind getPropertyAttributesAsWritten() const
Definition: DeclObjC.h:865
The basic abstraction for the target Objective-C runtime.
Definition: ObjCRuntime.h:27
attr_range attrs() const
Definition: DeclBase.h:501
bool CheckARCMethodDecl(ObjCMethodDecl *method)
Check a method declaration for compatibility with the Objective-C ARC conventions.
llvm::DenseMap< std::pair< IdentifierInfo *, unsigned >, ObjCPropertyDecl * > PropertyMap
Definition: DeclObjC.h:1119
bool hasObjCLifetime() const
Definition: Type.h:332
bool hasDesignatedInitializers() const
Returns true if this interface decl contains at least one initializer marked with the &#39;objc_designate...
Definition: DeclObjC.cpp:1547
bool isMacroID() const
Represents a pointer to an Objective C object.
Definition: Type.h:5951
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:1773
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2566
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4495
void overwritePropertyAttributes(unsigned PRVal)
Definition: DeclObjC.h:861
T * getAttr() const
Definition: DeclBase.h:538
SourceLocation getGetterNameLoc() const
Definition: DeclSpec.h:901
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2321
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:92
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1524
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const
lookupMethod - This method returns an instance/class method by looking in the class, its categories, and its super classes (using a linear search).
Definition: DeclObjC.cpp:682
void setSetterName(Selector Sel, SourceLocation Loc=SourceLocation())
Definition: DeclObjC.h:931
static void checkAtomicPropertyMismatch(Sema &S, ObjCPropertyDecl *OldProperty, ObjCPropertyDecl *NewProperty, bool PropagateAtomicity)
Check for a mismatch in the atomicity of the given properties.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:546
SourceManager & getSourceManager()
Definition: ASTContext.h:679
bool isObjCObjectType() const
Definition: Type.h:6622
bool IsClassExtension() const
Definition: DeclObjC.h:2404
ImplementationControl getImplementationControl() const
Definition: DeclObjC.h:494
SourceLocation getIdentifierLoc() const
Definition: DeclSpec.h:2178
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2305
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:244
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:174
static ObjCMethodDecl * RedeclarePropertyAccessor(ASTContext &Context, ObjCImplementationDecl *Impl, ObjCMethodDecl *AccessorDecl, SourceLocation AtLoc, SourceLocation PropertyLoc)
Create a synthesized property accessor stub inside the @implementation.
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups, surround it with a ExprWithCleanups node.
Compatible - the types are compatible according to the standard.
Definition: Sema.h:10603
ObjCPropertyImplDecl * FindPropertyImplDecl(IdentifierInfo *propertyId, ObjCPropertyQueryKind queryKind) const
FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl added to the list of thos...
Definition: DeclObjC.cpp:2135
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1959
static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:397
ImplicitParamDecl * getCmdDecl() const
Definition: DeclObjC.h:417
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:60
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:129
bool isVariadic() const
Definition: DeclObjC.h:428
void addAttr(Attr *A)
Definition: DeclBase.cpp:832
void setPropertyAttributes(PropertyAttributeKind PRVal)
Definition: DeclObjC.h:857
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, const IdentifierInfo *Name, bool OverridingProtocolProperty)
DiagnosePropertyMismatch - Compares two properties for their attributes and types and warns on a vari...
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclObjC.h:284
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:250
bool isArcWeakrefUnavailable() const
isArcWeakrefUnavailable - Checks for a class or one of its super classes to be incompatible with __we...
Definition: DeclObjC.cpp:412
static ObjCPropertyDecl * SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc, ObjCInterfaceDecl *ClassDecl, ObjCPropertyDecl *Property)
SelectPropertyForSynthesisFromProtocols - Finds the most appropriate property declaration that should...
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl, SourceLocation AtEnd)
DefaultSynthesizeProperties - This routine default synthesizes all properties which must be synthesiz...
static const unsigned OwnershipMask
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1171
void addPropertyImplementation(ObjCPropertyImplDecl *property)
Definition: DeclObjC.cpp:2098
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.
QualType getType() const
Definition: Decl.h:630
#define true
Definition: stdbool.h:16
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:129
A trivial tuple used to represent a source range.
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition: DeclObjC.cpp:91
ASTContext & Context
Definition: Sema.h:385
void setLexicalDeclContext(DeclContext *DC)
Definition: DeclBase.cpp:299
ObjCMethodDecl * getGetterMethodDecl() const
Definition: DeclObjC.h:936
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Definition: DeclObjC.h:1101
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:13460
llvm::DenseMap< const Stmt *, CFGBlock * > SMap
Definition: CFGStmtMap.cpp:21
AccessControl getAccessControl() const
Definition: DeclObjC.h:1998
bool isPropertyAccessor() const
Definition: DeclObjC.h:433
Selector getGetterName() const
Definition: DeclObjC.h:920
SourceLocation getLParenLoc() const
Definition: DeclObjC.h:837
void setType(QualType newType)
Definition: Decl.h:631
const LangOptions & getLangOpts() const
Definition: ASTContext.h:724
void setCmdDecl(ImplicitParamDecl *CD)
Definition: DeclObjC.h:418
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Definition: DeclObjC.h:2513
This class handles loading and caching of source files into memory.
static void checkPropertyDeclWithOwnership(Sema &S, ObjCPropertyDecl *property)
Check the internal consistency of a property declaration with an explicit ownership qualifier...
Attr - This represents one attribute.
Definition: Attr.h:45
SourceLocation getLocation() const
Definition: DeclBase.h:429
TypeSourceInfo * GetTypeForDeclarator(Declarator &D, Scope *S)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
Definition: SemaType.cpp:5432
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6238
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:368
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:128
bool isUnavailable(std::string *Message=nullptr) const
Determine whether this declaration is marked &#39;unavailable&#39;.
Definition: DeclBase.h:680
static bool isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2, ObjCPropertyDecl::PropertyAttributeKind Kind)
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition: Type.h:1080
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
Definition: DeclObjC.cpp:1689