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))
1375 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1376 <<
property->getDeclName() << PropType
1388 if (lhsType != rhsType &&
1390 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1391 <<
property->getDeclName() << PropType
1400 Diag(PropertyDiagLoc, diag::err_weak_property)
1401 <<
property->getDeclName() << Ivar->
getDeclName();
1406 if ((property->getType()->isObjCObjectPointerType() ||
1409 Diag(PropertyDiagLoc, diag::err_strong_property)
1410 <<
property->getDeclName() << Ivar->
getDeclName();
1414 if (
getLangOpts().ObjCAutoRefCount || isARCWeak ||
1417 }
else if (PropertyIvar)
1419 Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);
1421 assert (property &&
"ActOnPropertyImplDecl - property declaration missing");
1428 Ivar, PropertyIvarLoc);
1430 if (CompleteTypeErr || !compat)
1433 if (
ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
1434 getterMethod->createImplicitParams(
Context, IDecl);
1440 getterMethod->getSelector(), getterMethod->isInstanceMethod());
1459 Context, SelfDecl->
getType(), CK_LValueToRValue, SelfExpr,
nullptr,
1466 LoadSelfExpr,
true,
true);
1469 getterMethod->getReturnType()),
1470 PropertyDiagLoc, IvarRefExpr);
1478 if (property->hasAttr<NSReturnsNotRetainedAttr>() &&
1479 !getterMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
1480 Diag(getterMethod->getLocation(),
1481 diag::warn_property_getter_owning_mismatch);
1482 Diag(property->getLocation(), diag::note_property_declare);
1485 switch (getterMethod->getMethodFamily()) {
1490 Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def)
1491 << 1 << getterMethod->getSelector();
1498 if (
ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
1499 setterMethod->createImplicitParams(
Context, IDecl);
1504 setterMethod->getSelector(), setterMethod->isInstanceMethod());
1507 AtLoc, PropertyLoc);
1521 Context, SelfDecl->
getType(), CK_LValueToRValue, SelfExpr,
nullptr,
1528 LoadSelfExpr,
true,
true);
1536 BO_Assign, lhs, rhs);
1537 if (property->getPropertyAttributes() &
1541 dyn_cast_or_null<CXXOperatorCallExpr>(
callExpr))
1542 if (
const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
1543 if (!FuncDecl->isTrivial())
1544 if (property->getType()->isReferenceType()) {
1545 Diag(PropertyDiagLoc,
1546 diag::err_atomic_property_nontrivial_assign_op)
1547 <<
property->getType();
1548 Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
1560 Diag(PropertyLoc, diag::err_duplicate_ivar_use)
1561 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1563 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1568 Diag(PropertyLoc, diag::err_property_implemented) << PropertyId;
1569 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1584 if (PropertyIvar && PropertyIvar != PropertyId)
1599 Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)
1600 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1602 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1607 Diag(PropertyDiagLoc, diag::err_property_implemented) << PropertyId;
1608 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1617 Diag(PropertyLoc, diag::err_objc_direct_dynamic_property);
1619 diag::note_previous_declaration);
1637 bool OverridingProtocolProperty) {
1644 if (!OverridingProtocolProperty &&
1650 Diag(
Property->getLocation(), diag::warn_readonly_property)
1651 <<
Property->getDeclName() << inheritedName;
1654 Diag(
Property->getLocation(), diag::warn_property_attribute)
1655 <<
Property->getDeclName() <<
"copy" << inheritedName;
1661 bool CStrong = (CAttrRetain != 0);
1662 bool SStrong = (SAttrRetain != 0);
1663 if (CStrong != SStrong)
1664 Diag(
Property->getLocation(), diag::warn_property_attribute)
1665 <<
Property->getDeclName() <<
"retain (or strong)" << inheritedName;
1678 Diag(
Property->getLocation(), diag::warn_property_attribute)
1679 <<
Property->getDeclName() <<
"setter" << inheritedName;
1683 Diag(
Property->getLocation(), diag::warn_property_attribute)
1684 <<
Property->getDeclName() <<
"getter" << inheritedName;
1696 bool IncompatibleObjC =
false;
1699 ConvertedType, IncompatibleObjC) ||
1701 Diag(
Property->getLocation(), diag::warn_property_types_are_incompatible)
1715 property->getType().getNonReferenceType().getAtomicUnqualifiedType();
1720 if ((propertyObjCPtr =
1726 Diag(Loc, diag::err_property_accessor_type)
1727 <<
property->getDeclName() << PropertyRValueType
1741 Diag(Loc, diag::warn_accessor_property_type_mismatch)
1742 <<
property->getDeclName()
1757 bool CollectClassPropsOnly =
false,
1758 bool IncludeProtocols =
true) {
1760 for (
auto *Prop : IDecl->properties()) {
1761 if (CollectClassPropsOnly && !Prop->isClassProperty())
1763 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1768 for (
auto *Ext : IDecl->visible_extensions())
1770 CollectClassPropsOnly, IncludeProtocols);
1772 if (IncludeProtocols) {
1774 for (
auto *PI : IDecl->all_referenced_protocols())
1776 CollectClassPropsOnly);
1780 for (
auto *Prop : CATDecl->properties()) {
1781 if (CollectClassPropsOnly && !Prop->isClassProperty())
1783 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1786 if (IncludeProtocols) {
1788 for (
auto *PI : CATDecl->protocols())
1790 CollectClassPropsOnly);
1794 for (
auto *Prop : PDecl->properties()) {
1795 if (CollectClassPropsOnly && !Prop->isClassProperty())
1798 SuperPropMap[std::make_pair(Prop->getIdentifier(),
1799 Prop->isClassProperty())];
1802 if (!PropertyFromSuper ||
1803 PropertyFromSuper->
getIdentifier() != Prop->getIdentifier()) {
1805 PropMap[std::make_pair(Prop->getIdentifier(),
1806 Prop->isClassProperty())];
1812 for (
auto *PI : PDecl->protocols())
1814 CollectClassPropsOnly);
1825 SDecl->collectPropertiesToImplement(PropMap);
1826 SDecl = SDecl->getSuperClass();
1849 (
Property->getPropertyIvarDecl() == IV))
1855 for (
const auto *
Property : Ext->instance_properties())
1858 (
Property->getPropertyIvarDecl() == IV))
1865 bool SuperClassImplementsGetter =
false;
1866 bool SuperClassImplementsSetter =
false;
1868 SuperClassImplementsSetter =
true;
1873 SuperClassImplementsGetter =
true;
1876 SuperClassImplementsSetter =
true;
1877 if (SuperClassImplementsGetter && SuperClassImplementsSetter)
1891 if (PropMap.empty())
1896 for (
const auto &PropEntry : PropMap) {
1908 if (ImpMethod && !ImpMethod->
getBody()) {
1912 if (ImpMethod && !ImpMethod->
getBody())
1917 Diag(Prop->
getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
1919 if (PID->getLocation().isValid())
1920 Diag(PID->getLocation(), diag::note_property_synthesize);
1934 diag::warn_auto_synthesizing_protocol_property)
1938 (Twine(
"@synthesize ") + Prop->
getName() +
";\n\n").str();
1939 Diag(AtEnd, diag::note_add_synthesize_directive)
1945 if (PropInSuperClass) {
1956 Diag(Prop->
getLocation(), diag::warn_autosynthesis_property_in_superclass)
1988 if (!IDecl->isObjCRequiresPropertyDefs())
2007 if (I ==
SMap.end() &&
2008 (PrimaryClass ==
nullptr ||
2012 isa<ObjCCategoryDecl>(CDecl)
2014 ? diag::warn_impl_required_in_category_for_class_property
2015 : diag::warn_setter_getter_impl_required_in_category)
2017 ? diag::warn_impl_required_for_class_property
2018 : diag::warn_setter_getter_impl_required);
2021 if (S.
LangOpts.ObjCDefaultSynthProperties &&
2025 S.
Diag(RID->getLocation(), diag::note_suppressed_class_declare);
2031 bool SynthesizeProperties) {
2045 if ((IDecl =
C->getClassInterface())) {
2054 SynthesizeProperties);
2060 std::unique_ptr<ObjCContainerDecl::PropertyMap> LazyMap;
2063 if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
2081 for (
auto *PropDecl : PDecl->properties()) {
2082 if ((*LazyMap)[std::make_pair(PropDecl->getIdentifier(),
2083 PropDecl->isClassProperty())])
2085 PropMap[std::make_pair(PropDecl->getIdentifier(),
2086 PropDecl->isClassProperty())] = PropDecl;
2091 if (PropMap.empty())
2096 PropImplMap.insert(I->getPropertyDecl());
2100 for (
const auto *I : IMPDecl->
methods())
2105 if (
C && !
C->IsClassExtension())
2106 if ((PrimaryClass =
C->getClassInterface()))
2112 for (
const auto *I : IMP->methods())
2116 for (ObjCContainerDecl::PropertyMap::iterator
2117 P = PropMap.begin(), E = PropMap.end();
P != E; ++
P) {
2122 PropImplMap.count(Prop) ||
2128 PrimaryClass, Prop->
getGetterName(), IMPDecl, CDecl,
C, Prop, InsMap);
2132 IMPDecl, CDecl,
C, Prop, InsMap);
2138 const auto *
property = propertyImpl->getPropertyDecl();
2141 if (propertyImpl->getPropertyImplementation() ==
2143 (property->getPropertyAttributes() &
2145 property->getGetterMethodDecl() && property->getSetterMethodDecl()) {
2146 auto *getterImpl = propertyImpl->getGetterMethodDecl();
2147 auto *setterImpl = propertyImpl->getSetterMethodDecl();
2148 if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) &&
2149 (!setterImpl || setterImpl->isSynthesizedAccessorStub())) {
2154 Diag(loc, diag::warn_null_resettable_setter)
2155 << setterImpl->getSelector() <<
property->getDeclName();
2169 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2171 for (
auto *Prop : Ext->properties())
2172 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2174 for (ObjCContainerDecl::PropertyMap::iterator I = PM.begin(), E = PM.end();
2180 unsigned Attributes =
Property->getPropertyAttributes();
2181 unsigned AttributesAsWritten =
Property->getPropertyAttributesAsWritten();
2185 GetterMethod =
Property->isClassProperty() ?
2188 SetterMethod =
Property->isClassProperty() ?
2192 GetterMethod =
nullptr;
2194 SetterMethod =
nullptr;
2197 diag::warn_default_atomic_custom_getter_setter)
2199 Diag(
Property->getLocation(), diag::note_property_declare);
2203 diag::warn_default_atomic_custom_getter_setter)
2205 Diag(
Property->getLocation(), diag::note_property_declare);
2217 GetterMethod = PIDecl->getGetterMethodDecl();
2218 SetterMethod = PIDecl->getSetterMethodDecl();
2220 GetterMethod =
nullptr;
2222 SetterMethod =
nullptr;
2223 if ((
bool)GetterMethod ^ (
bool)SetterMethod) {
2226 : SetterMethod->getLocation());
2227 Diag(MethodLoc, diag::warn_atomic_property_rule)
2228 <<
Property->getIdentifier() << (GetterMethod !=
nullptr)
2229 << (SetterMethod !=
nullptr);
2231 if (
Property->getLParenLoc().isValid() &&
2236 StringRef NonatomicStr = AttributesAsWritten?
"nonatomic, "
2239 diag::note_atomic_property_fixup_suggest)
2241 }
else if (
Property->getLParenLoc().isInvalid()) {
2244 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
2246 diag::note_atomic_property_fixup_suggest)
2249 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);
2250 Diag(
Property->getLocation(), diag::note_property_declare);
2262 if (PD && !PD->
hasAttr<NSReturnsNotRetainedAttr>() &&
2282 for (
auto *getterRedecl : method->
redecls()) {
2283 if (getterRedecl->isImplicit())
2287 noteLoc = getterRedecl->getLocation();
2288 fixItLoc = getterRedecl->getEndLoc();
2293 tok::kw___attribute, tok::l_paren, tok::l_paren,
2296 tok::r_paren, tok::r_paren
2298 StringRef spelling =
"__attribute__((objc_method_family(none)))";
2300 if (!macroName.empty())
2301 spelling = macroName;
2303 auto noteDiag =
Diag(noteLoc, diag::note_cocoa_naming_declare_family)
2307 fixItText += spelling;
2325 if (I->getMethodFamily() ==
OMF_init)
2326 InitSelSet.insert(I->getSelector());
2331 I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
2336 bool Ignore =
false;
2342 if (
auto *IMD = Ext->getInstanceMethod(MD->
getSelector())) {
2343 Ignore = IMD->isUnavailable();
2349 diag::warn_objc_implementation_missing_designated_init_override)
2362 for (
const auto *A :
Property->attrs()) {
2363 if (isa<DeprecatedAttr>(A) ||
2364 isa<UnavailableAttr>(A) ||
2365 isa<AvailabilityAttr>(A))
2380 bool IsClassProperty =
property->isClassProperty();
2381 GetterMethod = IsClassProperty ?
2389 if (CatDecl->IsClassExtension())
2392 CatDecl->getClassInterface()->
2395 SetterMethod = IsClassProperty ?
2400 if (CatDecl->IsClassExtension())
2403 CatDecl->getClassInterface()->
2410 if (!GetterMethod) {
2412 auto *ExistingGetter = CatDecl->getClassInterface()->lookupMethod(
2413 property->
getGetterName(), !IsClassProperty,
true,
false, CatDecl);
2414 if (ExistingGetter) {
2417 <<
property->isDirectProperty() << 1
2418 << ExistingGetter->isDirectMethod()
2419 << ExistingGetter->getDeclName();
2420 Diag(ExistingGetter->getLocation(), diag::note_previous_declaration);
2426 if (!property->
isReadOnly() && !SetterMethod) {
2428 auto *ExistingSetter = CatDecl->getClassInterface()->lookupMethod(
2429 property->
getSetterName(), !IsClassProperty,
true,
false, CatDecl);
2430 if (ExistingSetter) {
2433 <<
property->isDirectProperty() << 1
2434 << ExistingSetter->isDirectMethod()
2435 << ExistingSetter->getDeclName();
2436 Diag(ExistingSetter->getLocation(), diag::note_previous_declaration);
2442 if (!property->
isReadOnly() && SetterMethod) {
2448 (*SetterMethod->
param_begin())->getType().getNonReferenceType(),
2451 diag::warn_accessor_property_type_mismatch)
2452 <<
property->getDeclName()
2464 if (!GetterMethod) {
2472 QualType resultTy =
property->getType().getAtomicUnqualifiedType();
2481 modifiedTy, modifiedTy);
2487 !IsClassProperty,
false,
2498 GetterMethod->
addAttr(ObjCDirectAttr::CreateImplicit(
Context, Loc));
2500 if (property->
hasAttr<NSReturnsNotRetainedAttr>())
2501 GetterMethod->
addAttr(NSReturnsNotRetainedAttr::CreateImplicit(
Context,
2504 if (property->
hasAttr<ObjCReturnsInnerPointerAttr>())
2506 ObjCReturnsInnerPointerAttr::CreateImplicit(
Context, Loc));
2508 if (
const SectionAttr *SA = property->
getAttr<SectionAttr>())
2509 GetterMethod->
addAttr(SectionAttr::CreateImplicit(
2510 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2521 property->setGetterMethodDecl(GetterMethod);
2526 if (!SetterMethod) {
2536 nullptr, CD, !IsClassProperty,
2549 property->getType().getUnqualifiedType().getAtomicUnqualifiedType();
2559 modifiedTy, modifiedTy);
2577 SetterMethod->
addAttr(ObjCDirectAttr::CreateImplicit(
Context, Loc));
2580 if (
const SectionAttr *SA = property->
getAttr<SectionAttr>())
2581 SetterMethod->
addAttr(SectionAttr::CreateImplicit(
2582 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2594 property->setSetterMethodDecl(SetterMethod);
2608 if (!IsClassProperty) {
2621 if (!CurrentClass) {
2623 CurrentClass = Cat->getClassInterface();
2624 else if (
ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(CD))
2625 CurrentClass = Impl->getClassInterface();
2635 unsigned &Attributes,
2636 bool propertyInPrimaryClass) {
2643 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2644 <<
"readonly" <<
"readwrite";
2655 !PropertyDecl->
hasAttr<ObjCNSObjectAttr>()) {
2656 Diag(Loc, diag::err_objc_property_requires_object)
2661 :
"retain (or strong)");
2674 Diag(Loc, diag::warn_objc_property_assign_on_object);
2680 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2681 <<
"assign" <<
"copy";
2682 Attributes &= ~ObjCPropertyAttribute::kind_copy;
2685 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2686 <<
"assign" <<
"retain";
2687 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2690 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2691 <<
"assign" <<
"strong";
2692 Attributes &= ~ObjCPropertyAttribute::kind_strong;
2696 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2697 <<
"assign" <<
"weak";
2698 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2700 if (PropertyDecl->
hasAttr<IBOutletCollectionAttr>())
2701 Diag(Loc, diag::warn_iboutletcollection_property_assign);
2704 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2705 <<
"unsafe_unretained" <<
"copy";
2706 Attributes &= ~ObjCPropertyAttribute::kind_copy;
2709 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2710 <<
"unsafe_unretained" <<
"retain";
2711 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2714 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2715 <<
"unsafe_unretained" <<
"strong";
2716 Attributes &= ~ObjCPropertyAttribute::kind_strong;
2720 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2721 <<
"unsafe_unretained" <<
"weak";
2722 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2726 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2727 <<
"copy" <<
"retain";
2728 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2731 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2732 <<
"copy" <<
"strong";
2733 Attributes &= ~ObjCPropertyAttribute::kind_strong;
2736 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2737 <<
"copy" <<
"weak";
2738 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2742 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"retain"
2744 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2747 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"strong"
2749 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2756 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2757 <<
"nonnull" <<
"weak";
2763 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) <<
"atomic"
2765 Attributes &= ~ObjCPropertyAttribute::kind_atomic;
2784 else if (propertyInPrimaryClass) {
2789 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
2793 Diag(Loc, diag::warn_objc_property_default_assign_on_object);
2805 Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
2810 Diag(Loc, diag::warn_objc_property_retain_of_block);
2814 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
const T * castAs() const
Member-template castAs<specific type>.
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.