23#include "llvm/ADT/DenseSet.h"
24#include "llvm/ADT/SmallString.h"
55 type->isObjCRetainableType()) {
70 =
property->getType().getObjCLifetime();
76 if (!expectedLifetime) {
90 property->setPropertyAttributes(
attr);
94 if (propertyLifetime == expectedLifetime)
return;
96 property->setInvalidDecl();
98 diag::err_arc_inconsistent_property_ownership)
99 <<
property->getDeclName()
109 llvm::SmallPtrSetImpl<ObjCProtocolDecl *> &Known) {
111 if (!Known.insert(Proto).second)
146 llvm_unreachable(
"bad qualifier");
196 if (CDecl->IsClassExtension()) {
201 isReadWrite, Attributes,
203 T, TSI, MethodImplKind);
221 (isa<ObjCInterfaceDecl>(ClassDecl) ||
222 isa<ObjCProtocolDecl>(ClassDecl)));
231 bool FoundInSuper =
false;
240 CurrentInterfaceDecl = Super;
245 for (
auto *
P : CurrentInterfaceDecl->
protocols()) {
250 for (
auto *
P : IFace->all_referenced_protocols()) {
258 if (!Cat->IsClassExtension())
259 for (
auto *
P : Cat->protocols())
273 unsigned attributesAsWritten = 0;
312 std::pair<FileID, unsigned> locInfo =
SM.getDecomposedLoc(LParenLoc);
314 bool invalidTemp =
false;
315 StringRef file =
SM.getBufferData(locInfo.first, &invalidTemp);
318 const char *tokenBegin = file.data() + locInfo.second;
321 Lexer lexer(
SM.getLocForStartOfFile(locInfo.first),
323 file.begin(), tokenBegin, file.end());
331 }
while (Tok.
isNot(tok::r_paren));
339 bool PropagateAtomicity) {
345 if (OldIsAtomic == NewIsAtomic)
return;
351 auto Attrs =
Property->getPropertyAttributes();
360 if (
Property->getPropertyAttributesAsWritten() &
371 if (PropagateAtomicity &&
374 Attrs = Attrs & ~AtomicityMask;
386 if ((OldIsAtomic && isImplicitlyReadonlyAtomic(OldProperty)) ||
387 (NewIsAtomic && isImplicitlyReadonlyAtomic(NewProperty)))
393 if (
auto Category = dyn_cast<ObjCCategoryDecl>(OldDC))
394 OldContextName =
Category->getClassInterface()->getIdentifier();
396 OldContextName = cast<ObjCContainerDecl>(OldDC)->getIdentifier();
413 const bool isReadWrite,
414 unsigned &Attributes,
415 const unsigned AttributesAsWritten,
432 bool isClassProperty =
443 Diag(AtLoc, diag::err_duplicate_property);
462 ? diag::err_use_continuation_class_redeclaration_readwrite
463 : diag::err_use_continuation_class;
474 Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)
485 unsigned ExistingOwnership
488 if (ExistingOwnership && NewOwnership != ExistingOwnership) {
491 Diag(AtLoc, diag::warn_property_attr_mismatch);
496 Attributes = (Attributes & ~OwnershipMask) | ExistingOwnership;
505 Diag(AtLoc, diag::warn_property_implicitly_mismatched);
513 FD, GetterSel, GetterNameLoc,
514 SetterSel, SetterNameLoc,
516 Attributes, AttributesAsWritten,
517 T, TSI, MethodImplKind, DC);
527 bool IncompatibleObjC =
false;
537 if (!isa<ObjCObjectPointerType>(PrimaryClassPropertyT) ||
538 !isa<ObjCObjectPointerType>(ClassExtPropertyT) ||
540 ConvertedType, IncompatibleObjC))
541 || IncompatibleObjC) {
543 diag::err_type_mismatch_continuation_class) << PDecl->
getType();
567 const bool isReadWrite,
568 const unsigned Attributes,
569 const unsigned AttributesAsWritten,
600 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
618 LParenLoc, T, TInfo);
620 bool isClassProperty =
627 Diag(prevDecl->getLocation(), diag::note_property_declare);
637 Diag(AtLoc, diag::err_property_type) << T;
692 if (MethodImplKind == tok::objc_required)
694 else if (MethodImplKind == tok::objc_optional)
707 CDecl->
hasAttr<ObjCDirectMembersAttr>()) {
708 if (isa<ObjCProtocolDecl>(CDecl)) {
735 if (propertyLifetime == ivarLifetime)
return;
761 switch (propertyLifetime) {
764 <<
property->getDeclName()
771 <<
property->getDeclName()
778 << ((
property->getPropertyAttributesAsWritten() &
783 llvm_unreachable(
"properties cannot be autoreleasing");
792 S.
Diag(propertyImplLoc, diag::note_property_synthesize);
824 return (Attr1 & Kind) != (Attr2 & Kind);
829 return ((Attr1 & Kinds) != 0) != ((Attr2 & Kinds) != 0);
841 assert(isa<ObjCProtocolDecl>(
Property->getDeclContext()) &&
842 "Expected a property from a protocol");
847 PDecl->collectInheritedProtocolProperties(
Property, ProtocolSet,
852 for (
const auto *PI : SDecl->all_referenced_protocols()) {
854 PDecl->collectInheritedProtocolProperties(
Property, ProtocolSet,
857 SDecl = SDecl->getSuperClass();
861 if (Properties.empty())
865 size_t SelectedIndex = 0;
866 for (
const auto &Prop : llvm::enumerate(Properties)) {
868 if (
Property->isReadOnly() && !Prop.value()->isReadOnly()) {
870 SelectedIndex = Prop.index();
875 Properties[SelectedIndex] = OriginalProperty;
879 unsigned OriginalAttributes =
Property->getPropertyAttributesAsWritten();
881 IncompatibleType = 0,
882 HasNoExpectedAttribute,
883 HasUnexpectedAttribute,
889 struct MismatchingProperty {
892 StringRef AttributeName;
897 unsigned Attr = Prop->getPropertyAttributesAsWritten();
898 if (
Attr != OriginalAttributes) {
899 auto Diag = [&](
bool OriginalHasAttribute, StringRef AttributeName) {
900 MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
901 : HasUnexpectedAttribute;
902 Mismatches.push_back({Prop, Kind, AttributeName});
920 OriginalAttributes,
Attr,
925 "retain (or strong)");
934 if (
Property->getGetterName() != Prop->getGetterName()) {
935 Mismatches.push_back({Prop, DifferentGetter,
""});
938 if (!
Property->isReadOnly() && !Prop->isReadOnly() &&
939 Property->getSetterName() != Prop->getSetterName()) {
940 Mismatches.push_back({Prop, DifferentSetter,
""});
945 bool IncompatibleObjC =
false;
948 || IncompatibleObjC) {
949 Mismatches.push_back({Prop, IncompatibleType,
""});
955 if (Mismatches.empty())
960 bool HasIncompatibleAttributes =
false;
961 for (
const auto &
Note : Mismatches)
962 HasIncompatibleAttributes =
963 Note.Kind != IncompatibleType ?
true : HasIncompatibleAttributes;
967 Property != OriginalProperty || HasIncompatibleAttributes
968 ? diag::err_protocol_property_mismatch
969 : diag::warn_protocol_property_mismatch);
970 Diag << Mismatches[0].Kind;
971 switch (Mismatches[0].Kind) {
972 case IncompatibleType:
975 case HasNoExpectedAttribute:
976 case HasUnexpectedAttribute:
977 Diag << Mismatches[0].AttributeName;
979 case DifferentGetter:
982 case DifferentSetter:
987 for (
const auto &
Note : Mismatches) {
989 S.
Diag(
Note.Prop->getLocation(), diag::note_protocol_property_declare)
992 case IncompatibleType:
995 case HasNoExpectedAttribute:
996 case HasUnexpectedAttribute:
999 case DifferentGetter:
1000 Diag <<
Note.Prop->getGetterName();
1002 case DifferentSetter:
1003 Diag <<
Note.Prop->getSetterName();
1008 S.
Diag(AtLoc, diag::note_property_synthesize);
1030 auto OrigClass =
Category->getClassInterface();
1031 for (
auto *Found : OrigClass->lookup(Prop->
getDeclName())) {
1033 return OrigProp->getPropertyAttributesAsWritten() &
OwnershipMask;
1037 for (
const auto *Proto : OrigClass->all_referenced_protocols()) {
1040 return OrigProp->getPropertyAttributesAsWritten() &
OwnershipMask;
1055 Decl->getSelector(),
Decl->getReturnType(),
1056 Decl->getReturnTypeSourceInfo(), Impl,
Decl->isInstanceMethod(),
1057 Decl->isVariadic(),
Decl->isPropertyAccessor(),
1059 Decl->getImplementationControl(),
Decl->hasRelatedResultType());
1066 Decl->getSelectorLocs(SelLocs);
1088 if (!ClassImpDecl) {
1089 Diag(AtLoc, diag::err_missing_property_context);
1093 PropertyIvarLoc = PropertyLoc;
1103 if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
1108 "ActOnPropertyImplDecl - @implementation without @interface");
1113 Diag(PropertyLoc, diag::err_bad_property_decl) << IDecl->
getDeclName();
1116 if (property->isClassProperty() && Synthesize) {
1117 Diag(PropertyLoc, diag::err_synthesize_on_class_property) << PropertyId;
1120 unsigned PIkind =
property->getPropertyAttributesAsWritten();
1124 Diag(AtLoc, diag::warn_implicit_atomic_property);
1127 Diag(property->getLocation(), diag::note_property_declare);
1131 dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
1132 if (!CD->IsClassExtension()) {
1133 Diag(PropertyLoc, diag::err_category_property) << CD->getDeclName();
1134 Diag(property->getLocation(), diag::note_property_declare);
1139 property->hasAttr<IBOutletAttr>() && !AtLoc.
isValid()) {
1140 bool ReadWriteProperty =
false;
1146 PIkind = ExtProp->getPropertyAttributesAsWritten();
1148 ReadWriteProperty =
true;
1154 if (!ReadWriteProperty) {
1155 Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property)
1159 property->getLParenLoc(), readonlyLoc)) {
1162 SourceRange ReadonlySourceRange(readonlyLoc, endLoc);
1163 Diag(property->getLocation(),
1164 diag::note_auto_readonly_iboutlet_fixup_suggest) <<
1169 if (Synthesize && isa<ObjCProtocolDecl>(property->getDeclContext()))
1173 }
else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
1175 Diag(AtLoc, diag::err_synthesize_category_decl);
1180 Diag(AtLoc, diag::err_missing_property_interface);
1191 property =
Category->FindPropertyDeclaration(PropertyId, QueryKind);
1193 Diag(PropertyLoc, diag::err_bad_category_property_decl)
1198 Diag(AtLoc, diag::err_bad_property_context);
1202 bool CompleteTypeErr =
false;
1208 PropertyIvar = PropertyId;
1212 QualType PropType =
property->getType();
1216 diag::err_incomplete_synthesized_property,
1217 property->getDeclName())) {
1218 Diag(property->getLocation(), diag::note_property_declare);
1219 CompleteTypeErr =
true;
1223 (property->getPropertyAttributesAsWritten() &
1231 bool isARCWeak =
false;
1237 Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);
1238 Diag(property->getLocation(), diag::note_property_declare);
1250 Diag(PropertyDiagLoc,
1252 ? diag::err_synthesizing_arc_weak_property_disabled
1253 : diag::err_synthesizing_arc_weak_property_no_runtime);
1254 Diag(property->getLocation(), diag::note_property_declare);
1256 CompleteTypeErr =
true;
1263 Diag(property->getLocation(),
1264 diag::err_arc_weak_unavailable_property)
1265 << PropertyIvarType;
1284 Diag(PropertyDiagLoc,
1285 diag::warn_autosynthesis_property_ivar_match)
1286 << PropertyId << (Ivar ==
nullptr) << PropertyIvar
1288 Diag(property->getLocation(), diag::note_property_declare);
1296 if ((
getLangOpts().ObjCAutoRefCount || isARCWeak) &&
1304 Diag(PropertyDiagLoc,
1305 diag::err_arc_objc_property_default_assign_on_object);
1306 Diag(property->getLocation(), diag::note_property_declare);
1310 assert(lifetime &&
"no lifetime for property?");
1319 PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,
1320 PropertyIvarType,
nullptr,
1322 (
Expr *)
nullptr,
true);
1325 diag::err_abstract_type_in_decl,
1327 Diag(property->getLocation(), diag::note_property_declare);
1329 CompleteTypeErr =
true;
1331 if (!CompleteTypeErr) {
1334 Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)
1335 << PropertyIvarType;
1336 CompleteTypeErr =
true;
1339 if (CompleteTypeErr)
1345 Diag(PropertyDiagLoc, diag::err_missing_property_ivar_decl)
1351 Diag(PropertyDiagLoc, diag::err_ivar_in_superclass_use)
1358 property->setPropertyIvarDecl(Ivar);
1364 if (isa<ObjCObjectPointerType>(PropertyIvarType)
1365 && isa<ObjCObjectPointerType>(IvarType))
1376 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1377 <<
property->getDeclName() << PropType
1389 if (lhsType != rhsType &&
1391 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1392 <<
property->getDeclName() << PropType
1401 Diag(PropertyDiagLoc, diag::err_weak_property)
1402 <<
property->getDeclName() << Ivar->
getDeclName();
1407 if ((property->getType()->isObjCObjectPointerType() ||
1410 Diag(PropertyDiagLoc, diag::err_strong_property)
1411 <<
property->getDeclName() << Ivar->
getDeclName();
1415 if (
getLangOpts().ObjCAutoRefCount || isARCWeak ||
1418 }
else if (PropertyIvar)
1420 Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);
1422 assert (property &&
"ActOnPropertyImplDecl - property declaration missing");
1429 Ivar, PropertyIvarLoc);
1431 if (CompleteTypeErr || !compat)
1434 if (
ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
1435 getterMethod->createImplicitParams(
Context, IDecl);
1441 getterMethod->getSelector(), getterMethod->isInstanceMethod());
1460 Context, SelfDecl->
getType(), CK_LValueToRValue, SelfExpr,
nullptr,
1467 LoadSelfExpr,
true,
true);
1470 getterMethod->getReturnType()),
1471 PropertyDiagLoc, IvarRefExpr);
1479 if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
1480 !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
1481 Diag(getterMethod->getLocation(),
1482 diag::warn_property_getter_owning_mismatch);
1483 Diag(property->getLocation(), diag::note_property_declare);
1486 switch (getterMethod->getMethodFamily()) {
1491 Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def)
1492 << 1 << getterMethod->getSelector();
1499 if (
ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
1500 setterMethod->createImplicitParams(
Context, IDecl);
1505 setterMethod->getSelector(), setterMethod->isInstanceMethod());
1508 AtLoc, PropertyLoc);
1522 Context, SelfDecl->
getType(), CK_LValueToRValue, SelfExpr,
nullptr,
1529 LoadSelfExpr,
true,
true);
1537 BO_Assign, lhs, rhs);
1538 if (property->getPropertyAttributes() &
1542 dyn_cast_or_null<CXXOperatorCallExpr>(
callExpr))
1543 if (
const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
1544 if (!FuncDecl->isTrivial())
1545 if (property->getType()->isReferenceType()) {
1546 Diag(PropertyDiagLoc,
1547 diag::err_atomic_property_nontrivial_assign_op)
1548 <<
property->getType();
1549 Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
1561 Diag(PropertyLoc, diag::err_duplicate_ivar_use)
1562 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1564 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1569 Diag(PropertyLoc, diag::err_property_implemented) << PropertyId;
1570 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1585 if (PropertyIvar && PropertyIvar != PropertyId)
1600 Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)
1601 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1603 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1608 Diag(PropertyDiagLoc, diag::err_property_implemented) << PropertyId;
1609 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1618 Diag(PropertyLoc, diag::err_objc_direct_dynamic_property);
1620 diag::note_previous_declaration);
1638 bool OverridingProtocolProperty) {
1645 if (!OverridingProtocolProperty &&
1651 Diag(
Property->getLocation(), diag::warn_readonly_property)
1652 <<
Property->getDeclName() << inheritedName;
1655 Diag(
Property->getLocation(), diag::warn_property_attribute)
1656 <<
Property->getDeclName() <<
"copy" << inheritedName;
1662 bool CStrong = (CAttrRetain != 0);
1663 bool SStrong = (SAttrRetain != 0);
1664 if (CStrong != SStrong)
1665 Diag(
Property->getLocation(), diag::warn_property_attribute)
1666 <<
Property->getDeclName() <<
"retain (or strong)" << inheritedName;
1679 Diag(
Property->getLocation(), diag::warn_property_attribute)
1680 <<
Property->getDeclName() <<
"setter" << inheritedName;
1684 Diag(
Property->getLocation(), diag::warn_property_attribute)
1685 <<
Property->getDeclName() <<
"getter" << inheritedName;
1697 bool IncompatibleObjC =
false;
1700 ConvertedType, IncompatibleObjC) ||
1702 Diag(
Property->getLocation(), diag::warn_property_types_are_incompatible)
1716 property->getType().getNonReferenceType().getAtomicUnqualifiedType();
1721 if ((propertyObjCPtr =
1727 Diag(Loc, diag::err_property_accessor_type)
1728 <<
property->getDeclName() << PropertyRValueType
1742 Diag(Loc, diag::warn_accessor_property_type_mismatch)
1743 <<
property->getDeclName()
1758 bool CollectClassPropsOnly =
false,
1759 bool IncludeProtocols =
true) {
1761 for (
auto *Prop : IDecl->properties()) {
1762 if (CollectClassPropsOnly && !Prop->isClassProperty())
1764 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1769 for (
auto *Ext : IDecl->visible_extensions())
1771 CollectClassPropsOnly, IncludeProtocols);
1773 if (IncludeProtocols) {
1775 for (
auto *PI : IDecl->all_referenced_protocols())
1777 CollectClassPropsOnly);
1781 for (
auto *Prop : CATDecl->properties()) {
1782 if (CollectClassPropsOnly && !Prop->isClassProperty())
1784 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1787 if (IncludeProtocols) {
1789 for (
auto *PI : CATDecl->protocols())
1791 CollectClassPropsOnly);
1795 for (
auto *Prop : PDecl->properties()) {
1796 if (CollectClassPropsOnly && !Prop->isClassProperty())
1799 SuperPropMap[std::make_pair(Prop->getIdentifier(),
1800 Prop->isClassProperty())];
1803 if (!PropertyFromSuper ||
1804 PropertyFromSuper->
getIdentifier() != Prop->getIdentifier()) {
1806 PropMap[std::make_pair(Prop->getIdentifier(),
1807 Prop->isClassProperty())];
1813 for (
auto *PI : PDecl->protocols())
1815 CollectClassPropsOnly);
1826 SDecl->collectPropertiesToImplement(PropMap);
1827 SDecl = SDecl->getSuperClass();
1850 (
Property->getPropertyIvarDecl() == IV))
1856 for (
const auto *
Property : Ext->instance_properties())
1859 (
Property->getPropertyIvarDecl() == IV))
1866 bool SuperClassImplementsGetter =
false;
1867 bool SuperClassImplementsSetter =
false;
1869 SuperClassImplementsSetter =
true;
1874 SuperClassImplementsGetter =
true;
1877 SuperClassImplementsSetter =
true;
1878 if (SuperClassImplementsGetter && SuperClassImplementsSetter)
1892 if (PropMap.empty())
1897 for (
const auto &PropEntry : PropMap) {
1909 if (ImpMethod && !ImpMethod->
getBody()) {
1913 if (ImpMethod && !ImpMethod->
getBody())
1918 Diag(Prop->
getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
1920 if (PID->getLocation().isValid())
1921 Diag(PID->getLocation(), diag::note_property_synthesize);
1935 diag::warn_auto_synthesizing_protocol_property)
1939 (Twine(
"@synthesize ") + Prop->
getName() +
";\n\n").str();
1940 Diag(AtEnd, diag::note_add_synthesize_directive)
1946 if (PropInSuperClass) {
1957 Diag(Prop->
getLocation(), diag::warn_autosynthesis_property_in_superclass)
1989 if (!IDecl->isObjCRequiresPropertyDefs())
2008 if (I ==
SMap.end() &&
2009 (PrimaryClass ==
nullptr ||
2013 isa<ObjCCategoryDecl>(CDecl)
2015 ? diag::warn_impl_required_in_category_for_class_property
2016 : diag::warn_setter_getter_impl_required_in_category)
2018 ? diag::warn_impl_required_for_class_property
2019 : diag::warn_setter_getter_impl_required);
2022 if (S.
LangOpts.ObjCDefaultSynthProperties &&
2026 S.
Diag(RID->getLocation(), diag::note_suppressed_class_declare);
2032 bool SynthesizeProperties) {
2046 if ((IDecl =
C->getClassInterface())) {
2055 SynthesizeProperties);
2061 std::unique_ptr<ObjCContainerDecl::PropertyMap> LazyMap;
2064 if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
2082 for (
auto *PropDecl : PDecl->properties()) {
2083 if ((*LazyMap)[std::make_pair(PropDecl->getIdentifier(),
2084 PropDecl->isClassProperty())])
2086 PropMap[std::make_pair(PropDecl->getIdentifier(),
2087 PropDecl->isClassProperty())] = PropDecl;
2092 if (PropMap.empty())
2097 PropImplMap.insert(I->getPropertyDecl());
2101 for (
const auto *I : IMPDecl->
methods())
2106 if (
C && !
C->IsClassExtension())
2107 if ((PrimaryClass =
C->getClassInterface()))
2113 for (
const auto *I : IMP->methods())
2117 for (ObjCContainerDecl::PropertyMap::iterator
2118 P = PropMap.begin(), E = PropMap.end();
P != E; ++
P) {
2123 PropImplMap.count(Prop) ||
2129 PrimaryClass, Prop->
getGetterName(), IMPDecl, CDecl,
C, Prop, InsMap);
2133 IMPDecl, CDecl,
C, Prop, InsMap);
2139 const auto *
property = propertyImpl->getPropertyDecl();
2142 if (propertyImpl->getPropertyImplementation() ==
2144 (property->getPropertyAttributes() &
2146 property->getGetterMethodDecl() && property->getSetterMethodDecl()) {
2147 auto *getterImpl = propertyImpl->getGetterMethodDecl();
2148 auto *setterImpl = propertyImpl->getSetterMethodDecl();
2149 if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) &&
2150 (!setterImpl || setterImpl->isSynthesizedAccessorStub())) {
2155 Diag(loc, diag::warn_null_resettable_setter)
2156 << setterImpl->getSelector() <<
property->getDeclName();
2170 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2172 for (
auto *Prop : Ext->properties())
2173 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2175 for (ObjCContainerDecl::PropertyMap::iterator I = PM.begin(), E = PM.end();
2181 unsigned Attributes =
Property->getPropertyAttributes();
2182 unsigned AttributesAsWritten =
Property->getPropertyAttributesAsWritten();
2186 GetterMethod =
Property->isClassProperty() ?
2189 SetterMethod =
Property->isClassProperty() ?
2193 GetterMethod =
nullptr;
2195 SetterMethod =
nullptr;
2198 diag::warn_default_atomic_custom_getter_setter)
2200 Diag(
Property->getLocation(), diag::note_property_declare);
2204 diag::warn_default_atomic_custom_getter_setter)
2206 Diag(
Property->getLocation(), diag::note_property_declare);
2218 GetterMethod = PIDecl->getGetterMethodDecl();
2219 SetterMethod = PIDecl->getSetterMethodDecl();
2221 GetterMethod =
nullptr;
2223 SetterMethod =
nullptr;
2224 if ((
bool)GetterMethod ^ (
bool)SetterMethod) {
2227 : SetterMethod->getLocation());
2228 Diag(MethodLoc, diag::warn_atomic_property_rule)
2229 <<
Property->getIdentifier() << (GetterMethod !=
nullptr)
2230 << (SetterMethod !=
nullptr);
2232 if (
Property->getLParenLoc().isValid() &&
2237 StringRef NonatomicStr = AttributesAsWritten?
"nonatomic, "
2240 diag::note_atomic_property_fixup_suggest)
2242 }
else if (
Property->getLParenLoc().isInvalid()) {
2245 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
2247 diag::note_atomic_property_fixup_suggest)
2250 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);
2251 Diag(
Property->getLocation(), diag::note_property_declare);
2263 if (PD && !PD->
hasAttr<NSReturnsNotRetainedAttr>() &&
2283 for (
auto *getterRedecl : method->
redecls()) {
2284 if (getterRedecl->isImplicit())
2288 noteLoc = getterRedecl->getLocation();
2289 fixItLoc = getterRedecl->getEndLoc();
2294 tok::kw___attribute, tok::l_paren, tok::l_paren,
2297 tok::r_paren, tok::r_paren
2299 StringRef spelling =
"__attribute__((objc_method_family(none)))";
2301 if (!macroName.empty())
2302 spelling = macroName;
2304 auto noteDiag =
Diag(noteLoc, diag::note_cocoa_naming_declare_family)
2308 fixItText += spelling;
2326 if (I->getMethodFamily() ==
OMF_init)
2327 InitSelSet.insert(I->getSelector());
2332 I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
2337 bool Ignore =
false;
2343 if (
auto *IMD = Ext->getInstanceMethod(MD->
getSelector())) {
2344 Ignore = IMD->isUnavailable();
2350 diag::warn_objc_implementation_missing_designated_init_override)
2363 for (
const auto *A :
Property->attrs()) {
2364 if (isa<DeprecatedAttr>(A) ||
2365 isa<UnavailableAttr>(A) ||
2366 isa<AvailabilityAttr>(A))
2381 bool IsClassProperty =
property->isClassProperty();
2382 GetterMethod = IsClassProperty ?
2390 if (CatDecl->IsClassExtension())
2393 CatDecl->getClassInterface()->
2396 SetterMethod = IsClassProperty ?
2401 if (CatDecl->IsClassExtension())
2404 CatDecl->getClassInterface()->
2411 if (!GetterMethod) {
2413 auto *ExistingGetter = CatDecl->getClassInterface()->lookupMethod(
2414 property->
getGetterName(), !IsClassProperty,
true,
false, CatDecl);
2415 if (ExistingGetter) {
2418 <<
property->isDirectProperty() << 1
2419 << ExistingGetter->isDirectMethod()
2420 << ExistingGetter->getDeclName();
2421 Diag(ExistingGetter->getLocation(), diag::note_previous_declaration);
2427 if (!property->
isReadOnly() && !SetterMethod) {
2429 auto *ExistingSetter = CatDecl->getClassInterface()->lookupMethod(
2430 property->
getSetterName(), !IsClassProperty,
true,
false, CatDecl);
2431 if (ExistingSetter) {
2434 <<
property->isDirectProperty() << 1
2435 << ExistingSetter->isDirectMethod()
2436 << ExistingSetter->getDeclName();
2437 Diag(ExistingSetter->getLocation(), diag::note_previous_declaration);
2443 if (!property->
isReadOnly() && SetterMethod) {
2449 (*SetterMethod->
param_begin())->getType().getNonReferenceType(),
2452 diag::warn_accessor_property_type_mismatch)
2453 <<
property->getDeclName()
2465 if (!GetterMethod) {
2473 QualType resultTy =
property->getType().getAtomicUnqualifiedType();
2482 modifiedTy, modifiedTy);
2488 !IsClassProperty,
false,
2499 GetterMethod->
addAttr(ObjCDirectAttr::CreateImplicit(
Context, Loc));
2501 if (property->
hasAttr<NSReturnsNotRetainedAttr>())
2502 GetterMethod->
addAttr(NSReturnsNotRetainedAttr::CreateImplicit(
Context,
2505 if (property->
hasAttr<ObjCReturnsInnerPointerAttr>())
2507 ObjCReturnsInnerPointerAttr::CreateImplicit(
Context, Loc));
2509 if (
const SectionAttr *SA = property->
getAttr<SectionAttr>())
2510 GetterMethod->
addAttr(SectionAttr::CreateImplicit(
2512 SectionAttr::GNU_section));
2523 property->setGetterMethodDecl(GetterMethod);
2528 if (!SetterMethod) {
2538 nullptr, CD, !IsClassProperty,
2551 property->getType().getUnqualifiedType().getAtomicUnqualifiedType();
2561 modifiedTy, modifiedTy);
2579 SetterMethod->
addAttr(ObjCDirectAttr::CreateImplicit(
Context, Loc));
2582 if (
const SectionAttr *SA = property->
getAttr<SectionAttr>())
2583 SetterMethod->
addAttr(SectionAttr::CreateImplicit(
2585 SectionAttr::GNU_section));
2597 property->setSetterMethodDecl(SetterMethod);
2611 if (!IsClassProperty) {
2624 if (!CurrentClass) {
2626 CurrentClass = Cat->getClassInterface();
2627 else if (
ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(CD))
2628 CurrentClass = Impl->getClassInterface();
2638 unsigned &Attributes,
2639 bool propertyInPrimaryClass) {
2646 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2647 <<
"readonly" <<
"readwrite";
2658 !PropertyDecl->
hasAttr<ObjCNSObjectAttr>()) {
2659 Diag(Loc, diag::err_objc_property_requires_object)
2664 :
"retain (or strong)");
2677 Diag(Loc, diag::warn_objc_property_assign_on_object);
2683 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2684 <<
"assign" <<
"copy";
2685 Attributes &= ~ObjCPropertyAttribute::kind_copy;
2688 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2689 <<
"assign" <<
"retain";
2690 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2693 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2694 <<
"assign" <<
"strong";
2695 Attributes &= ~ObjCPropertyAttribute::kind_strong;
2699 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2700 <<
"assign" <<
"weak";
2701 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2703 if (PropertyDecl->
hasAttr<IBOutletCollectionAttr>())
2704 Diag(Loc, diag::warn_iboutletcollection_property_assign);
2707 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2708 <<
"unsafe_unretained" <<
"copy";
2709 Attributes &= ~ObjCPropertyAttribute::kind_copy;
2712 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2713 <<
"unsafe_unretained" <<
"retain";
2714 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2717 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2718 <<
"unsafe_unretained" <<
"strong";
2719 Attributes &= ~ObjCPropertyAttribute::kind_strong;
2723 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2724 <<
"unsafe_unretained" <<
"weak";
2725 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2729 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2730 <<
"copy" <<
"retain";
2731 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2734 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2735 <<
"copy" <<
"strong";
2736 Attributes &= ~ObjCPropertyAttribute::kind_strong;
2739 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2740 <<
"copy" <<
"weak";
2741 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2745 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"retain"
2747 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2750 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"strong"
2752 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2759 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2760 <<
"nonnull" <<
"weak";
2766 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"atomic"
2768 Attributes &= ~ObjCPropertyAttribute::kind_atomic;
2787 else if (propertyInPrimaryClass) {
2792 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
2796 Diag(Loc, diag::warn_objc_property_default_assign_on_object);
2810 Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
2815 Diag(Loc, diag::warn_objc_property_retain_of_block);
2819 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)
Defines the SourceManager interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
bool propertyTypesAreCompatible(QualType, QualType)
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...
const LangOptions & getLangOpts() const
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getObjCGCQualType(QualType T, Qualifiers::GC gcAttr) const
Return the uniqued reference to the type for an Objective-C gc-qualified type.
Attr - This represents one attribute.
static std::optional< NullabilityKind > stripOuterNullability(QualType &T)
Strip off the top-level nullability annotation on the given type, if it's there.
A call to an overloaded operator written using operator syntax.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
The results of name lookup within a DeclContext.
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.
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
IdentifierInfo * getIdentifier() const
void setObjCWeakProperty(bool Val=true)
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.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
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
llvm::MapVector< std::pair< IdentifierInfo *, unsigned >, ObjCPropertyDecl * > PropertyMap
instmeth_range instance_methods() const
llvm::SmallDenseSet< const ObjCProtocolDecl *, 8 > ProtocolPropertySet
ObjCPropertyDecl * getProperty(const IdentifierInfo *Id, bool IsInstance) const
instprop_range instance_properties() const
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
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(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
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...
ObjCCategoryDecl * FindCategoryDeclaration(IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
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, 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)
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ImplementationControl impControl=None, bool HasRelatedResultType=false)
bool isPropertyAccessor() const
param_const_iterator param_begin() const
void setCmdDecl(ImplicitParamDecl *CD)
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
bool isSynthesizedAccessorStub() const
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs=std::nullopt)
Sets the method's parameters and selector source locations.
void setPropertyAccessor(bool isAccessor)
Selector getSelector() const
bool isInstanceMethod() 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
static ObjCPropertyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, SourceLocation AtLocation, SourceLocation LParenLocation, QualType T, TypeSourceInfo *TSI, PropertyControl propControl=None)
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const
Get the default name of the synthesized ivar.
ObjCPropertyAttribute::Kind getPropertyAttributes() const
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, 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.
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...
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
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() 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.
RAII object to handle the state changes required to synthesize a function body.
Sema - This implements semantic analysis and AST building for C.
bool CheckARCMethodDecl(ObjCMethodDecl *method)
Check a method declaration for compatibility with the Objective-C ARC conventions.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Preprocessor & getPreprocessor() const
Decl * ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
ObjCPropertyDecl * HandlePropertyInClassExtension(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, unsigned &Attributes, const unsigned AttributesAsWritten, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind)
Called by ActOnProperty to handle @property declarations in class extensions.
bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC)
isObjCPointerConversion - Determines whether this is an Objective-C pointer conversion.
void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ObjCInterfaceDecl *CurrentClass, ResultTypeCompatibilityKind RTC)
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() const
void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D)
void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, unsigned &Attributes, bool propertyInPrimaryClass)
Ensure attributes are consistent with type.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
void AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl)
AtomicPropertySetterGetterRules - This routine enforces the rule (via warning) when atomic property h...
const LangOptions & LangOpts
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddInstanceMethodToGlobalPool - All instance methods in a translation unit are added to a global pool...
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...
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
void ActOnDocumentableDecl(Decl *D)
Should be called on all declarations that might have attached documentation comments.
@ Compatible
Compatible - the types are compatible according to the standard.
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=NotForRedeclaration)
Find the protocol with the given name, if any.
void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base=nullptr)
Perform reference-marking and odr-use handling for a DeclRefExpr.
void DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD)
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 AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
void ProcessPropertyDecl(ObjCPropertyDecl *property)
Process the specified property declaration and create decls for the setters and getters as needed.
void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, bool SynthesizeProperties)
DiagnoseUnimplementedProperties - This routine warns on those properties which must be implemented by...
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
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...
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD)
ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in it, apply them to D.
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
@ AbstractSynthesizedIvarType
TypeSourceInfo * GetTypeForDeclarator(Declarator &D, Scope *S)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, QualType LHSType, QualType RHSType)
CheckAssignmentConstraints - Perform type checking for assignment, argument passing,...
void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)
Diagnose any null-resettable synthesized setters.
void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl, SourceLocation AtEnd)
DefaultSynthesizeProperties - This routine default synthesizes all properties which must be synthesiz...
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 getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
bool isNot(tok::TokenKind K) const
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
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
bool isArithmeticType() const
bool isObjCObjectType() const
bool isFunctionType() const
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)
@ kind_nullability
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
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 '@'.
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ NonNull
Values of this type can never be null.
ObjCMethodFamily
A family of Objective-C methods.
@ C
Languages that the frontend can parse and compile.
@ 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.
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.