23#include "llvm/ADT/DenseSet.h"
54 type->isObjCRetainableType()) {
69 =
property->getType().getObjCLifetime();
75 if (!expectedLifetime) {
89 property->setPropertyAttributes(
attr);
93 if (propertyLifetime == expectedLifetime)
return;
95 property->setInvalidDecl();
97 diag::err_arc_inconsistent_property_ownership)
98 <<
property->getDeclName()
108 llvm::SmallPtrSetImpl<ObjCProtocolDecl *> &Known) {
110 if (!Known.insert(Proto).second)
129 if (
T.isObjCGCWeak())
134 }
else if (
auto ownership =
T.getObjCLifetime()) {
146 llvm_unreachable(
"bad qualifier");
183 if (
T.getPointerAuth().isPresent()) {
184 Diag(AtLoc, diag::err_ptrauth_qualifier_invalid) <<
T << 2;
197 if (CDecl->IsClassExtension()) {
202 isReadWrite, Attributes,
204 T, TSI, MethodImplKind);
232 bool FoundInSuper =
false;
241 CurrentInterfaceDecl = Super;
246 for (
auto *P : CurrentInterfaceDecl->
protocols()) {
251 for (
auto *P : IFace->all_referenced_protocols()) {
259 if (!Cat->IsClassExtension())
260 for (
auto *P : Cat->protocols())
268 SemaRef.ActOnDocumentableDecl(Res);
274 unsigned attributesAsWritten = 0;
315 bool invalidTemp =
false;
316 StringRef file =
SM.getBufferData(locInfo.first, &invalidTemp);
319 const char *tokenBegin = file.data() + locInfo.second;
322 Lexer lexer(
SM.getLocForStartOfFile(locInfo.first),
323 Context.getLangOpts(),
324 file.begin(), tokenBegin, file.end());
328 if (
Tok.is(tok::raw_identifier) &&
Tok.getRawIdentifier() == attrName) {
329 Loc =
Tok.getLocation();
332 }
while (
Tok.isNot(tok::r_paren));
340 bool PropagateAtomicity) {
346 if (OldIsAtomic == NewIsAtomic)
return;
352 auto Attrs = Property->getPropertyAttributes();
361 if (Property->getPropertyAttributesAsWritten() &
372 if (PropagateAtomicity &&
375 Attrs = Attrs & ~AtomicityMask;
387 if ((OldIsAtomic && isImplicitlyReadonlyAtomic(OldProperty)) ||
388 (NewIsAtomic && isImplicitlyReadonlyAtomic(NewProperty)))
394 if (
auto Category = dyn_cast<ObjCCategoryDecl>(OldDC))
395 OldContextName = Category->getClassInterface()->getIdentifier();
409 unsigned &Attributes,
const unsigned AttributesAsWritten,
QualType T,
424 bool isClassProperty =
435 Diag(AtLoc, diag::err_duplicate_property);
454 ? diag::err_use_continuation_class_redeclaration_readwrite
455 : diag::err_use_continuation_class;
466 Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)
477 unsigned ExistingOwnership
480 if (ExistingOwnership && NewOwnership != ExistingOwnership) {
483 Diag(AtLoc, diag::warn_property_attr_mismatch);
497 Diag(AtLoc, diag::warn_property_implicitly_mismatched);
505 FD, GetterSel, GetterNameLoc,
506 SetterSel, SetterNameLoc,
508 Attributes, AttributesAsWritten,
509 T, TSI, MethodImplKind, DC);
519 bool IncompatibleObjC =
false;
531 (!
SemaRef.isObjCPointerConversion(ClassExtPropertyT,
532 PrimaryClassPropertyT, ConvertedType,
533 IncompatibleObjC)) ||
536 diag::err_type_mismatch_continuation_class) << PDecl->
getType();
556 const unsigned Attributes,
const unsigned AttributesAsWritten,
QualType T,
572 !
T->isObjCRetainableType());
586 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
590 if (
T->isObjCObjectType()) {
592 StarLoc =
SemaRef.getLocForEndOfToken(StarLoc);
595 T = Context.getObjCObjectPointerType(
T);
597 TInfo = Context.getTrivialTypeSourceInfo(
T, TLoc);
604 LParenLoc,
T, TInfo);
606 bool isClassProperty =
613 Diag(prevDecl->getLocation(), diag::note_property_declare);
622 if (
T->isArrayType() ||
T->isFunctionType()) {
623 Diag(AtLoc, diag::err_property_type) <<
T;
634 SemaRef.ProcessDeclAttributes(S, PDecl, FD.
D);
678 if (MethodImplKind == tok::objc_required)
680 else if (MethodImplKind == tok::objc_optional)
693 CDecl->
hasAttr<ObjCDirectMembersAttr>()) {
721 if (propertyLifetime == ivarLifetime)
return;
747 switch (propertyLifetime) {
750 <<
property->getDeclName()
757 <<
property->getDeclName()
764 << ((
property->getPropertyAttributesAsWritten() &
769 llvm_unreachable(
"properties cannot be autoreleasing");
778 S.
Diag(propertyImplLoc, diag::note_property_synthesize);
810 return (Attr1 & Kind) != (Attr2 & Kind);
815 return ((Attr1 & Kinds) != 0) != ((Attr2 & Kinds) != 0);
828 "Expected a property from a protocol");
833 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
838 for (
const auto *PI : SDecl->all_referenced_protocols()) {
840 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
843 SDecl = SDecl->getSuperClass();
847 if (Properties.empty())
851 size_t SelectedIndex = 0;
852 for (
const auto &Prop : llvm::enumerate(Properties)) {
854 if (Property->isReadOnly() && !Prop.value()->isReadOnly()) {
855 Property = Prop.value();
856 SelectedIndex = Prop.index();
859 if (Property != OriginalProperty) {
861 Properties[SelectedIndex] = OriginalProperty;
865 unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
867 IncompatibleType = 0,
868 HasNoExpectedAttribute,
869 HasUnexpectedAttribute,
875 struct MismatchingProperty {
878 StringRef AttributeName;
883 unsigned Attr = Prop->getPropertyAttributesAsWritten();
884 if (
Attr != OriginalAttributes) {
885 auto Diag = [&](
bool OriginalHasAttribute, StringRef AttributeName) {
886 MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
887 : HasUnexpectedAttribute;
888 Mismatches.push_back({Prop, Kind, AttributeName});
906 OriginalAttributes,
Attr,
911 "retain (or strong)");
920 if (Property->getGetterName() != Prop->getGetterName()) {
921 Mismatches.push_back({Prop, DifferentGetter,
""});
924 if (!Property->isReadOnly() && !Prop->isReadOnly() &&
925 Property->getSetterName() != Prop->getSetterName()) {
926 Mismatches.push_back({Prop, DifferentSetter,
""});
931 bool IncompatibleObjC =
false;
934 || IncompatibleObjC) {
935 Mismatches.push_back({Prop, IncompatibleType,
""});
941 if (Mismatches.empty())
946 bool HasIncompatibleAttributes =
false;
947 for (
const auto &
Note : Mismatches)
948 HasIncompatibleAttributes =
949 Note.Kind != IncompatibleType ?
true : HasIncompatibleAttributes;
952 auto Diag = S.
Diag(Property->getLocation(),
953 Property != OriginalProperty || HasIncompatibleAttributes
954 ? diag::err_protocol_property_mismatch
955 : diag::warn_protocol_property_mismatch);
956 Diag << Mismatches[0].Kind;
957 switch (Mismatches[0].Kind) {
958 case IncompatibleType:
959 Diag << Property->getType();
961 case HasNoExpectedAttribute:
962 case HasUnexpectedAttribute:
963 Diag << Mismatches[0].AttributeName;
965 case DifferentGetter:
966 Diag << Property->getGetterName();
968 case DifferentSetter:
969 Diag << Property->getSetterName();
973 for (
const auto &
Note : Mismatches) {
975 S.
Diag(
Note.Prop->getLocation(), diag::note_protocol_property_declare)
978 case IncompatibleType:
981 case HasNoExpectedAttribute:
982 case HasUnexpectedAttribute:
985 case DifferentGetter:
988 case DifferentSetter:
994 S.
Diag(AtLoc, diag::note_property_synthesize);
1012 auto Category = dyn_cast<ObjCCategoryDecl>(Prop->
getDeclContext());
1013 if (!Category || !Category->IsClassExtension())
return false;
1016 auto OrigClass = Category->getClassInterface();
1019 return OrigProp->getPropertyAttributesAsWritten() &
OwnershipMask;
1023 for (
const auto *Proto : OrigClass->all_referenced_protocols()) {
1026 return OrigProp->getPropertyAttributesAsWritten() &
OwnershipMask;
1041 Decl->getSelector(),
Decl->getReturnType(),
1042 Decl->getReturnTypeSourceInfo(), Impl,
Decl->isInstanceMethod(),
1043 Decl->isVariadic(),
Decl->isPropertyAccessor(),
1045 Decl->getImplementationControl(),
Decl->hasRelatedResultType());
1052 Decl->getSelectorLocs(SelLocs);
1069 dyn_cast<ObjCContainerDecl>(
SemaRef.CurContext);
1071 if (!ClassImpDecl) {
1072 Diag(AtLoc, diag::err_missing_property_context);
1076 PropertyIvarLoc = PropertyLoc;
1086 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
1091 "ActOnPropertyImplDecl - @implementation without @interface");
1096 Diag(PropertyLoc, diag::err_bad_property_decl) << IDecl->
getDeclName();
1099 if (property->isClassProperty() && Synthesize) {
1100 Diag(PropertyLoc, diag::err_synthesize_on_class_property) << PropertyId;
1107 Diag(AtLoc, diag::warn_implicit_atomic_property);
1110 Diag(property->getLocation(), diag::note_property_declare);
1114 dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
1115 if (!CD->IsClassExtension()) {
1116 Diag(PropertyLoc, diag::err_category_property) << CD->getDeclName();
1117 Diag(property->getLocation(), diag::note_property_declare);
1122 property->hasAttr<IBOutletAttr>() && !AtLoc.
isValid()) {
1123 bool ReadWriteProperty =
false;
1129 PIkind = ExtProp->getPropertyAttributesAsWritten();
1131 ReadWriteProperty =
true;
1137 if (!ReadWriteProperty) {
1138 Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property)
1142 property->getLParenLoc(), readonlyLoc)) {
1145 SourceRange ReadonlySourceRange(readonlyLoc, endLoc);
1146 Diag(property->getLocation(),
1147 diag::note_auto_readonly_iboutlet_fixup_suggest) <<
1156 }
else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
1158 Diag(AtLoc, diag::err_synthesize_category_decl);
1163 Diag(AtLoc, diag::err_missing_property_interface);
1176 Diag(PropertyLoc, diag::err_bad_category_property_decl)
1177 << Category->getDeclName();
1181 Diag(AtLoc, diag::err_bad_property_context);
1185 bool CompleteTypeErr =
false;
1191 PropertyIvar = PropertyId;
1195 QualType PropType =
property->getType();
1198 if (
SemaRef.RequireCompleteType(PropertyDiagLoc, PropertyIvarType,
1199 diag::err_incomplete_synthesized_property,
1200 property->getDeclName())) {
1201 Diag(property->getLocation(), diag::note_property_declare);
1202 CompleteTypeErr =
true;
1206 (property->getPropertyAttributesAsWritten() &
1214 bool isARCWeak =
false;
1220 Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);
1221 Diag(property->getLocation(), diag::note_property_declare);
1233 Diag(PropertyDiagLoc,
1235 ? diag::err_synthesizing_arc_weak_property_disabled
1236 : diag::err_synthesizing_arc_weak_property_no_runtime);
1237 Diag(property->getLocation(), diag::note_property_declare);
1239 CompleteTypeErr =
true;
1246 Diag(property->getLocation(),
1247 diag::err_arc_weak_unavailable_property)
1248 << PropertyIvarType;
1267 Diag(PropertyDiagLoc,
1268 diag::warn_autosynthesis_property_ivar_match)
1269 << PropertyId << (Ivar ==
nullptr) << PropertyIvar
1271 Diag(property->getLocation(), diag::note_property_declare);
1279 if ((
getLangOpts().ObjCAutoRefCount || isARCWeak) &&
1287 Diag(PropertyDiagLoc,
1288 diag::err_arc_objc_property_default_assign_on_object);
1289 Diag(property->getLocation(), diag::note_property_declare);
1293 assert(lifetime &&
"no lifetime for property?");
1297 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);
1301 if (Context.getLangOpts().PointerAuthObjcInterfaceSel &&
1304 if (
auto PAQ = Context.getObjCMemberSelTypePtrAuth())
1306 Context.getPointerAuthType(PropertyIvarType, PAQ);
1311 PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,
1312 PropertyIvarType,
nullptr,
1314 (
Expr *)
nullptr,
true);
1315 if (
SemaRef.RequireNonAbstractType(PropertyIvarLoc, PropertyIvarType,
1316 diag::err_abstract_type_in_decl,
1318 Diag(property->getLocation(), diag::note_property_declare);
1320 CompleteTypeErr =
true;
1322 if (!CompleteTypeErr) {
1325 Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)
1326 << PropertyIvarType;
1327 CompleteTypeErr =
true;
1330 if (CompleteTypeErr)
1336 Diag(PropertyDiagLoc, diag::err_missing_property_ivar_decl)
1342 Diag(PropertyDiagLoc, diag::err_ivar_in_superclass_use)
1349 property->setPropertyIvarDecl(Ivar);
1354 if (!Context.hasSameType(PropertyIvarType, IvarType)) {
1357 compat = Context.canAssignObjCInterfaces(
1361 compat =
SemaRef.IsAssignConvertCompatible(
1362 SemaRef.CheckAssignmentConstraints(PropertyIvarLoc,
1363 PropertyIvarType, IvarType));
1366 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1367 <<
property->getDeclName() << PropType
1379 if (lhsType != rhsType &&
1381 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1382 <<
property->getDeclName() << PropType
1391 Diag(PropertyDiagLoc, diag::err_weak_property)
1392 <<
property->getDeclName() << Ivar->
getDeclName();
1397 if ((property->getType()->isObjCObjectPointerType() ||
1400 Diag(PropertyDiagLoc, diag::err_strong_property)
1401 <<
property->getDeclName() << Ivar->
getDeclName();
1405 if (
getLangOpts().ObjCAutoRefCount || isARCWeak ||
1408 }
else if (PropertyIvar)
1410 Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);
1412 assert (property &&
"ActOnPropertyImplDecl - property declaration missing");
1414 Context,
SemaRef.CurContext, AtLoc, PropertyLoc, property,
1417 Ivar, PropertyIvarLoc);
1419 if (CompleteTypeErr || !compat)
1422 if (
ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
1423 getterMethod->createImplicitParams(Context, IDecl);
1429 getterMethod->getSelector(), getterMethod->isInstanceMethod());
1446 SemaRef.MarkDeclRefReferenced(SelfExpr);
1448 Context, SelfDecl->
getType(), CK_LValueToRValue, SelfExpr,
nullptr,
1455 LoadSelfExpr,
true,
true);
1458 getterMethod->getReturnType()),
1459 PropertyDiagLoc, IvarRefExpr);
1463 ResExpr =
SemaRef.MaybeCreateExprWithCleanups(ResExpr);
1467 if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
1468 !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
1469 Diag(getterMethod->getLocation(),
1470 diag::warn_property_getter_owning_mismatch);
1471 Diag(property->getLocation(), diag::note_property_declare);
1474 switch (getterMethod->getMethodFamily()) {
1479 Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def)
1480 << 1 << getterMethod->getSelector();
1487 if (
ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
1488 setterMethod->createImplicitParams(Context, IDecl);
1493 setterMethod->getSelector(), setterMethod->isInstanceMethod());
1496 AtLoc, PropertyLoc);
1508 SemaRef.MarkDeclRefReferenced(SelfExpr);
1510 Context, SelfDecl->
getType(), CK_LValueToRValue, SelfExpr,
nullptr,
1517 LoadSelfExpr,
true,
true);
1520 QualType T = Param->getType().getNonReferenceType();
1523 SemaRef.MarkDeclRefReferenced(rhs);
1525 SemaRef.BuildBinOp(S, PropertyDiagLoc, BO_Assign, lhs, rhs);
1526 if (property->getPropertyAttributes() &
1530 dyn_cast_or_null<CXXOperatorCallExpr>(
callExpr))
1531 if (
const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
1532 if (!FuncDecl->isTrivial())
1533 if (property->getType()->isReferenceType()) {
1534 Diag(PropertyDiagLoc,
1535 diag::err_atomic_property_nontrivial_assign_op)
1536 <<
property->getType();
1537 Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
1549 Diag(PropertyLoc, diag::err_duplicate_ivar_use)
1550 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1552 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1557 Diag(PropertyLoc, diag::err_property_implemented) << PropertyId;
1558 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1573 if (PropertyIvar && PropertyIvar != PropertyId)
1588 Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)
1589 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1591 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1596 Diag(PropertyDiagLoc, diag::err_property_implemented) << PropertyId;
1597 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1606 Diag(PropertyLoc, diag::err_objc_direct_dynamic_property);
1608 diag::note_previous_declaration);
1625 bool OverridingProtocolProperty) {
1633 if (!OverridingProtocolProperty &&
1639 Diag(
Property->getLocation(), diag::warn_readonly_property)
1640 <<
Property->getDeclName() << inheritedName;
1643 Diag(
Property->getLocation(), diag::warn_property_attribute)
1644 <<
Property->getDeclName() <<
"copy" << inheritedName;
1650 bool CStrong = (CAttrRetain != 0);
1651 bool SStrong = (SAttrRetain != 0);
1652 if (CStrong != SStrong)
1653 Diag(
Property->getLocation(), diag::warn_property_attribute)
1654 <<
Property->getDeclName() <<
"retain (or strong)" << inheritedName;
1667 Diag(
Property->getLocation(), diag::warn_property_attribute)
1668 <<
Property->getDeclName() <<
"setter" << inheritedName;
1672 Diag(
Property->getLocation(), diag::warn_property_attribute)
1673 <<
Property->getDeclName() <<
"getter" << inheritedName;
1682 if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) {
1685 bool IncompatibleObjC =
false;
1687 if (!
SemaRef.isObjCPointerConversion(RHSType, LHSType, ConvertedType,
1688 IncompatibleObjC) ||
1690 Diag(
Property->getLocation(), diag::warn_property_types_are_incompatible)
1705 property->getType().getNonReferenceType().getAtomicUnqualifiedType();
1706 bool compat = Context.hasSameType(PropertyRValueType, GetterType);
1710 if ((propertyObjCPtr =
1713 compat = Context.canAssignObjCInterfaces(getterObjCPtr, propertyObjCPtr);
1714 else if (!
SemaRef.IsAssignConvertCompatible(
1715 SemaRef.CheckAssignmentConstraints(Loc, GetterType,
1716 PropertyRValueType))) {
1717 Diag(Loc, diag::err_property_accessor_type)
1718 <<
property->getDeclName() << PropertyRValueType
1732 Diag(Loc, diag::warn_accessor_property_type_mismatch)
1733 <<
property->getDeclName()
1748 bool CollectClassPropsOnly =
false,
1749 bool IncludeProtocols =
true) {
1751 for (
auto *Prop : IDecl->properties()) {
1752 if (CollectClassPropsOnly && !Prop->isClassProperty())
1754 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1759 for (
auto *Ext : IDecl->visible_extensions())
1761 CollectClassPropsOnly, IncludeProtocols);
1763 if (IncludeProtocols) {
1765 for (
auto *PI : IDecl->all_referenced_protocols())
1767 CollectClassPropsOnly);
1771 for (
auto *Prop : CATDecl->properties()) {
1772 if (CollectClassPropsOnly && !Prop->isClassProperty())
1774 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1777 if (IncludeProtocols) {
1779 for (
auto *PI : CATDecl->protocols())
1781 CollectClassPropsOnly);
1785 for (
auto *Prop : PDecl->properties()) {
1786 if (CollectClassPropsOnly && !Prop->isClassProperty())
1789 SuperPropMap[std::make_pair(Prop->getIdentifier(),
1790 Prop->isClassProperty())];
1793 if (!PropertyFromSuper ||
1794 PropertyFromSuper->
getIdentifier() != Prop->getIdentifier()) {
1796 PropMap[std::make_pair(Prop->getIdentifier(),
1797 Prop->isClassProperty())];
1803 for (
auto *PI : PDecl->protocols())
1805 CollectClassPropsOnly);
1816 SDecl->collectPropertiesToImplement(PropMap);
1817 SDecl = SDecl->getSuperClass();
1831 Method->isInstanceMethod());
1840 (
Property->getPropertyIvarDecl() == IV))
1846 for (
const auto *
Property : Ext->instance_properties())
1849 (
Property->getPropertyIvarDecl() == IV))
1856 bool SuperClassImplementsGetter =
false;
1857 bool SuperClassImplementsSetter =
false;
1859 SuperClassImplementsSetter =
true;
1864 SuperClassImplementsGetter =
true;
1867 SuperClassImplementsSetter =
true;
1868 if (SuperClassImplementsGetter && SuperClassImplementsSetter)
1883 if (PropMap.empty())
1888 for (
const auto &PropEntry : PropMap) {
1900 if (ImpMethod && !ImpMethod->
getBody()) {
1904 if (ImpMethod && !ImpMethod->
getBody())
1909 Diag(Prop->
getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
1911 if (PID->getLocation().isValid())
1912 Diag(PID->getLocation(), diag::note_property_synthesize);
1926 diag::warn_auto_synthesizing_protocol_property)
1930 (Twine(
"@synthesize ") + Prop->
getName() +
";\n\n").str();
1931 Diag(AtEnd, diag::note_add_synthesize_directive)
1937 if (PropInSuperClass) {
1948 Diag(Prop->
getLocation(), diag::warn_autosynthesis_property_in_superclass)
1981 if (!IDecl->isObjCRequiresPropertyDefs())
2000 if (I ==
SMap.end() &&
2001 (PrimaryClass ==
nullptr ||
2007 ? diag::warn_impl_required_in_category_for_class_property
2008 : diag::warn_setter_getter_impl_required_in_category)
2010 ? diag::warn_impl_required_for_class_property
2011 : diag::warn_setter_getter_impl_required);
2014 if (S.
LangOpts.ObjCDefaultSynthProperties &&
2018 S.
Diag(RID->getLocation(), diag::note_suppressed_class_declare);
2024 bool SynthesizeProperties) {
2038 if ((IDecl =
C->getClassInterface())) {
2047 SynthesizeProperties);
2053 std::unique_ptr<ObjCContainerDecl::PropertyMap> LazyMap;
2056 if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
2074 for (
auto *PropDecl : PDecl->properties()) {
2075 if ((*LazyMap)[std::make_pair(PropDecl->getIdentifier(),
2076 PropDecl->isClassProperty())])
2078 PropMap[std::make_pair(PropDecl->getIdentifier(),
2079 PropDecl->isClassProperty())] = PropDecl;
2084 if (PropMap.empty())
2087 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;
2089 PropImplMap.insert(I->getPropertyDecl());
2097 if (
C && !
C->IsClassExtension())
2098 if ((PrimaryClass =
C->getClassInterface()))
2104 InsMap.insert_range(IMP->methods());
2107 for (ObjCContainerDecl::PropertyMap::iterator
2108 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
2113 PropImplMap.count(Prop) ||
2119 IMPDecl, CDecl,
C, Prop, InsMap);
2130 const auto *
property = propertyImpl->getPropertyDecl();
2133 if (propertyImpl->getPropertyImplementation() ==
2135 (property->getPropertyAttributes() &
2137 property->getGetterMethodDecl() && property->getSetterMethodDecl()) {
2138 auto *getterImpl = propertyImpl->getGetterMethodDecl();
2139 auto *setterImpl = propertyImpl->getSetterMethodDecl();
2140 if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) &&
2141 (!setterImpl || setterImpl->isSynthesizedAccessorStub())) {
2146 Diag(loc, diag::warn_null_resettable_setter)
2147 << setterImpl->getSelector() <<
property->getDeclName();
2160 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2162 for (
auto *Prop : Ext->properties())
2163 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2165 for (ObjCContainerDecl::PropertyMap::iterator I = PM.begin(), E = PM.end();
2171 unsigned Attributes =
Property->getPropertyAttributes();
2172 unsigned AttributesAsWritten =
Property->getPropertyAttributesAsWritten();
2176 GetterMethod =
Property->isClassProperty() ?
2179 SetterMethod =
Property->isClassProperty() ?
2183 GetterMethod =
nullptr;
2185 SetterMethod =
nullptr;
2188 diag::warn_default_atomic_custom_getter_setter)
2190 Diag(
Property->getLocation(), diag::note_property_declare);
2194 diag::warn_default_atomic_custom_getter_setter)
2196 Diag(
Property->getLocation(), diag::note_property_declare);
2208 GetterMethod = PIDecl->getGetterMethodDecl();
2209 SetterMethod = PIDecl->getSetterMethodDecl();
2211 GetterMethod =
nullptr;
2213 SetterMethod =
nullptr;
2214 if ((
bool)GetterMethod ^ (
bool)SetterMethod) {
2217 : SetterMethod->getLocation());
2218 Diag(MethodLoc, diag::warn_atomic_property_rule)
2219 <<
Property->getIdentifier() << (GetterMethod !=
nullptr)
2220 << (SetterMethod !=
nullptr);
2222 if (
Property->getLParenLoc().isValid() &&
2227 StringRef NonatomicStr = AttributesAsWritten?
"nonatomic, "
2230 diag::note_atomic_property_fixup_suggest)
2232 }
else if (
Property->getLParenLoc().isInvalid()) {
2235 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
2237 diag::note_atomic_property_fixup_suggest)
2240 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);
2241 Diag(
Property->getLocation(), diag::note_property_declare);
2254 if (PD && !PD->
hasAttr<NSReturnsNotRetainedAttr>() &&
2274 for (
auto *getterRedecl : method->
redecls()) {
2275 if (getterRedecl->isImplicit())
2279 noteLoc = getterRedecl->getLocation();
2280 fixItLoc = getterRedecl->getEndLoc();
2285 tok::kw___attribute, tok::l_paren, tok::l_paren,
2288 tok::r_paren, tok::r_paren
2290 StringRef spelling =
"__attribute__((objc_method_family(none)))";
2292 if (!macroName.empty())
2293 spelling = macroName;
2295 auto noteDiag =
Diag(noteLoc, diag::note_cocoa_naming_declare_family)
2299 fixItText += spelling;
2316 if (I->getMethodFamily() ==
OMF_init)
2317 InitSelSet.insert(I->getSelector());
2322 I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
2327 bool Ignore =
false;
2329 Ignore = IMD->isUnavailable();
2333 if (
auto *IMD = Ext->getInstanceMethod(MD->
getSelector())) {
2334 Ignore = IMD->isUnavailable();
2340 diag::warn_objc_implementation_missing_designated_init_override)
2353 for (
const auto *A : Property->attrs()) {
2372 bool IsClassProperty =
property->isClassProperty();
2373 GetterMethod = IsClassProperty ?
2381 if (CatDecl->IsClassExtension())
2382 GetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
2384 CatDecl->getClassInterface()->
2387 SetterMethod = IsClassProperty ?
2392 if (CatDecl->IsClassExtension())
2393 SetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
2395 CatDecl->getClassInterface()->
2402 if (!GetterMethod) {
2404 auto *ExistingGetter = CatDecl->getClassInterface()->lookupMethod(
2405 property->
getGetterName(), !IsClassProperty,
true,
false, CatDecl);
2406 if (ExistingGetter) {
2409 <<
property->isDirectProperty() << 1
2410 << ExistingGetter->isDirectMethod()
2411 << ExistingGetter->getDeclName();
2412 Diag(ExistingGetter->getLocation(), diag::note_previous_declaration);
2418 if (!property->
isReadOnly() && !SetterMethod) {
2420 auto *ExistingSetter = CatDecl->getClassInterface()->lookupMethod(
2421 property->
getSetterName(), !IsClassProperty,
true,
false, CatDecl);
2422 if (ExistingSetter) {
2425 <<
property->isDirectProperty() << 1
2426 << ExistingSetter->isDirectMethod()
2427 << ExistingSetter->getDeclName();
2428 Diag(ExistingSetter->getLocation(), diag::note_previous_declaration);
2434 if (!property->
isReadOnly() && SetterMethod) {
2435 if (Context.getCanonicalType(SetterMethod->
getReturnType()) !=
2439 !Context.hasSameUnqualifiedType(
2440 (*SetterMethod->
param_begin())->getType().getNonReferenceType(),
2443 diag::warn_accessor_property_type_mismatch)
2444 <<
property->getDeclName()
2456 if (!GetterMethod) {
2464 QualType resultTy =
property->getType().getAtomicUnqualifiedType();
2470 if (
auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
2473 modifiedTy, modifiedTy);
2478 Context, Loc, Loc, property->
getGetterName(), resultTy,
nullptr, CD,
2479 !IsClassProperty,
false,
2490 GetterMethod->
addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2492 if (property->
hasAttr<NSReturnsNotRetainedAttr>())
2493 GetterMethod->
addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context,
2496 if (property->
hasAttr<ObjCReturnsInnerPointerAttr>())
2498 ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc));
2500 if (
const SectionAttr *SA = property->
getAttr<SectionAttr>())
2501 GetterMethod->
addAttr(SectionAttr::CreateImplicit(
2502 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2504 SemaRef.ProcessAPINotes(GetterMethod);
2515 property->setGetterMethodDecl(GetterMethod);
2520 if (!SetterMethod) {
2528 Context, Loc, Loc, property->
getSetterName(), Context.VoidTy,
nullptr,
2529 CD, !IsClassProperty,
2541 property->getType().getUnqualifiedType().getAtomicUnqualifiedType();
2548 if (
auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
2551 modifiedTy, modifiedTy);
2569 SetterMethod->
addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2572 if (
const SectionAttr *SA = property->
getAttr<SectionAttr>())
2573 SetterMethod->
addAttr(SectionAttr::CreateImplicit(
2574 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2576 SemaRef.ProcessAPINotes(SetterMethod);
2589 property->setSetterMethodDecl(SetterMethod);
2603 if (!IsClassProperty) {
2616 if (!CurrentClass) {
2618 CurrentClass = Cat->getClassInterface();
2619 else if (
ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(CD))
2620 CurrentClass = Impl->getClassInterface();
2629 unsigned &Attributes,
2630 bool propertyInPrimaryClass) {
2637 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2638 <<
"readonly" <<
"readwrite";
2649 !PropertyDecl->
hasAttr<ObjCNSObjectAttr>()) {
2650 Diag(Loc, diag::err_objc_property_requires_object)
2655 :
"retain (or strong)");
2668 Diag(Loc, diag::warn_objc_property_assign_on_object);
2674 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2675 <<
"assign" <<
"copy";
2679 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2680 <<
"assign" <<
"retain";
2684 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2685 <<
"assign" <<
"strong";
2690 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2691 <<
"assign" <<
"weak";
2694 if (PropertyDecl->
hasAttr<IBOutletCollectionAttr>())
2695 Diag(Loc, diag::warn_iboutletcollection_property_assign);
2698 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2699 <<
"unsafe_unretained" <<
"copy";
2703 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2704 <<
"unsafe_unretained" <<
"retain";
2708 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2709 <<
"unsafe_unretained" <<
"strong";
2714 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2715 <<
"unsafe_unretained" <<
"weak";
2720 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2721 <<
"copy" <<
"retain";
2725 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2726 <<
"copy" <<
"strong";
2730 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2731 <<
"copy" <<
"weak";
2736 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"retain"
2741 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"strong"
2750 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2751 <<
"nonnull" <<
"weak";
2757 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"atomic"
2778 else if (propertyInPrimaryClass) {
2783 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
2787 Diag(Loc, diag::warn_objc_property_default_assign_on_object);
2799 Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
2804 Diag(Loc, diag::warn_objc_property_retain_of_block);
2808 Diag(Loc, diag::warn_objc_readonly_property_has_setter);
llvm::DenseMap< const Stmt *, CFGBlock * > SMap
Defines the clang::Expr interface and subclasses for C++ expressions.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines the clang::Preprocessor interface.
static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl, ObjCPropertyDecl *Prop)
static bool areIncompatiblePropertyAttributes(unsigned Attr1, unsigned Attr2, unsigned Kinds)
static Qualifiers::ObjCLifetime getImpliedARCOwnership(ObjCPropertyAttribute::Kind attrs, QualType type)
getImpliedARCOwnership - Given a set of property attributes and a type, infer an expected lifetime.
static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc, ObjCPropertyDecl *property, ObjCIvarDecl *ivar)
static bool LocPropertyAttribute(ASTContext &Context, const char *attrName, SourceLocation LParenLoc, SourceLocation &Loc)
static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, ObjCPropertyDecl *Property)
AddPropertyAttrs - Propagates attributes from a property to the implicitly-declared getter or setter ...
static void checkPropertyDeclWithOwnership(Sema &S, ObjCPropertyDecl *property)
Check the internal consistency of a property declaration with an explicit ownership qualifier.
static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T)
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...
static void checkAtomicPropertyMismatch(Sema &S, ObjCPropertyDecl *OldProperty, ObjCPropertyDecl *NewProperty, bool PropagateAtomicity)
Check for a mismatch in the atomicity of the given properties.
static void setImpliedPropertyAttributeForReadOnlyProperty(ObjCPropertyDecl *property, ObjCIvarDecl *ivar)
setImpliedPropertyAttributeForReadOnlyProperty - This routine evaludates life-time attributes for a '...
static unsigned getOwnershipRule(unsigned attr)
static ObjCMethodDecl * RedeclarePropertyAccessor(ASTContext &Context, ObjCImplementationDecl *Impl, ObjCMethodDecl *AccessorDecl, SourceLocation AtLoc, SourceLocation PropertyLoc)
Create a synthesized property accessor stub inside the @implementation.
static bool hasWrittenStorageAttribute(ObjCPropertyDecl *Prop, ObjCPropertyQueryKind QueryKind)
Determine whether any storage attributes were written on the property.
static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, ObjCInterfaceDecl::PropertyMap &PropMap)
CollectSuperClassPropertyImplementations - This routine collects list of properties to be implemented...
static const unsigned OwnershipMask
static void DiagnoseUnimplementedAccessor(Sema &S, ObjCInterfaceDecl *PrimaryClass, Selector Method, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, ObjCCategoryDecl *C, ObjCPropertyDecl *Prop, llvm::SmallPtrSet< const ObjCMethodDecl *, 8 > &SMap)
static ObjCPropertyDecl * SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc, ObjCInterfaceDecl *ClassDecl, ObjCPropertyDecl *Property)
SelectPropertyForSynthesisFromProtocols - Finds the most appropriate property declaration that should...
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.
static ObjCPropertyAttribute::Kind makePropertyAttributesAsWritten(unsigned Attributes)
static bool isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2, ObjCPropertyAttribute::Kind Kind)
This file declares semantic analysis for Objective-C.
Defines the SourceManager interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool propertyTypesAreCompatible(QualType, QualType)
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Attr - This represents one attribute.
A call to an overloaded operator written using operator syntax.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
void makeDeclVisibleInContext(NamedDecl *D)
Makes a declaration visible within this context.
DeclContextLookupResult lookup_result
void addDecl(Decl *D)
Add the declaration D into this context.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
void setAttrs(const AttrVec &Attrs)
bool isUnavailable(std::string *Message=nullptr) const
Determine whether this declaration is marked 'unavailable'.
AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple(), StringRef *RealizedPlatform=nullptr) const
Determine the availability of the given declaration.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isInvalidDecl() const
SourceLocation getLocation() const
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
void setLexicalDeclContext(DeclContext *DC)
SourceLocation getIdentifierLoc() const
void setObjCWeakProperty(bool Val=true)
const IdentifierInfo * getIdentifier() const
This represents one expression.
Represents difference between two FPOptions values.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
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.
Represents a function declaration or definition.
One of these records is kept for each identifier that is lexed.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)
Create the initialization entity for the result of a function.
clang::ObjCRuntime ObjCRuntime
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ObjCCategoryDecl - Represents a category declaration.
ObjCInterfaceDecl * getClassInterface()
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCContainerDecl - Represents a container for method declarations.
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
method_range methods() const
instmeth_range instance_methods() const
llvm::SmallDenseSet< const ObjCProtocolDecl *, 8 > ProtocolPropertySet
ObjCPropertyDecl * getProperty(const IdentifierInfo *Id, bool IsInstance) const
instprop_range instance_properties() const
llvm::MapVector< std::pair< IdentifierInfo *, unsigned >, ObjCPropertyDecl * > PropertyMap
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
llvm::SmallVector< ObjCPropertyDecl *, 8 > PropertyDeclOrder
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
prop_range properties() const
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const
This routine returns 'true' if a user declared setter method was found in the class,...
Captures information about "declaration specifiers" specific to Objective-C.
ObjCPropertyAttribute::Kind getPropertyAttributes() const
SourceLocation getGetterNameLoc() const
SourceLocation getSetterNameLoc() const
void addPropertyImplementation(ObjCPropertyImplDecl *property)
propimpl_range property_impls() const
ObjCPropertyImplDecl * FindPropertyImplDecl(IdentifierInfo *propertyId, ObjCPropertyQueryKind queryKind) const
FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl added to the list of thos...
const ObjCInterfaceDecl * getClassInterface() const
ObjCPropertyImplDecl * FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const
FindPropertyImplIvarDecl - This method lookup the ivar in the list of properties implemented in this ...
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCPropertyDecl * FindPropertyVisibleInPrimaryClass(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyVisibleInPrimaryClass - Finds declaration of the property with name 'PropertyId' in the p...
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
all_protocol_range all_referenced_protocols() const
visible_extensions_range visible_extensions() const
ObjCCategoryDecl * FindCategoryDeclaration(const IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
protocol_range protocols() const
const ObjCInterfaceDecl * isObjCRequiresPropertyDefs() const
isObjCRequiresPropertyDefs - Checks that a class or one of its super classes must not be auto-synthes...
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...
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,...
bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, bool lookupCategory, bool RHSIsQualifiedID=false)
ClassImplementsProtocol - Checks that 'lProto' protocol has been implemented in IDecl class,...
ObjCImplementationDecl * getImplementation() const
bool hasDesignatedInitializers() const
Returns true if this interface decl contains at least one initializer marked with the 'objc_designate...
void getDesignatedInitializers(llvm::SmallVectorImpl< const ObjCMethodDecl * > &Methods) const
Returns the designated initializers for the interface.
void collectPropertiesToImplement(PropertyMap &PM) const override
This routine collects list of properties to be implemented in the class.
bool isArcWeakrefUnavailable() const
isArcWeakrefUnavailable - Checks for a class or one of its super classes to be incompatible with __we...
ObjCInterfaceDecl * getSuperClass() const
known_extensions_range known_extensions() const
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
bool getSynthesize() const
static ObjCIvarDecl * Create(ASTContext &C, ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW=nullptr, bool synthesized=false)
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
ObjCMethodDecl - Represents an instance or class method declaration.
void setDefined(bool isDefined)
unsigned param_size() const
void setSelfDecl(ImplicitParamDecl *SD)
bool isPropertyAccessor() const
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, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
param_const_iterator param_begin() const
void setCmdDecl(ImplicitParamDecl *CD)
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
bool isSynthesizedAccessorStub() const
void setPropertyAccessor(bool isAccessor)
Selector getSelector() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID)
createImplicitParams - Used to lazily create the self and cmd implicit parameters.
QualType getReturnType() const
ParmVarDecl *const * param_iterator
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
Represents one property declaration in an Objective-C interface.
ObjCPropertyQueryKind getQueryKind() const
bool isClassProperty() const
void setPropertyImplementation(PropertyControl pc)
void setSetterName(Selector Sel, SourceLocation Loc=SourceLocation())
ObjCMethodDecl * getGetterMethodDecl() const
bool isInstanceProperty() const
void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal)
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, ObjCPropertyQueryKind queryKind)
Lookup a property by name in the specified DeclContext.
bool isDirectProperty() const
Selector getSetterName() const
void setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal)
void overwritePropertyAttributes(unsigned PRVal)
Selector getGetterName() const
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const
Get the default name of the synthesized ivar.
ObjCPropertyAttribute::Kind getPropertyAttributes() const
static ObjCPropertyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation AtLocation, SourceLocation LParenLocation, QualType T, TypeSourceInfo *TSI, PropertyControl propControl=None)
void setGetterName(Selector Sel, SourceLocation Loc=SourceLocation())
PropertyControl getPropertyImplementation() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Kind getPropertyImplementation() const
void setSetterMethodDecl(ObjCMethodDecl *MD)
ObjCPropertyDecl * getPropertyDecl() const
void setSetterCXXAssignment(Expr *setterCXXAssignment)
static ObjCPropertyImplDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc)
void setGetterMethodDecl(ObjCMethodDecl *MD)
void setGetterCXXConstructor(Expr *getterCXXConstructor)
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
protocol_range protocols() const
The basic abstraction for the target Objective-C runtime.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
bool allowsDirectDispatch() const
Does this runtime supports direct dispatch.
bool isFragile() const
The inverse of isNonFragile(): does this runtime follow the set of implied behaviors for a "fragile" ...
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const
Return the name of the macro defined before Loc that has spelling Tokens.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
bool isObjCGCStrong() const
true when Type is objc's strong.
bool isObjCGCWeak() const
true when Type is objc's weak.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasObjCLifetime() const
void addObjCLifetime(ObjCLifetime type)
void setObjCLifetime(ObjCLifetime type)
bool hasFlexibleArrayMember() const
Scope - A scope is a transient data structure that is used while parsing the program.
Smart pointer class that efficiently represents Objective-C method names.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl, SourceLocation AtEnd)
DefaultSynthesizeProperties - This routine default synthesizes all properties which must be synthesiz...
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
void ProcessPropertyDecl(ObjCPropertyDecl *property)
Process the specified property declaration and create decls for the setters and getters as needed.
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.
void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)
Diagnose any null-resettable synthesized setters.
llvm::SmallPtrSet< Selector, 8 > SelectorSet
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...
bool CheckARCMethodDecl(ObjCMethodDecl *method)
Check a method declaration for compatibility with the Objective-C ARC conventions.
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D)
Decl * ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, bool SynthesizeProperties)
DiagnoseUnimplementedProperties - This routine warns on those properties which must be implemented by...
void AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl)
AtomicPropertySetterGetterRules - This routine enforces the rule (via warning) when atomic property h...
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 ...
void DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD)
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, unsigned &Attributes, bool propertyInPrimaryClass)
Ensure attributes are consistent with type.
void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
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...
void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ObjCInterfaceDecl *CurrentClass, ResultTypeCompatibilityKind RTC)
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddInstanceMethodToGlobalPool - All instance methods in a translation unit are added to a global pool...
RAII object to handle the state changes required to synthesize a function body.
Sema - This implements semantic analysis and AST building for C.
bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC)
isObjCPointerConversion - Determines whether this is an Objective-C pointer conversion.
const LangOptions & getLangOpts() const
const LangOptions & LangOpts
@ AbstractSynthesizedIvarType
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
Stores token information for comparing actual tokens with predefined values.
Token - This structure provides full information about a lexed token.
SourceLocation getEndLoc() const
Get the end source location.
SourceLocation getBeginLoc() const
Get the begin source location.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
bool isBlockPointerType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isArithmeticType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isObjCARCImplicitlyUnretainedType() const
Determines if this type, which must satisfy isObjCLifetimeType(), is implicitly __unsafe_unretained r...
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
void setType(QualType newType)
ObjCPropertyAttribute::Kind - list of property attributes.
@ kind_nullability
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Nullable
Values of this type can be null.
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ NonNull
Values of this type can never be null.
std::pair< FileID, unsigned > FileIDAndOffset
ObjCMethodFamily
A family of Objective-C methods.
@ Property
The type of a property.
const FunctionProtoType * T
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
This little struct is used to capture information about structure field declarators,...
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Qualifiers Quals
The local qualifiers.