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);
280 bool invalidTemp =
false;
281 StringRef file =
SM.getBufferData(locInfo.first, &invalidTemp);
284 const char *tokenBegin = file.data() + locInfo.second;
287 Lexer lexer(
SM.getLocForStartOfFile(locInfo.first),
288 Context.getLangOpts(),
289 file.begin(), tokenBegin, file.end());
293 if (
Tok.is(tok::raw_identifier) &&
Tok.getRawIdentifier() == attrName) {
294 Loc =
Tok.getLocation();
297 }
while (
Tok.isNot(tok::r_paren));
305 bool PropagateAtomicity) {
311 if (OldIsAtomic == NewIsAtomic)
return;
317 auto Attrs = Property->getPropertyAttributes();
326 if (Property->getPropertyAttributesAsWritten() &
337 if (PropagateAtomicity &&
340 Attrs = Attrs & ~AtomicityMask;
352 if ((OldIsAtomic && isImplicitlyReadonlyAtomic(OldProperty)) ||
353 (NewIsAtomic && isImplicitlyReadonlyAtomic(NewProperty)))
359 if (
auto Category = dyn_cast<ObjCCategoryDecl>(OldDC))
360 OldContextName = Category->getClassInterface()->getIdentifier();
374 unsigned &Attributes,
const unsigned AttributesAsWritten,
QualType T,
389 bool isClassProperty =
400 Diag(AtLoc, diag::err_duplicate_property);
419 ? diag::err_use_continuation_class_redeclaration_readwrite
420 : diag::err_use_continuation_class;
431 Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)
442 unsigned ExistingOwnership
445 if (ExistingOwnership && NewOwnership != ExistingOwnership) {
448 Diag(AtLoc, diag::warn_property_attr_mismatch);
462 Diag(AtLoc, diag::warn_property_implicitly_mismatched);
470 FD, GetterSel, GetterNameLoc,
471 SetterSel, SetterNameLoc,
473 Attributes, AttributesAsWritten,
474 T, TSI, MethodImplKind, DC);
484 bool IncompatibleObjC =
false;
496 (!
SemaRef.isObjCPointerConversion(ClassExtPropertyT,
497 PrimaryClassPropertyT, ConvertedType,
498 IncompatibleObjC)) ||
501 diag::err_type_mismatch_continuation_class) << PDecl->
getType();
521 const unsigned Attributes,
const unsigned AttributesAsWritten,
QualType T,
537 !T->isObjCRetainableType());
551 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
555 if (T->isObjCObjectType()) {
557 StarLoc =
SemaRef.getLocForEndOfToken(StarLoc);
560 T = Context.getObjCObjectPointerType(T);
562 TInfo = Context.getTrivialTypeSourceInfo(T, TLoc);
569 LParenLoc, T, TInfo);
571 bool isClassProperty =
578 Diag(prevDecl->getLocation(), diag::note_property_declare);
587 if (T->isArrayType() || T->isFunctionType()) {
588 Diag(AtLoc, diag::err_property_type) << T;
599 SemaRef.ProcessDeclAttributes(S, PDecl, FD.
D);
643 if (MethodImplKind == tok::objc_required)
645 else if (MethodImplKind == tok::objc_optional)
658 CDecl->
hasAttr<ObjCDirectMembersAttr>()) {
686 if (propertyLifetime == ivarLifetime)
return;
712 switch (propertyLifetime) {
715 <<
property->getDeclName()
722 <<
property->getDeclName()
729 << ((
property->getPropertyAttributesAsWritten() &
734 llvm_unreachable(
"properties cannot be autoreleasing");
743 S.
Diag(propertyImplLoc, diag::note_property_synthesize);
775 return (Attr1 & Kind) != (Attr2 & Kind);
780 return ((Attr1 & Kinds) != 0) != ((Attr2 & Kinds) != 0);
793 "Expected a property from a protocol");
798 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
803 for (
const auto *PI : SDecl->all_referenced_protocols()) {
805 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
808 SDecl = SDecl->getSuperClass();
812 if (Properties.empty())
816 size_t SelectedIndex = 0;
817 for (
const auto &Prop : llvm::enumerate(Properties)) {
819 if (Property->isReadOnly() && !Prop.value()->isReadOnly()) {
820 Property = Prop.value();
821 SelectedIndex = Prop.index();
824 if (Property != OriginalProperty) {
826 Properties[SelectedIndex] = OriginalProperty;
830 unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
832 IncompatibleType = 0,
833 HasNoExpectedAttribute,
834 HasUnexpectedAttribute,
840 struct MismatchingProperty {
843 StringRef AttributeName;
848 unsigned Attr = Prop->getPropertyAttributesAsWritten();
849 if (
Attr != OriginalAttributes) {
850 auto Diag = [&](
bool OriginalHasAttribute, StringRef AttributeName) {
851 MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
852 : HasUnexpectedAttribute;
853 Mismatches.push_back({Prop, Kind, AttributeName});
871 OriginalAttributes,
Attr,
876 "retain (or strong)");
885 if (Property->getGetterName() != Prop->getGetterName()) {
886 Mismatches.push_back({Prop, DifferentGetter,
""});
889 if (!Property->isReadOnly() && !Prop->isReadOnly() &&
890 Property->getSetterName() != Prop->getSetterName()) {
891 Mismatches.push_back({Prop, DifferentSetter,
""});
896 bool IncompatibleObjC =
false;
899 || IncompatibleObjC) {
900 Mismatches.push_back({Prop, IncompatibleType,
""});
906 if (Mismatches.empty())
911 bool HasIncompatibleAttributes =
false;
912 for (
const auto &
Note : Mismatches)
913 HasIncompatibleAttributes =
914 Note.Kind != IncompatibleType ?
true : HasIncompatibleAttributes;
917 auto Diag = S.
Diag(Property->getLocation(),
918 Property != OriginalProperty || HasIncompatibleAttributes
919 ? diag::err_protocol_property_mismatch
920 : diag::warn_protocol_property_mismatch);
921 Diag << Mismatches[0].Kind;
922 switch (Mismatches[0].Kind) {
923 case IncompatibleType:
924 Diag << Property->getType();
926 case HasNoExpectedAttribute:
927 case HasUnexpectedAttribute:
928 Diag << Mismatches[0].AttributeName;
930 case DifferentGetter:
931 Diag << Property->getGetterName();
933 case DifferentSetter:
934 Diag << Property->getSetterName();
938 for (
const auto &
Note : Mismatches) {
940 S.
Diag(
Note.Prop->getLocation(), diag::note_protocol_property_declare)
943 case IncompatibleType:
946 case HasNoExpectedAttribute:
947 case HasUnexpectedAttribute:
950 case DifferentGetter:
953 case DifferentSetter:
959 S.
Diag(AtLoc, diag::note_property_synthesize);
977 auto Category = dyn_cast<ObjCCategoryDecl>(Prop->
getDeclContext());
978 if (!Category || !Category->IsClassExtension())
return false;
981 auto OrigClass = Category->getClassInterface();
984 return OrigProp->getPropertyAttributesAsWritten() &
OwnershipMask;
988 for (
const auto *Proto : OrigClass->all_referenced_protocols()) {
991 return OrigProp->getPropertyAttributesAsWritten() &
OwnershipMask;
1006 Decl->getSelector(),
Decl->getReturnType(),
1007 Decl->getReturnTypeSourceInfo(), Impl,
Decl->isInstanceMethod(),
1008 Decl->isVariadic(),
Decl->isPropertyAccessor(),
1010 Decl->getImplementationControl(),
Decl->hasRelatedResultType());
1017 Decl->getSelectorLocs(SelLocs);
1034 dyn_cast<ObjCContainerDecl>(
SemaRef.CurContext);
1036 if (!ClassImpDecl) {
1037 Diag(AtLoc, diag::err_missing_property_context);
1041 PropertyIvarLoc = PropertyLoc;
1051 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
1056 "ActOnPropertyImplDecl - @implementation without @interface");
1061 Diag(PropertyLoc, diag::err_bad_property_decl) << IDecl->
getDeclName();
1064 if (property->isClassProperty() && Synthesize) {
1065 Diag(PropertyLoc, diag::err_synthesize_on_class_property) << PropertyId;
1072 Diag(AtLoc, diag::warn_implicit_atomic_property);
1075 Diag(property->getLocation(), diag::note_property_declare);
1079 dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
1080 if (!CD->IsClassExtension()) {
1081 Diag(PropertyLoc, diag::err_category_property) << CD->getDeclName();
1082 Diag(property->getLocation(), diag::note_property_declare);
1087 property->hasAttr<IBOutletAttr>() && !AtLoc.
isValid()) {
1088 bool ReadWriteProperty =
false;
1094 PIkind = ExtProp->getPropertyAttributesAsWritten();
1096 ReadWriteProperty =
true;
1102 if (!ReadWriteProperty) {
1103 Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property)
1107 property->getLParenLoc(), readonlyLoc)) {
1110 SourceRange ReadonlySourceRange(readonlyLoc, endLoc);
1111 Diag(property->getLocation(),
1112 diag::note_auto_readonly_iboutlet_fixup_suggest) <<
1121 }
else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
1123 Diag(AtLoc, diag::err_synthesize_category_decl);
1128 Diag(AtLoc, diag::err_missing_property_interface);
1141 Diag(PropertyLoc, diag::err_bad_category_property_decl)
1142 << Category->getDeclName();
1146 Diag(AtLoc, diag::err_bad_property_context);
1150 bool CompleteTypeErr =
false;
1156 PropertyIvar = PropertyId;
1160 QualType PropType =
property->getType();
1163 if (
SemaRef.RequireCompleteType(PropertyDiagLoc, PropertyIvarType,
1164 diag::err_incomplete_synthesized_property,
1165 property->getDeclName())) {
1166 Diag(property->getLocation(), diag::note_property_declare);
1167 CompleteTypeErr =
true;
1171 (property->getPropertyAttributesAsWritten() &
1179 bool isARCWeak =
false;
1185 Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);
1186 Diag(property->getLocation(), diag::note_property_declare);
1198 Diag(PropertyDiagLoc,
1200 ? diag::err_synthesizing_arc_weak_property_disabled
1201 : diag::err_synthesizing_arc_weak_property_no_runtime);
1202 Diag(property->getLocation(), diag::note_property_declare);
1204 CompleteTypeErr =
true;
1211 Diag(property->getLocation(),
1212 diag::err_arc_weak_unavailable_property)
1213 << PropertyIvarType;
1232 Diag(PropertyDiagLoc,
1233 diag::warn_autosynthesis_property_ivar_match)
1234 << PropertyId << (Ivar ==
nullptr) << PropertyIvar
1236 Diag(property->getLocation(), diag::note_property_declare);
1244 if ((
getLangOpts().ObjCAutoRefCount || isARCWeak) &&
1252 Diag(PropertyDiagLoc,
1253 diag::err_arc_objc_property_default_assign_on_object);
1254 Diag(property->getLocation(), diag::note_property_declare);
1258 assert(lifetime &&
"no lifetime for property?");
1262 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);
1266 if (Context.getLangOpts().PointerAuthObjcInterfaceSel &&
1269 if (
auto PAQ = Context.getObjCMemberSelTypePtrAuth())
1271 Context.getPointerAuthType(PropertyIvarType, PAQ);
1276 PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,
1277 PropertyIvarType,
nullptr,
1279 (
Expr *)
nullptr,
true);
1280 if (
SemaRef.RequireNonAbstractType(PropertyIvarLoc, PropertyIvarType,
1281 diag::err_abstract_type_in_decl,
1283 Diag(property->getLocation(), diag::note_property_declare);
1285 CompleteTypeErr =
true;
1287 if (!CompleteTypeErr) {
1290 Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)
1291 << PropertyIvarType;
1292 CompleteTypeErr =
true;
1295 if (CompleteTypeErr)
1301 Diag(PropertyDiagLoc, diag::err_missing_property_ivar_decl)
1307 Diag(PropertyDiagLoc, diag::err_ivar_in_superclass_use)
1314 property->setPropertyIvarDecl(Ivar);
1319 if (!Context.hasSameType(PropertyIvarType, IvarType)) {
1322 compat = Context.canAssignObjCInterfaces(
1326 compat =
SemaRef.IsAssignConvertCompatible(
1327 SemaRef.CheckAssignmentConstraints(PropertyIvarLoc,
1328 PropertyIvarType, IvarType));
1331 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1332 <<
property->getDeclName() << PropType
1344 if (lhsType != rhsType &&
1346 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1347 <<
property->getDeclName() << PropType
1356 Diag(PropertyDiagLoc, diag::err_weak_property)
1357 <<
property->getDeclName() << Ivar->
getDeclName();
1362 if ((property->getType()->isObjCObjectPointerType() ||
1365 Diag(PropertyDiagLoc, diag::err_strong_property)
1366 <<
property->getDeclName() << Ivar->
getDeclName();
1370 if (
getLangOpts().ObjCAutoRefCount || isARCWeak ||
1373 }
else if (PropertyIvar)
1375 Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);
1377 assert (property &&
"ActOnPropertyImplDecl - property declaration missing");
1379 Context,
SemaRef.CurContext, AtLoc, PropertyLoc, property,
1382 Ivar, PropertyIvarLoc);
1384 if (CompleteTypeErr || !compat)
1387 if (
ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
1388 getterMethod->createImplicitParams(Context, IDecl);
1394 getterMethod->getSelector(), getterMethod->isInstanceMethod());
1411 SemaRef.MarkDeclRefReferenced(SelfExpr);
1413 Context, SelfDecl->
getType(), CK_LValueToRValue, SelfExpr,
nullptr,
1420 LoadSelfExpr,
true,
true);
1423 getterMethod->getReturnType()),
1424 PropertyDiagLoc, IvarRefExpr);
1428 ResExpr =
SemaRef.MaybeCreateExprWithCleanups(ResExpr);
1432 if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
1433 !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
1434 Diag(getterMethod->getLocation(),
1435 diag::warn_property_getter_owning_mismatch);
1436 Diag(property->getLocation(), diag::note_property_declare);
1439 switch (getterMethod->getMethodFamily()) {
1444 Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def)
1445 << 1 << getterMethod->getSelector();
1452 if (
ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
1453 setterMethod->createImplicitParams(Context, IDecl);
1458 setterMethod->getSelector(), setterMethod->isInstanceMethod());
1461 AtLoc, PropertyLoc);
1473 SemaRef.MarkDeclRefReferenced(SelfExpr);
1475 Context, SelfDecl->
getType(), CK_LValueToRValue, SelfExpr,
nullptr,
1482 LoadSelfExpr,
true,
true);
1485 QualType T = Param->getType().getNonReferenceType();
1488 SemaRef.MarkDeclRefReferenced(rhs);
1490 SemaRef.BuildBinOp(S, PropertyDiagLoc, BO_Assign, lhs, rhs);
1491 if (property->getPropertyAttributes() &
1495 dyn_cast_or_null<CXXOperatorCallExpr>(
callExpr))
1496 if (
const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
1497 if (!FuncDecl->isTrivial())
1498 if (property->getType()->isReferenceType()) {
1499 Diag(PropertyDiagLoc,
1500 diag::err_atomic_property_nontrivial_assign_op)
1501 <<
property->getType();
1502 Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
1514 Diag(PropertyLoc, diag::err_duplicate_ivar_use)
1515 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1517 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1522 Diag(PropertyLoc, diag::err_property_implemented) << PropertyId;
1523 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1538 if (PropertyIvar && PropertyIvar != PropertyId)
1553 Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)
1554 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1556 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1561 Diag(PropertyDiagLoc, diag::err_property_implemented) << PropertyId;
1562 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1571 Diag(PropertyLoc, diag::err_objc_direct_dynamic_property);
1573 diag::note_previous_declaration);
1590 bool OverridingProtocolProperty) {
1598 if (!OverridingProtocolProperty &&
1604 Diag(
Property->getLocation(), diag::warn_readonly_property)
1605 <<
Property->getDeclName() << inheritedName;
1608 Diag(
Property->getLocation(), diag::warn_property_attribute)
1609 <<
Property->getDeclName() <<
"copy" << inheritedName;
1615 bool CStrong = (CAttrRetain != 0);
1616 bool SStrong = (SAttrRetain != 0);
1617 if (CStrong != SStrong)
1618 Diag(
Property->getLocation(), diag::warn_property_attribute)
1619 <<
Property->getDeclName() <<
"retain (or strong)" << inheritedName;
1632 Diag(
Property->getLocation(), diag::warn_property_attribute)
1633 <<
Property->getDeclName() <<
"setter" << inheritedName;
1637 Diag(
Property->getLocation(), diag::warn_property_attribute)
1638 <<
Property->getDeclName() <<
"getter" << inheritedName;
1647 if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) {
1650 bool IncompatibleObjC =
false;
1652 if (!
SemaRef.isObjCPointerConversion(RHSType, LHSType, ConvertedType,
1653 IncompatibleObjC) ||
1655 Diag(
Property->getLocation(), diag::warn_property_types_are_incompatible)
1670 property->getType().getNonReferenceType().getAtomicUnqualifiedType();
1671 bool compat = Context.hasSameType(PropertyRValueType, GetterType);
1675 if ((propertyObjCPtr =
1678 compat = Context.canAssignObjCInterfaces(getterObjCPtr, propertyObjCPtr);
1679 else if (!
SemaRef.IsAssignConvertCompatible(
1680 SemaRef.CheckAssignmentConstraints(Loc, GetterType,
1681 PropertyRValueType))) {
1682 Diag(Loc, diag::err_property_accessor_type)
1683 <<
property->getDeclName() << PropertyRValueType
1697 Diag(Loc, diag::warn_accessor_property_type_mismatch)
1698 <<
property->getDeclName()
1713 bool CollectClassPropsOnly =
false,
1714 bool IncludeProtocols =
true) {
1716 for (
auto *Prop : IDecl->properties()) {
1717 if (CollectClassPropsOnly && !Prop->isClassProperty())
1719 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1724 for (
auto *Ext : IDecl->visible_extensions())
1726 CollectClassPropsOnly, IncludeProtocols);
1728 if (IncludeProtocols) {
1730 for (
auto *PI : IDecl->all_referenced_protocols())
1732 CollectClassPropsOnly);
1736 for (
auto *Prop : CATDecl->properties()) {
1737 if (CollectClassPropsOnly && !Prop->isClassProperty())
1739 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1742 if (IncludeProtocols) {
1744 for (
auto *PI : CATDecl->protocols())
1746 CollectClassPropsOnly);
1750 for (
auto *Prop : PDecl->properties()) {
1751 if (CollectClassPropsOnly && !Prop->isClassProperty())
1754 SuperPropMap[std::make_pair(Prop->getIdentifier(),
1755 Prop->isClassProperty())];
1758 if (!PropertyFromSuper ||
1759 PropertyFromSuper->
getIdentifier() != Prop->getIdentifier()) {
1761 PropMap[std::make_pair(Prop->getIdentifier(),
1762 Prop->isClassProperty())];
1768 for (
auto *PI : PDecl->protocols())
1770 CollectClassPropsOnly);
1781 SDecl->collectPropertiesToImplement(PropMap);
1782 SDecl = SDecl->getSuperClass();
1796 Method->isInstanceMethod());
1805 (
Property->getPropertyIvarDecl() == IV))
1811 for (
const auto *
Property : Ext->instance_properties())
1814 (
Property->getPropertyIvarDecl() == IV))
1821 bool SuperClassImplementsGetter =
false;
1822 bool SuperClassImplementsSetter =
false;
1824 SuperClassImplementsSetter =
true;
1829 SuperClassImplementsGetter =
true;
1832 SuperClassImplementsSetter =
true;
1833 if (SuperClassImplementsGetter && SuperClassImplementsSetter)
1848 if (PropMap.empty())
1853 for (
const auto &PropEntry : PropMap) {
1865 if (ImpMethod && !ImpMethod->
getBody()) {
1869 if (ImpMethod && !ImpMethod->
getBody())
1874 Diag(Prop->
getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
1876 if (PID->getLocation().isValid())
1877 Diag(PID->getLocation(), diag::note_property_synthesize);
1891 diag::warn_auto_synthesizing_protocol_property)
1895 (Twine(
"@synthesize ") + Prop->
getName() +
";\n\n").str();
1896 Diag(AtEnd, diag::note_add_synthesize_directive)
1902 if (PropInSuperClass) {
1913 Diag(Prop->
getLocation(), diag::warn_autosynthesis_property_in_superclass)
1946 if (!IDecl->isObjCRequiresPropertyDefs())
1965 if (I == SMap.end() &&
1966 (PrimaryClass ==
nullptr ||
1972 ? diag::warn_impl_required_in_category_for_class_property
1973 : diag::warn_setter_getter_impl_required_in_category)
1975 ? diag::warn_impl_required_for_class_property
1976 : diag::warn_setter_getter_impl_required);
1979 if (S.
LangOpts.ObjCDefaultSynthProperties &&
1983 S.
Diag(RID->getLocation(), diag::note_suppressed_class_declare);
1989 bool SynthesizeProperties) {
2003 if ((IDecl =
C->getClassInterface())) {
2012 SynthesizeProperties);
2018 std::unique_ptr<ObjCContainerDecl::PropertyMap> LazyMap;
2021 if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
2039 for (
auto *PropDecl : PDecl->properties()) {
2040 if ((*LazyMap)[std::make_pair(PropDecl->getIdentifier(),
2041 PropDecl->isClassProperty())])
2043 PropMap[std::make_pair(PropDecl->getIdentifier(),
2044 PropDecl->isClassProperty())] = PropDecl;
2049 if (PropMap.empty())
2052 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;
2054 PropImplMap.insert(I->getPropertyDecl());
2062 if (
C && !
C->IsClassExtension())
2063 if ((PrimaryClass =
C->getClassInterface()))
2069 InsMap.insert_range(IMP->methods());
2072 for (ObjCContainerDecl::PropertyMap::iterator
2073 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
2078 PropImplMap.count(Prop) ||
2084 IMPDecl, CDecl,
C, Prop, InsMap);
2095 const auto *
property = propertyImpl->getPropertyDecl();
2098 if (propertyImpl->getPropertyImplementation() ==
2100 (property->getPropertyAttributes() &
2102 property->getGetterMethodDecl() && property->getSetterMethodDecl()) {
2103 auto *getterImpl = propertyImpl->getGetterMethodDecl();
2104 auto *setterImpl = propertyImpl->getSetterMethodDecl();
2105 if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) &&
2106 (!setterImpl || setterImpl->isSynthesizedAccessorStub())) {
2111 Diag(loc, diag::warn_null_resettable_setter)
2112 << setterImpl->getSelector() <<
property->getDeclName();
2125 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2127 for (
auto *Prop : Ext->properties())
2128 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2130 for (ObjCContainerDecl::PropertyMap::iterator I = PM.begin(), E = PM.end();
2136 unsigned Attributes =
Property->getPropertyAttributes();
2137 unsigned AttributesAsWritten =
Property->getPropertyAttributesAsWritten();
2141 GetterMethod =
Property->isClassProperty() ?
2144 SetterMethod =
Property->isClassProperty() ?
2148 GetterMethod =
nullptr;
2150 SetterMethod =
nullptr;
2153 diag::warn_default_atomic_custom_getter_setter)
2155 Diag(
Property->getLocation(), diag::note_property_declare);
2159 diag::warn_default_atomic_custom_getter_setter)
2161 Diag(
Property->getLocation(), diag::note_property_declare);
2173 GetterMethod = PIDecl->getGetterMethodDecl();
2174 SetterMethod = PIDecl->getSetterMethodDecl();
2176 GetterMethod =
nullptr;
2178 SetterMethod =
nullptr;
2179 if ((
bool)GetterMethod ^ (
bool)SetterMethod) {
2182 : SetterMethod->getLocation());
2183 Diag(MethodLoc, diag::warn_atomic_property_rule)
2184 <<
Property->getIdentifier() << (GetterMethod !=
nullptr)
2185 << (SetterMethod !=
nullptr);
2187 if (
Property->getLParenLoc().isValid() &&
2192 StringRef NonatomicStr = AttributesAsWritten?
"nonatomic, "
2195 diag::note_atomic_property_fixup_suggest)
2197 }
else if (
Property->getLParenLoc().isInvalid()) {
2200 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
2202 diag::note_atomic_property_fixup_suggest)
2205 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);
2206 Diag(
Property->getLocation(), diag::note_property_declare);
2219 if (PD && !PD->
hasAttr<NSReturnsNotRetainedAttr>() &&
2239 for (
auto *getterRedecl : method->
redecls()) {
2240 if (getterRedecl->isImplicit())
2244 noteLoc = getterRedecl->getLocation();
2245 fixItLoc = getterRedecl->getEndLoc();
2250 tok::kw___attribute, tok::l_paren, tok::l_paren,
2253 tok::r_paren, tok::r_paren
2255 StringRef spelling =
"__attribute__((objc_method_family(none)))";
2257 if (!macroName.empty())
2258 spelling = macroName;
2260 auto noteDiag =
Diag(noteLoc, diag::note_cocoa_naming_declare_family)
2264 fixItText += spelling;
2281 if (I->getMethodFamily() ==
OMF_init)
2282 InitSelSet.insert(I->getSelector());
2287 I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
2292 bool Ignore =
false;
2294 Ignore = IMD->isUnavailable();
2298 if (
auto *IMD = Ext->getInstanceMethod(MD->
getSelector())) {
2299 Ignore = IMD->isUnavailable();
2305 diag::warn_objc_implementation_missing_designated_init_override)
2318 for (
const auto *A : Property->attrs()) {
2337 bool IsClassProperty =
property->isClassProperty();
2338 GetterMethod = IsClassProperty ?
2346 if (CatDecl->IsClassExtension())
2347 GetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
2349 CatDecl->getClassInterface()->
2352 SetterMethod = IsClassProperty ?
2357 if (CatDecl->IsClassExtension())
2358 SetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
2360 CatDecl->getClassInterface()->
2367 if (!GetterMethod) {
2369 auto *ExistingGetter = CatDecl->getClassInterface()->lookupMethod(
2370 property->
getGetterName(), !IsClassProperty,
true,
false, CatDecl);
2371 if (ExistingGetter) {
2374 <<
property->isDirectProperty() << 1
2375 << ExistingGetter->isDirectMethod()
2376 << ExistingGetter->getDeclName();
2377 Diag(ExistingGetter->getLocation(), diag::note_previous_declaration);
2383 if (!property->
isReadOnly() && !SetterMethod) {
2385 auto *ExistingSetter = CatDecl->getClassInterface()->lookupMethod(
2386 property->
getSetterName(), !IsClassProperty,
true,
false, CatDecl);
2387 if (ExistingSetter) {
2390 <<
property->isDirectProperty() << 1
2391 << ExistingSetter->isDirectMethod()
2392 << ExistingSetter->getDeclName();
2393 Diag(ExistingSetter->getLocation(), diag::note_previous_declaration);
2399 if (!property->
isReadOnly() && SetterMethod) {
2400 if (Context.getCanonicalType(SetterMethod->
getReturnType()) !=
2404 !Context.hasSameUnqualifiedType(
2405 (*SetterMethod->
param_begin())->getType().getNonReferenceType(),
2408 diag::warn_accessor_property_type_mismatch)
2409 <<
property->getDeclName()
2421 if (!GetterMethod) {
2429 QualType resultTy =
property->getType().getAtomicUnqualifiedType();
2435 if (
auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
2438 modifiedTy, modifiedTy);
2443 Context, Loc, Loc, property->
getGetterName(), resultTy,
nullptr, CD,
2444 !IsClassProperty,
false,
2455 GetterMethod->
addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2457 if (property->
hasAttr<NSReturnsNotRetainedAttr>())
2458 GetterMethod->
addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context,
2461 if (property->
hasAttr<ObjCReturnsInnerPointerAttr>())
2463 ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc));
2465 if (
const SectionAttr *SA = property->
getAttr<SectionAttr>())
2466 GetterMethod->
addAttr(SectionAttr::CreateImplicit(
2467 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2469 SemaRef.ProcessAPINotes(GetterMethod);
2480 property->setGetterMethodDecl(GetterMethod);
2485 if (!SetterMethod) {
2493 Context, Loc, Loc, property->
getSetterName(), Context.VoidTy,
nullptr,
2494 CD, !IsClassProperty,
2506 property->getType().getUnqualifiedType().getAtomicUnqualifiedType();
2513 if (
auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
2516 modifiedTy, modifiedTy);
2534 SetterMethod->
addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2537 if (
const SectionAttr *SA = property->
getAttr<SectionAttr>())
2538 SetterMethod->
addAttr(SectionAttr::CreateImplicit(
2539 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2541 SemaRef.ProcessAPINotes(SetterMethod);
2554 property->setSetterMethodDecl(SetterMethod);
2568 if (!IsClassProperty) {
2581 if (!CurrentClass) {
2583 CurrentClass = Cat->getClassInterface();
2584 else if (
ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(CD))
2585 CurrentClass = Impl->getClassInterface();
2594 unsigned &Attributes,
2595 bool propertyInPrimaryClass) {
2602 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2603 <<
"readonly" <<
"readwrite";
2614 !PropertyDecl->
hasAttr<ObjCNSObjectAttr>()) {
2615 Diag(Loc, diag::err_objc_property_requires_object)
2620 :
"retain (or strong)");
2633 Diag(Loc, diag::warn_objc_property_assign_on_object);
2639 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2640 <<
"assign" <<
"copy";
2644 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2645 <<
"assign" <<
"retain";
2649 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2650 <<
"assign" <<
"strong";
2655 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2656 <<
"assign" <<
"weak";
2659 if (PropertyDecl->
hasAttr<IBOutletCollectionAttr>())
2660 Diag(Loc, diag::warn_iboutletcollection_property_assign);
2663 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2664 <<
"unsafe_unretained" <<
"copy";
2668 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2669 <<
"unsafe_unretained" <<
"retain";
2673 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2674 <<
"unsafe_unretained" <<
"strong";
2679 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2680 <<
"unsafe_unretained" <<
"weak";
2685 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2686 <<
"copy" <<
"retain";
2690 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2691 <<
"copy" <<
"strong";
2695 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2696 <<
"copy" <<
"weak";
2701 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"retain"
2706 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"strong"
2715 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2716 <<
"nonnull" <<
"weak";
2722 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"atomic"
2743 else if (propertyInPrimaryClass) {
2748 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
2752 Diag(Loc, diag::warn_objc_property_default_assign_on_object);
2764 Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
2769 Diag(Loc, diag::warn_objc_property_retain_of_block);
2773 Diag(Loc, diag::warn_objc_readonly_property_has_setter);
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.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
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 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 ...
static CanQualType getCanonicalType(QualType T)
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.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
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.
@ 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.