clang: lib/Sema/SemaObjCProperty.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
23#include "llvm/ADT/DenseSet.h"
24
25using namespace clang;
26
27
28
29
30
31
32
33
34
35
36
39
40
41 if (attrs &
49 }
50
51
52
54 type->isObjCRetainableType()) {
56 }
57
59}
60
61
62
66
69 = property->getType().getObjCLifetime();
70
72
75 if (!expectedLifetime) {
76
77
78
79
85 } else {
88 }
89 property->setPropertyAttributes(attr);
90 return;
91 }
92
93 if (propertyLifetime == expectedLifetime) return;
94
95 property->setInvalidDecl();
97 diag::err_arc_inconsistent_property_ownership)
98 << property->getDeclName()
99 << expectedLifetime
100 << propertyLifetime;
101}
102
103
104
105static void
108 llvm::SmallPtrSetImpl<ObjCProtocolDecl *> &Known) {
109
110 if (!Known.insert(Proto).second)
111 return;
112
113
117 true);
118 return;
119 }
120
121
122 for (auto *P : Proto->protocols())
124}
125
127
129 if (T.isObjCGCWeak())
131
132
133
134 } else if (auto ownership = T.getObjCLifetime()) {
135 switch (ownership) {
144 return 0;
145 }
146 llvm_unreachable("bad qualifier");
147 }
148
149 return 0;
150}
151
157
160
161
162
167 }
168
169 return result;
170}
171
180 0);
183 if (T.getPointerAuth().isPresent()) {
184 Diag(AtLoc, diag::err_ptrauth_qualifier_invalid) << T << 2;
185 }
188 }
190
192
193
196 if (ObjCCategoryDecl *CDecl = dyn_cast(ClassDecl)) {
197 if (CDecl->IsClassExtension()) {
199 FD,
202 isReadWrite, Attributes,
204 T, TSI, MethodImplKind);
205 if (!Res)
206 return nullptr;
207 }
208 }
209
210 if (!Res) {
215 MethodImplKind);
216 if (lexicalDC)
218 }
219
220
224
225
228
230 if (ObjCInterfaceDecl *IFace = dyn_cast(ClassDecl)) {
231
232 bool FoundInSuper = false;
238 FoundInSuper = true;
239 break;
240 }
241 CurrentInterfaceDecl = Super;
242 }
243
244 if (FoundInSuper) {
245
246 for (auto *P : CurrentInterfaceDecl->protocols()) {
248 }
249 } else {
250
251 for (auto *P : IFace->all_referenced_protocols()) {
253 }
254 }
255 } else if (ObjCCategoryDecl *Cat = dyn_cast(ClassDecl)) {
256
257
258
259 if (!Cat->IsClassExtension())
260 for (auto *P : Cat->protocols())
262 } else {
264 for (auto *P : Proto->protocols())
266 }
267
268 SemaRef.ActOnDocumentableDecl(Res);
269 return Res;
270}
271
274 unsigned attributesAsWritten = 0;
303
305}
306
310 return false;
311
314
315 bool invalidTemp = false;
316 StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
317 if (invalidTemp)
318 return false;
319 const char *tokenBegin = file.data() + locInfo.second;
320
321
322 Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
323 Context.getLangOpts(),
324 file.begin(), tokenBegin, file.end());
326 do {
328 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == attrName) {
329 Loc = Tok.getLocation();
330 return true;
331 }
332 } while (Tok.isNot(tok::r_paren));
333 return false;
334}
335
336
340 bool PropagateAtomicity) {
341
346 if (OldIsAtomic == NewIsAtomic) return;
347
348
349
350 auto isImplicitlyReadonlyAtomic = [](ObjCPropertyDecl *Property) -> bool {
351
352 auto Attrs = Property->getPropertyAttributes();
354 return false;
355
356
358 return false;
359
360
361 if (Property->getPropertyAttributesAsWritten() &
363 return false;
364
365 return true;
366 };
367
368
369
372 if (PropagateAtomicity &&
375 Attrs = Attrs & ~AtomicityMask;
376 if (OldIsAtomic)
378 else
380
382 return;
383 }
384
385
386
387 if ((OldIsAtomic && isImplicitlyReadonlyAtomic(OldProperty)) ||
388 (NewIsAtomic && isImplicitlyReadonlyAtomic(NewProperty)))
389 return;
390
391
394 if (auto Category = dyn_cast(OldDC))
395 OldContextName = Category->getClassInterface()->getIdentifier();
396 else
398
399 S.Diag(NewProperty->getLocation(), diag::warn_property_attribute)
400 << NewProperty->getDeclName() << "atomic"
401 << OldContextName;
402 S.Diag(OldProperty->getLocation(), diag::note_property_declare);
403}
404
409 unsigned &Attributes, const unsigned AttributesAsWritten, QualType T,
412
416
417
418
419 if (!CCPrimary) {
420 Diag(CDecl->getLocation(), diag::err_continuation_class);
421 return nullptr;
422 }
423
424 bool isClassProperty =
427
428
429
432
433
435 Diag(AtLoc, diag::err_duplicate_property);
436 Diag(PIDecl->getLocation(), diag::note_property_declare);
437 return nullptr;
438 }
439
440
441 if (PIDecl) {
442
443
444
445 if (!(PIDecl->isReadOnly() && isReadWrite)) {
446
447
448
449
450 unsigned diag =
454 ? diag::err_use_continuation_class_redeclaration_readwrite
455 : diag::err_use_continuation_class;
458 Diag(PIDecl->getLocation(), diag::note_property_declare);
459 return nullptr;
460 }
461
462
464
466 Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)
468 Diag(PIDecl->getLocation(), diag::note_property_declare);
469 }
470
471
474 }
475
476
477 unsigned ExistingOwnership
480 if (ExistingOwnership && NewOwnership != ExistingOwnership) {
481
483 Diag(AtLoc, diag::warn_property_attr_mismatch);
484 Diag(PIDecl->getLocation(), diag::note_property_declare);
485 }
486
487
488 Attributes = (Attributes & ~OwnershipMask) | ExistingOwnership;
489 }
490
491
497 Diag(AtLoc, diag::warn_property_implicitly_mismatched);
498 Diag(PIDecl->getLocation(), diag::note_property_declare);
499 }
500 }
501
502
503
505 FD, GetterSel, GetterNameLoc,
506 SetterSel, SetterNameLoc,
507 isReadWrite,
508 Attributes, AttributesAsWritten,
509 T, TSI, MethodImplKind, DC);
511
512
513 if (!PIDecl) {
515 return PDecl;
516 }
517
518 if (!Context.hasSameType(PIDecl->getType(), PDecl->getType())) {
519 bool IncompatibleObjC = false;
521
522
523
524
525
526
531 (.isObjCPointerConversion(ClassExtPropertyT,
532 PrimaryClassPropertyT, ConvertedType,
533 IncompatibleObjC)) ||
534 IncompatibleObjC) {
536 diag::err_type_mismatch_continuation_class) << PDecl->getType();
537 Diag(PIDecl->getLocation(), diag::note_property_declare);
538 return nullptr;
539 }
540 }
541
542
543
545
546
548 return PDecl;
549}
550
555 SourceLocation SetterNameLoc, const bool isReadWrite,
556 const unsigned Attributes, const unsigned AttributesAsWritten, QualType T,
561
562
563
564 bool isAssign;
567 isAssign = true;
569 isAssign = false;
570 } else {
571 isAssign = (().ObjCAutoRefCount ||
572 ->isObjCRetainableType());
573 }
574
575
576
581 ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
582 if (IDecl)
584 LookupProtocol(&Context.Idents.get("NSCopying"), AtLoc))
586 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
587 }
588 }
589
590 if (T->isObjCObjectType()) {
592 StarLoc = SemaRef.getLocForEndOfToken(StarLoc);
595 T = Context.getObjCObjectPointerType(T);
597 TInfo = Context.getTrivialTypeSourceInfo(T, TLoc);
598 }
599
603 PropertyId, AtLoc,
604 LParenLoc, T, TInfo);
605
606 bool isClassProperty =
609
612 Diag(PDecl->getLocation(), diag::err_duplicate_property);
613 Diag(prevDecl->getLocation(), diag::note_property_declare);
615 }
616 else {
618 if (lexicalDC)
620 }
621
622 if (T->isArrayType() || T->isFunctionType()) {
623 Diag(AtLoc, diag::err_property_type) << T;
625 }
626
627
628
633
634 SemaRef.ProcessDeclAttributes(S, PDecl, FD.D);
635
638
641
644
645 if (isReadWrite)
647
650
653
656
659
662
663 if (isAssign)
665
666
669 else
671
672
675 if (isAssign)
677
678 if (MethodImplKind == tok::objc_required)
680 else if (MethodImplKind == tok::objc_optional)
682
685
688
691
693 CDecl->hasAttr()) {
695 Diag(PDecl->getLocation(), diag::err_objc_direct_on_protocol) << true;
698 } else {
699 Diag(PDecl->getLocation(), diag::warn_objc_direct_property_ignored)
701 }
702 }
703
704 return PDecl;
705}
706
711
714
715
719
720
721 if (propertyLifetime == ivarLifetime) return;
722
723
724
728 return;
729
730
731
732
733
743 return;
744 }
745 }
746
747 switch (propertyLifetime) {
749 S.Diag(ivar->getLocation(), diag::err_arc_strong_property_ownership)
750 << property->getDeclName()
752 << ivarLifetime;
753 break;
754
757 << property->getDeclName()
759 break;
760
762 S.Diag(ivar->getLocation(), diag::err_arc_assign_property_ownership)
763 << property->getDeclName() << ivar->getDeclName()
764 << ((property->getPropertyAttributesAsWritten() &
766 break;
767
769 llvm_unreachable("properties cannot be autoreleasing");
770
772
773 return;
774 }
775
776 S.Diag(property->getLocation(), diag::note_property_declare);
777 if (propertyImplLoc.isValid())
778 S.Diag(propertyImplLoc, diag::note_property_synthesize);
779}
780
781
782
783
784
785
792 return;
793
794 if (!ivar) {
795
797 return;
798 }
799
806}
807
810 return (Attr1 & Kind) != (Attr2 & Kind);
811}
812
814 unsigned Kinds) {
815 return ((Attr1 & Kinds) != 0) != ((Attr2 & Kinds) != 0);
816}
817
818
819
820
821
822
828 "Expected a property from a protocol");
833 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
834 Properties);
835 }
837 while (SDecl) {
838 for (const auto *PI : SDecl->all_referenced_protocols()) {
840 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
841 Properties);
842 }
843 SDecl = SDecl->getSuperClass();
844 }
845 }
846
847 if (Properties.empty())
848 return Property;
849
851 size_t SelectedIndex = 0;
852 for (const auto &Prop : llvm::enumerate(Properties)) {
853
854 if (Property->isReadOnly() && !Prop.value()->isReadOnly()) {
855 Property = Prop.value();
856 SelectedIndex = Prop.index();
857 }
858 }
859 if (Property != OriginalProperty) {
860
861 Properties[SelectedIndex] = OriginalProperty;
862 }
863
865 unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
866 enum MismatchKind {
867 IncompatibleType = 0,
868 HasNoExpectedAttribute,
869 HasUnexpectedAttribute,
870 DifferentGetter,
871 DifferentSetter
872 };
873
874
875 struct MismatchingProperty {
877 MismatchKind Kind;
878 StringRef AttributeName;
879 };
882
883 unsigned Attr = Prop->getPropertyAttributesAsWritten();
884 if (Attr != OriginalAttributes) {
885 auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {
886 MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
887 : HasUnexpectedAttribute;
888 Mismatches.push_back({Prop, Kind, AttributeName});
889 };
890
891
892 bool HasOwnership =
899 if (HasOwnership &&
903 continue;
904 }
906 OriginalAttributes, Attr,
911 "retain (or strong)");
912 continue;
913 }
917 continue;
918 }
919 }
920 if (Property->getGetterName() != Prop->getGetterName()) {
921 Mismatches.push_back({Prop, DifferentGetter, ""});
922 continue;
923 }
924 if (!Property->isReadOnly() && !Prop->isReadOnly() &&
925 Property->getSetterName() != Prop->getSetterName()) {
926 Mismatches.push_back({Prop, DifferentSetter, ""});
927 continue;
928 }
931 bool IncompatibleObjC = false;
934 || IncompatibleObjC) {
935 Mismatches.push_back({Prop, IncompatibleType, ""});
936 continue;
937 }
938 }
939 }
940
941 if (Mismatches.empty())
942 return Property;
943
944
945 {
946 bool HasIncompatibleAttributes = false;
947 for (const auto &Note : Mismatches)
948 HasIncompatibleAttributes =
949 Note.Kind != IncompatibleType ? true : HasIncompatibleAttributes;
950
951
952 auto Diag = S.Diag(Property->getLocation(),
953 Property != OriginalProperty || HasIncompatibleAttributes
954 ? diag::err_protocol_property_mismatch
955 : diag::warn_protocol_property_mismatch);
956 Diag << Mismatches[0].Kind;
957 switch (Mismatches[0].Kind) {
958 case IncompatibleType:
959 Diag << Property->getType();
960 break;
961 case HasNoExpectedAttribute:
962 case HasUnexpectedAttribute:
963 Diag << Mismatches[0].AttributeName;
964 break;
965 case DifferentGetter:
966 Diag << Property->getGetterName();
967 break;
968 case DifferentSetter:
969 Diag << Property->getSetterName();
970 break;
971 }
972 }
973 for (const auto &Note : Mismatches) {
975 S.Diag(Note.Prop->getLocation(), diag::note_protocol_property_declare)
976 << Note.Kind;
977 switch (Note.Kind) {
978 case IncompatibleType:
979 Diag << Note.Prop->getType();
980 break;
981 case HasNoExpectedAttribute:
982 case HasUnexpectedAttribute:
984 break;
985 case DifferentGetter:
986 Diag << Note.Prop->getGetterName();
987 break;
988 case DifferentSetter:
989 Diag << Note.Prop->getSetterName();
990 break;
991 }
992 }
994 S.Diag(AtLoc, diag::note_property_synthesize);
995
996 return Property;
997}
998
999
1003
1004
1005
1006
1007
1008
1009 if (Prop->isReadOnly()) return false;
1010
1011
1012 auto Category = dyn_cast(Prop->getDeclContext());
1013 if (!Category || !Category->IsClassExtension()) return false;
1014
1015
1016 auto OrigClass = Category->getClassInterface();
1017 for (auto *Found : OrigClass->lookup(Prop->getDeclName())) {
1019 return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;
1020 }
1021
1022
1023 for (const auto *Proto : OrigClass->all_referenced_protocols()) {
1024 if (ObjCPropertyDecl *OrigProp = Proto->FindPropertyDeclaration(
1026 return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;
1027 }
1028
1029 return false;
1030}
1031
1032
1041 Decl->getSelector(), Decl->getReturnType(),
1042 Decl->getReturnTypeSourceInfo(), Impl, Decl->isInstanceMethod(),
1043 Decl->isVariadic(), Decl->isPropertyAccessor(),
1044 true, Decl->isImplicit(), Decl->isDefined(),
1045 Decl->getImplementationControl(), Decl->hasRelatedResultType());
1052 Decl->getSelectorLocs(SelLocs);
1056 return ImplDecl;
1057}
1058
1059
1060
1061
1062
1069 dyn_cast(SemaRef.CurContext);
1070
1071 if (!ClassImpDecl) {
1072 Diag(AtLoc, diag::err_missing_property_context);
1073 return nullptr;
1074 }
1075 if (PropertyIvarLoc.isInvalid())
1076 PropertyIvarLoc = PropertyLoc;
1078 if (PropertyDiagLoc.isInvalid())
1079 PropertyDiagLoc = ClassImpDecl->getBeginLoc();
1082
1083
1086 if ((IC = dyn_cast(ClassImpDecl))) {
1088
1089
1090 assert(IDecl &&
1091 "ActOnPropertyImplDecl - @implementation without @interface");
1092
1093
1095 if (!property) {
1096 Diag(PropertyLoc, diag::err_bad_property_decl) << IDecl->getDeclName();
1097 return nullptr;
1098 }
1099 if (property->isClassProperty() && Synthesize) {
1100 Diag(PropertyLoc, diag::err_synthesize_on_class_property) << PropertyId;
1101 return nullptr;
1102 }
1107 Diag(AtLoc, diag::warn_implicit_atomic_property);
1108 else
1109 Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property);
1110 Diag(property->getLocation(), diag::note_property_declare);
1111 }
1112
1114 dyn_cast(property->getDeclContext())) {
1115 if (!CD->IsClassExtension()) {
1116 Diag(PropertyLoc, diag::err_category_property) << CD->getDeclName();
1117 Diag(property->getLocation(), diag::note_property_declare);
1118 return nullptr;
1119 }
1120 }
1122 property->hasAttr() && !AtLoc.isValid()) {
1123 bool ReadWriteProperty = false;
1124
1125
1129 PIkind = ExtProp->getPropertyAttributesAsWritten();
1131 ReadWriteProperty = true;
1132 break;
1133 }
1134 }
1135 }
1136
1137 if (!ReadWriteProperty) {
1138 Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property)
1139 << property;
1142 property->getLParenLoc(), readonlyLoc)) {
1145 SourceRange ReadonlySourceRange(readonlyLoc, endLoc);
1146 Diag(property->getLocation(),
1147 diag::note_auto_readonly_iboutlet_fixup_suggest) <<
1149 }
1150 }
1151 }
1154 property);
1155
1156 } else if ((CatImplClass = dyn_cast(ClassImpDecl))) {
1157 if (Synthesize) {
1158 Diag(AtLoc, diag::err_synthesize_category_decl);
1159 return nullptr;
1160 }
1162 if (!IDecl) {
1163 Diag(AtLoc, diag::err_missing_property_interface);
1164 return nullptr;
1165 }
1168
1169
1170
1171 if (!Category)
1172 return nullptr;
1173
1175 if (!property) {
1176 Diag(PropertyLoc, diag::err_bad_category_property_decl)
1177 << Category->getDeclName();
1178 return nullptr;
1179 }
1180 } else {
1181 Diag(AtLoc, diag::err_bad_property_context);
1182 return nullptr;
1183 }
1185 bool CompleteTypeErr = false;
1186 bool compat = true;
1187
1188 if (Synthesize) {
1189
1190 if (!PropertyIvar)
1191 PropertyIvar = PropertyId;
1192
1195 QualType PropType = property->getType();
1197
1198 if (SemaRef.RequireCompleteType(PropertyDiagLoc, PropertyIvarType,
1199 diag::err_incomplete_synthesized_property,
1200 property->getDeclName())) {
1201 Diag(property->getLocation(), diag::note_property_declare);
1202 CompleteTypeErr = true;
1203 }
1204
1206 (property->getPropertyAttributesAsWritten() &
1210 }
1211
1213
1214 bool isARCWeak = false;
1216
1218 assert(().ObjCAutoRefCount);
1220 Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);
1221 Diag(property->getLocation(), diag::note_property_declare);
1222 } else {
1223 PropertyIvarType =
1224 Context.getObjCGCQualType(PropertyIvarType, Qualifiers::Weak);
1225 }
1226
1227
1228
1229 } else {
1231
1232 if (!Ivar) {
1233 Diag(PropertyDiagLoc,
1235 ? diag::err_synthesizing_arc_weak_property_disabled
1236 : diag::err_synthesizing_arc_weak_property_no_runtime);
1237 Diag(property->getLocation(), diag::note_property_declare);
1238 }
1239 CompleteTypeErr = true;
1240 } else {
1241 isARCWeak = true;
1246 Diag(property->getLocation(),
1247 diag::err_arc_weak_unavailable_property)
1248 << PropertyIvarType;
1249 Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class)
1250 << ClassImpDecl->getName();
1251 }
1252 }
1253 }
1254 }
1255 }
1256
1258
1259
1260
1261
1265 ClassDeclared);
1266 if (originalIvar) {
1267 Diag(PropertyDiagLoc,
1268 diag::warn_autosynthesis_property_ivar_match)
1269 << PropertyId << (Ivar == nullptr) << PropertyIvar
1271 Diag(property->getLocation(), diag::note_property_declare);
1272 Diag(originalIvar->getLocation(), diag::note_ivar_decl);
1273 }
1274 }
1275
1276 if (!Ivar) {
1277
1278
1279 if ((getLangOpts().ObjCAutoRefCount || isARCWeak) &&
1282
1283
1284
1287 Diag(PropertyDiagLoc,
1288 diag::err_arc_objc_property_default_assign_on_object);
1289 Diag(property->getLocation(), diag::note_property_declare);
1290 } else {
1293 assert(lifetime && "no lifetime for property?");
1294
1297 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);
1298 }
1299 }
1300
1301 if (Context.getLangOpts().PointerAuthObjcInterfaceSel &&
1303 if (Context.isObjCSelType(QualType(PropertyIvarType.getTypePtr(), 0))) {
1304 if (auto PAQ = Context.getObjCMemberSelTypePtrAuth())
1305 PropertyIvarType =
1306 Context.getPointerAuthType(PropertyIvarType, PAQ);
1307 }
1308 }
1309
1311 PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,
1312 PropertyIvarType, nullptr,
1314 (Expr *)nullptr, true);
1315 if (SemaRef.RequireNonAbstractType(PropertyIvarLoc, PropertyIvarType,
1316 diag::err_abstract_type_in_decl,
1318 Diag(property->getLocation(), diag::note_property_declare);
1319
1320 CompleteTypeErr = true;
1321 }
1322 if (!CompleteTypeErr) {
1323 if (const auto *RD = PropertyIvarType->getAsRecordDecl();
1325 Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)
1326 << PropertyIvarType;
1327 CompleteTypeErr = true;
1328 }
1329 }
1330 if (CompleteTypeErr)
1332 ClassImpDecl->addDecl(Ivar);
1334
1336 Diag(PropertyDiagLoc, diag::err_missing_property_ivar_decl)
1337 << PropertyId;
1338
1339
1342 Diag(PropertyDiagLoc, diag::err_ivar_in_superclass_use)
1343 << property->getDeclName() << Ivar->getDeclName()
1345 Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
1346 << Ivar << Ivar->getName();
1347
1348 }
1349 property->setPropertyIvarDecl(Ivar);
1350
1352
1353
1354 if (!Context.hasSameType(PropertyIvarType, IvarType)) {
1357 compat = Context.canAssignObjCInterfaces(
1360 else {
1361 compat = SemaRef.IsAssignConvertCompatible(
1362 SemaRef.CheckAssignmentConstraints(PropertyIvarLoc,
1363 PropertyIvarType, IvarType));
1364 }
1365 if (!compat) {
1366 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1367 << property->getDeclName() << PropType
1370
1371
1372 }
1373 else {
1374
1375
1376
1379 if (lhsType != rhsType &&
1381 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1382 << property->getDeclName() << PropType
1385
1386 }
1387 }
1388
1391 Diag(PropertyDiagLoc, diag::err_weak_property)
1392 << property->getDeclName() << Ivar->getDeclName();
1394
1395 }
1396
1397 if ((property->getType()->isObjCObjectPointerType() ||
1400 Diag(PropertyDiagLoc, diag::err_strong_property)
1401 << property->getDeclName() << Ivar->getDeclName();
1402
1403 }
1404 }
1405 if (getLangOpts().ObjCAutoRefCount || isARCWeak ||
1408 } else if (PropertyIvar)
1409
1410 Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);
1411
1412 assert (property && "ActOnPropertyImplDecl - property declaration missing");
1414 Context, SemaRef.CurContext, AtLoc, PropertyLoc, property,
1417 Ivar, PropertyIvarLoc);
1418
1419 if (CompleteTypeErr || !compat)
1421
1422 if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
1423 getterMethod->createImplicitParams(Context, IDecl);
1424
1425
1426 if (Synthesize) {
1427
1429 getterMethod->getSelector(), getterMethod->isInstanceMethod());
1430 if (!OMD)
1432 PropertyLoc);
1434 }
1435
1438
1439
1440
1445 PropertyDiagLoc);
1446 SemaRef.MarkDeclRefReferenced(SelfExpr);
1448 Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,
1450 Expr *IvarRefExpr =
1453 PropertyDiagLoc,
1455 LoadSelfExpr, true, true);
1458 getterMethod->getReturnType()),
1459 PropertyDiagLoc, IvarRefExpr);
1462 if (ResExpr)
1463 ResExpr = SemaRef.MaybeCreateExprWithCleanups(ResExpr);
1465 }
1466 }
1467 if (property->hasAttr() &&
1468 !getterMethod->hasAttr()) {
1469 Diag(getterMethod->getLocation(),
1470 diag::warn_property_getter_owning_mismatch);
1471 Diag(property->getLocation(), diag::note_property_declare);
1472 }
1473 if (getLangOpts().ObjCAutoRefCount && Synthesize)
1474 switch (getterMethod->getMethodFamily()) {
1479 Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def)
1480 << 1 << getterMethod->getSelector();
1481 break;
1482 default:
1483 break;
1484 }
1485 }
1486
1487 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
1488 setterMethod->createImplicitParams(Context, IDecl);
1489
1490
1491 if (Synthesize) {
1493 setterMethod->getSelector(), setterMethod->isInstanceMethod());
1494 if (!OMD)
1496 AtLoc, PropertyLoc);
1498 }
1499
1502
1507 PropertyDiagLoc);
1508 SemaRef.MarkDeclRefReferenced(SelfExpr);
1510 Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,
1515 PropertyDiagLoc,
1517 LoadSelfExpr, true, true);
1520 QualType T = Param->getType().getNonReferenceType();
1523 SemaRef.MarkDeclRefReferenced(rhs);
1525 SemaRef.BuildBinOp(S, PropertyDiagLoc, BO_Assign, lhs, rhs);
1526 if (property->getPropertyAttributes() &
1530 dyn_cast_or_null(callExpr))
1531 if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
1532 if (!FuncDecl->isTrivial())
1533 if (property->getType()->isReferenceType()) {
1534 Diag(PropertyDiagLoc,
1535 diag::err_atomic_property_nontrivial_assign_op)
1536 << property->getType();
1537 Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
1538 << FuncDecl;
1539 }
1540 }
1542 }
1543 }
1544
1545 if (IC) {
1546 if (Synthesize)
1549 Diag(PropertyLoc, diag::err_duplicate_ivar_use)
1550 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1551 << PropertyIvar;
1552 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1553 }
1554
1557 Diag(PropertyLoc, diag::err_property_implemented) << PropertyId;
1558 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1559 return nullptr;
1560 }
1562 if (getLangOpts().ObjCDefaultSynthProperties &&
1565
1566
1567
1570 if (!Synthesize)
1572 else {
1573 if (PropertyIvar && PropertyIvar != PropertyId)
1575 }
1576
1580 << PropertyId;
1582 }
1583 }
1584 } else {
1585 if (Synthesize)
1588 Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)
1589 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1590 << PropertyIvar;
1591 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1592 }
1593
1596 Diag(PropertyDiagLoc, diag::err_property_implemented) << PropertyId;
1597 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1598 return nullptr;
1599 }
1601 }
1602
1606 Diag(PropertyLoc, diag::err_objc_direct_dynamic_property);
1608 diag::note_previous_declaration);
1609 return nullptr;
1610 }
1611
1612 return PIDecl;
1613}
1614
1615
1616
1617
1618
1619
1620
1621
1625 bool OverridingProtocolProperty) {
1629
1630
1631
1632
1633 if (!OverridingProtocolProperty &&
1635 ;
1636 else {
1639 Diag(Property->getLocation(), diag::warn_readonly_property)
1640 << Property->getDeclName() << inheritedName;
1643 Diag(Property->getLocation(), diag::warn_property_attribute)
1644 << Property->getDeclName() << "copy" << inheritedName;
1650 bool CStrong = (CAttrRetain != 0);
1651 bool SStrong = (SAttrRetain != 0);
1652 if (CStrong != SStrong)
1653 Diag(Property->getLocation(), diag::warn_property_attribute)
1654 << Property->getDeclName() << "retain (or strong)" << inheritedName;
1655 }
1656 }
1657
1658
1659
1660
1662
1663
1667 Diag(Property->getLocation(), diag::warn_property_attribute)
1668 << Property->getDeclName() << "setter" << inheritedName;
1669 Diag(SuperProperty->getLocation(), diag::note_property_declare);
1670 }
1672 Diag(Property->getLocation(), diag::warn_property_attribute)
1673 << Property->getDeclName() << "getter" << inheritedName;
1674 Diag(SuperProperty->getLocation(), diag::note_property_declare);
1675 }
1676
1681
1682 if (!Context.propertyTypesAreCompatible(LHSType, RHSType)) {
1683
1684
1685 bool IncompatibleObjC = false;
1687 if (.isObjCPointerConversion(RHSType, LHSType, ConvertedType,
1688 IncompatibleObjC) ||
1689 IncompatibleObjC) {
1690 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
1691 << Property->getType() << SuperProperty->getType() << inheritedName;
1692 Diag(SuperProperty->getLocation(), diag::note_property_declare);
1693 }
1694 }
1695}
1696
1701 if (!GetterMethod)
1702 return false;
1704 QualType PropertyRValueType =
1705 property->getType().getNonReferenceType().getAtomicUnqualifiedType();
1706 bool compat = Context.hasSameType(PropertyRValueType, GetterType);
1707 if (!compat) {
1710 if ((propertyObjCPtr =
1713 compat = Context.canAssignObjCInterfaces(getterObjCPtr, propertyObjCPtr);
1714 else if (.IsAssignConvertCompatible(
1715 SemaRef.CheckAssignmentConstraints(Loc, GetterType,
1716 PropertyRValueType))) {
1717 Diag(Loc, diag::err_property_accessor_type)
1718 << property->getDeclName() << PropertyRValueType
1719 << GetterMethod->getSelector() << GetterType;
1720 Diag(GetterMethod->getLocation(), diag::note_declared_at);
1721 return true;
1722 } else {
1723 compat = true;
1727 compat = false;
1728 }
1729 }
1730
1731 if (!compat) {
1732 Diag(Loc, diag::warn_accessor_property_type_mismatch)
1733 << property->getDeclName()
1735 Diag(GetterMethod->getLocation(), diag::note_declared_at);
1736 return true;
1737 }
1738
1739 return false;
1740}
1741
1742
1743
1744static void
1748 bool CollectClassPropsOnly = false,
1749 bool IncludeProtocols = true) {
1750 if (ObjCInterfaceDecl *IDecl = dyn_cast(CDecl)) {
1751 for (auto *Prop : IDecl->properties()) {
1752 if (CollectClassPropsOnly && !Prop->isClassProperty())
1753 continue;
1754 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1755 Prop;
1756 }
1757
1758
1759 for (auto *Ext : IDecl->visible_extensions())
1761 CollectClassPropsOnly, IncludeProtocols);
1762
1763 if (IncludeProtocols) {
1764
1765 for (auto *PI : IDecl->all_referenced_protocols())
1767 CollectClassPropsOnly);
1768 }
1769 }
1770 if (ObjCCategoryDecl *CATDecl = dyn_cast(CDecl)) {
1771 for (auto *Prop : CATDecl->properties()) {
1772 if (CollectClassPropsOnly && !Prop->isClassProperty())
1773 continue;
1774 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1775 Prop;
1776 }
1777 if (IncludeProtocols) {
1778
1779 for (auto *PI : CATDecl->protocols())
1781 CollectClassPropsOnly);
1782 }
1783 }
1784 else if (ObjCProtocolDecl *PDecl = dyn_cast(CDecl)) {
1785 for (auto *Prop : PDecl->properties()) {
1786 if (CollectClassPropsOnly && !Prop->isClassProperty())
1787 continue;
1789 SuperPropMap[std::make_pair(Prop->getIdentifier(),
1790 Prop->isClassProperty())];
1791
1792
1793 if (!PropertyFromSuper ||
1794 PropertyFromSuper->getIdentifier() != Prop->getIdentifier()) {
1796 PropMap[std::make_pair(Prop->getIdentifier(),
1797 Prop->isClassProperty())];
1798 if (!PropEntry)
1799 PropEntry = Prop;
1800 }
1801 }
1802
1803 for (auto *PI : PDecl->protocols())
1805 CollectClassPropsOnly);
1806 }
1807}
1808
1809
1810
1811
1815 while (SDecl) {
1816 SDecl->collectPropertiesToImplement(PropMap);
1817 SDecl = SDecl->getSuperClass();
1818 }
1819 }
1820}
1821
1822
1823
1824
1829 return false;
1831 Method->isInstanceMethod());
1833 return false;
1834
1835
1836
1840 (Property->getPropertyIvarDecl() == IV))
1841 return true;
1842 }
1843
1844
1846 for (const auto *Property : Ext->instance_properties())
1849 (Property->getPropertyIvarDecl() == IV))
1850 return true;
1851 return false;
1852}
1853
1856 bool SuperClassImplementsGetter = false;
1857 bool SuperClassImplementsSetter = false;
1859 SuperClassImplementsSetter = true;
1860
1864 SuperClassImplementsGetter = true;
1865
1867 SuperClassImplementsSetter = true;
1868 if (SuperClassImplementsGetter && SuperClassImplementsSetter)
1869 return true;
1871 }
1872 return false;
1873}
1874
1875
1876
1883 if (PropMap.empty())
1884 return;
1887
1888 for (const auto &PropEntry : PropMap) {
1890
1894 continue;
1895
1898 continue;
1900 if (ImpMethod && !ImpMethod->getBody()) {
1902 continue;
1904 if (ImpMethod && !ImpMethod->getBody())
1905 continue;
1906 }
1909 Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
1911 if (PID->getLocation().isValid())
1912 Diag(PID->getLocation(), diag::note_property_synthesize);
1913 continue;
1914 }
1916 SuperPropMap[std::make_pair(Prop->getIdentifier(),
1919 dyn_cast(Prop->getDeclContext())) {
1920
1921
1922
1923
1926 diag::warn_auto_synthesizing_protocol_property)
1927 << Prop << Proto;
1929 std::string FixIt =
1930 (Twine("@synthesize ") + Prop->getName() + ";\n\n").str();
1931 Diag(AtEnd, diag::note_add_synthesize_directive)
1933 }
1934 continue;
1935 }
1936
1937 if (PropInSuperClass) {
1944 Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
1946 Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
1947 } else {
1948 Diag(Prop->getLocation(), diag::warn_autosynthesis_property_in_superclass)
1950 Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
1951 Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
1952 }
1953 continue;
1954 }
1955
1956
1957
1958
1961 true,
1966 Diag(Prop->getLocation(), diag::warn_missing_explicit_synthesis);
1967 Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
1968 }
1969 }
1970}
1971
1974 if (().ObjCDefaultSynthProperties ||
1976 return;
1978 if (!IC)
1979 return;
1981 if (!IDecl->isObjCRequiresPropertyDefs())
1983}
1984
1990
1991
1995 });
1996
1997
1998
1999
2000 if (I == SMap.end() &&
2001 (PrimaryClass == nullptr ||
2004 unsigned diag =
2007 ? diag::warn_impl_required_in_category_for_class_property
2008 : diag::warn_setter_getter_impl_required_in_category)
2010 ? diag::warn_impl_required_for_class_property
2011 : diag::warn_setter_getter_impl_required);
2013 S.Diag(Prop->getLocation(), diag::note_property_declare);
2014 if (S.LangOpts.ObjCDefaultSynthProperties &&
2018 S.Diag(RID->getLocation(), diag::note_suppressed_class_declare);
2019 }
2020}
2021
2024 bool SynthesizeProperties) {
2027
2028
2029
2031
2032
2033 if (!IDecl)
2035
2036
2037
2038 if ((IDecl = C->getClassInterface())) {
2040 }
2041 }
2042 if (IDecl)
2044
2045
2047 SynthesizeProperties);
2048
2049
2050
2051
2052 if (IDecl) {
2053 std::unique_ptrObjCContainerDecl::PropertyMap LazyMap;
2054
2056 if (!PDecl->hasAttr())
2057 continue;
2058
2059
2060
2061
2062
2063
2064
2065 if (!LazyMap) {
2069 false,
2070 false);
2071 }
2072
2073
2074 for (auto *PropDecl : PDecl->properties()) {
2075 if ((*LazyMap)[std::make_pair(PropDecl->getIdentifier(),
2076 PropDecl->isClassProperty())])
2077 continue;
2078 PropMap[std::make_pair(PropDecl->getIdentifier(),
2079 PropDecl->isClassProperty())] = PropDecl;
2080 }
2081 }
2082 }
2083
2084 if (PropMap.empty())
2085 return;
2086
2087 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;
2089 PropImplMap.insert(I->getPropertyDecl());
2090
2091
2094
2097 if (C && ->IsClassExtension())
2098 if ((PrimaryClass = C->getClassInterface()))
2099
2101
2102
2103
2104 InsMap.insert_range(IMP->methods());
2105 }
2106
2107 for (ObjCContainerDecl::PropertyMap::iterator
2108 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
2110
2113 PropImplMap.count(Prop) ||
2115 continue;
2116
2117
2119 IMPDecl, CDecl, C, Prop, InsMap);
2123 Prop, InsMap);
2124 }
2125}
2126
2129 for (const auto *propertyImpl : impDecl->property_impls()) {
2130 const auto *property = propertyImpl->getPropertyDecl();
2131
2132
2133 if (propertyImpl->getPropertyImplementation() ==
2135 (property->getPropertyAttributes() &
2137 property->getGetterMethodDecl() && property->getSetterMethodDecl()) {
2138 auto *getterImpl = propertyImpl->getGetterMethodDecl();
2139 auto *setterImpl = propertyImpl->getSetterMethodDecl();
2140 if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) &&
2141 (!setterImpl || setterImpl->isSynthesizedAccessorStub())) {
2145
2146 Diag(loc, diag::warn_null_resettable_setter)
2147 << setterImpl->getSelector() << property->getDeclName();
2148 }
2149 }
2150 }
2151}
2152
2155
2157 return;
2159 for (auto *Prop : IDecl->properties())
2160 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2162 for (auto *Prop : Ext->properties())
2163 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2164
2165 for (ObjCContainerDecl::PropertyMap::iterator I = PM.begin(), E = PM.end();
2166 I != E; ++I) {
2170
2171 unsigned Attributes = Property->getPropertyAttributes();
2172 unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten();
2173
2176 GetterMethod = Property->isClassProperty() ?
2179 SetterMethod = Property->isClassProperty() ?
2183 GetterMethod = nullptr;
2185 SetterMethod = nullptr;
2186 if (GetterMethod) {
2188 diag::warn_default_atomic_custom_getter_setter)
2189 << Property->getIdentifier() << 0;
2190 Diag(Property->getLocation(), diag::note_property_declare);
2191 }
2192 if (SetterMethod) {
2194 diag::warn_default_atomic_custom_getter_setter)
2195 << Property->getIdentifier() << 1;
2196 Diag(Property->getLocation(), diag::note_property_declare);
2197 }
2198 }
2199
2200
2203 continue;
2207 continue;
2208 GetterMethod = PIDecl->getGetterMethodDecl();
2209 SetterMethod = PIDecl->getSetterMethodDecl();
2211 GetterMethod = nullptr;
2213 SetterMethod = nullptr;
2214 if ((bool)GetterMethod ^ (bool)SetterMethod) {
2216 (GetterMethod ? GetterMethod->getLocation()
2217 : SetterMethod->getLocation());
2218 Diag(MethodLoc, diag::warn_atomic_property_rule)
2219 << Property->getIdentifier() << (GetterMethod != nullptr)
2220 << (SetterMethod != nullptr);
2221
2222 if (Property->getLParenLoc().isValid() &&
2224
2227 StringRef NonatomicStr = AttributesAsWritten? "nonatomic, "
2228 : "nonatomic";
2230 diag::note_atomic_property_fixup_suggest)
2232 } else if (Property->getLParenLoc().isInvalid()) {
2233
2235 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
2237 diag::note_atomic_property_fixup_suggest)
2239 } else
2240 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);
2241 Diag(Property->getLocation(), diag::note_property_declare);
2242 }
2243 }
2244 }
2245}
2246
2250 return;
2251
2254 if (PD && !PD->hasAttr() &&
2258 continue;
2260 if (!method)
2261 continue;
2266 Diag(PD->getLocation(), diag::err_cocoa_naming_owned_rule);
2267 else
2268 Diag(PD->getLocation(), diag::warn_cocoa_naming_owned_rule);
2269
2270
2271
2274 for (auto *getterRedecl : method->redecls()) {
2275 if (getterRedecl->isImplicit())
2276 continue;
2277 if (getterRedecl->getDeclContext() != PD->getDeclContext())
2278 continue;
2279 noteLoc = getterRedecl->getLocation();
2280 fixItLoc = getterRedecl->getEndLoc();
2281 }
2282
2285 tok::kw___attribute, tok::l_paren, tok::l_paren,
2288 tok::r_paren, tok::r_paren
2289 };
2290 StringRef spelling = "__attribute__((objc_method_family(none)))";
2292 if (!macroName.empty())
2293 spelling = macroName;
2294
2295 auto noteDiag = Diag(noteLoc, diag::note_cocoa_naming_declare_family)
2297 if (fixItLoc.isValid()) {
2299 fixItText += spelling;
2301 }
2302 }
2303 }
2304 }
2305}
2306
2311 if (!SuperD)
2312 return;
2313
2316 if (I->getMethodFamily() == OMF_init)
2317 InitSelSet.insert(I->getSelector());
2318
2322 I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
2324 if (!InitSelSet.count(MD->getSelector())) {
2325
2326
2327 bool Ignore = false;
2329 Ignore = IMD->isUnavailable();
2330 } else {
2331
2333 if (auto *IMD = Ext->getInstanceMethod(MD->getSelector())) {
2334 Ignore = IMD->isUnavailable();
2335 break;
2336 }
2337 }
2338 if (!Ignore) {
2340 diag::warn_objc_implementation_missing_designated_init_override)
2342 Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here);
2343 }
2344 }
2345 }
2346}
2347
2348
2349
2352
2353 for (const auto *A : Property->attrs()) {
2358 }
2359}
2360
2361
2362
2363
2364
2370 return;
2371
2372 bool IsClassProperty = property->isClassProperty();
2373 GetterMethod = IsClassProperty ?
2376
2377
2378
2379 if (!GetterMethod)
2380 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD))
2381 if (CatDecl->IsClassExtension())
2382 GetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
2384 CatDecl->getClassInterface()->
2386
2387 SetterMethod = IsClassProperty ?
2390 if (!SetterMethod)
2391 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD))
2392 if (CatDecl->IsClassExtension())
2393 SetterMethod = IsClassProperty ? CatDecl->getClassInterface()->
2395 CatDecl->getClassInterface()->
2399
2400
2401
2402 if (!GetterMethod) {
2403 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD)) {
2404 auto *ExistingGetter = CatDecl->getClassInterface()->lookupMethod(
2405 property->getGetterName(), !IsClassProperty, true, false, CatDecl);
2406 if (ExistingGetter) {
2407 if (ExistingGetter->isDirectMethod() || property->isDirectProperty()) {
2408 Diag(property->getLocation(), diag::err_objc_direct_duplicate_decl)
2409 << property->isDirectProperty() << 1
2410 << ExistingGetter->isDirectMethod()
2411 << ExistingGetter->getDeclName();
2412 Diag(ExistingGetter->getLocation(), diag::note_previous_declaration);
2413 }
2414 }
2415 }
2416 }
2417
2418 if (!property->isReadOnly() && !SetterMethod) {
2419 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD)) {
2420 auto *ExistingSetter = CatDecl->getClassInterface()->lookupMethod(
2421 property->getSetterName(), !IsClassProperty, true, false, CatDecl);
2422 if (ExistingSetter) {
2423 if (ExistingSetter->isDirectMethod() || property->isDirectProperty()) {
2424 Diag(property->getLocation(), diag::err_objc_direct_duplicate_decl)
2425 << property->isDirectProperty() << 1
2426 << ExistingSetter->isDirectMethod()
2427 << ExistingSetter->getDeclName();
2428 Diag(ExistingSetter->getLocation(), diag::note_previous_declaration);
2429 }
2430 }
2431 }
2432 }
2433
2434 if (!property->isReadOnly() && SetterMethod) {
2435 if (Context.getCanonicalType(SetterMethod->getReturnType()) !=
2436 Context.VoidTy)
2437 Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
2438 if (SetterMethod->param_size() != 1 ||
2439 !Context.hasSameUnqualifiedType(
2440 (*SetterMethod->param_begin())->getType().getNonReferenceType(),
2443 diag::warn_accessor_property_type_mismatch)
2444 << property->getDeclName()
2446 Diag(SetterMethod->getLocation(), diag::note_declared_at);
2447 }
2448 }
2449
2450
2451
2452
2453
2454
2455
2456 if (!GetterMethod) {
2457
2458
2459
2461
2462
2463
2464 QualType resultTy = property->getType().getAtomicUnqualifiedType();
2465
2466
2469 QualType modifiedTy = resultTy;
2470 if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
2473 modifiedTy, modifiedTy);
2474 }
2475 }
2476
2478 Context, Loc, Loc, property->getGetterName(), resultTy, nullptr, CD,
2479 !IsClassProperty, false,
2480 true, false,
2481 true, false,
2485 CD->addDecl(GetterMethod);
2486
2488
2490 GetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2491
2492 if (property->hasAttr())
2493 GetterMethod->addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context,
2494 Loc));
2495
2496 if (property->hasAttr())
2498 ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc));
2499
2500 if (const SectionAttr *SA = property->getAttr())
2501 GetterMethod->addAttr(SectionAttr::CreateImplicit(
2502 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2503
2504 SemaRef.ProcessAPINotes(GetterMethod);
2505
2508 } else
2509
2510
2512
2515 property->setGetterMethodDecl(GetterMethod);
2516
2517
2519
2520 if (!SetterMethod) {
2521
2522
2523
2524
2526
2528 Context, Loc, Loc, property->getSetterName(), Context.VoidTy, nullptr,
2529 CD, !IsClassProperty,
2530 false,
2531 true,
2532 false,
2533 true,
2534 false,
2538
2539
2541 property->getType().getUnqualifiedType().getAtomicUnqualifiedType();
2542
2543
2544
2547 QualType modifiedTy = paramTy;
2548 if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
2551 modifiedTy, modifiedTy);
2552 }
2553 }
2554
2555
2556
2558 Loc, Loc,
2560 paramTy,
2561 nullptr,
2563 nullptr);
2565
2567
2569 SetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2570
2571 CD->addDecl(SetterMethod);
2572 if (const SectionAttr *SA = property->getAttr())
2573 SetterMethod->addAttr(SectionAttr::CreateImplicit(
2574 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2575
2576 SemaRef.ProcessAPINotes(SetterMethod);
2577
2578
2579
2582 } else
2583
2584
2586
2589 property->setSetterMethodDecl(SetterMethod);
2590 }
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603 if (!IsClassProperty) {
2604 if (GetterMethod)
2606 if (SetterMethod)
2608 } else {
2609 if (GetterMethod)
2611 if (SetterMethod)
2613 }
2614
2615 ObjCInterfaceDecl *CurrentClass = dyn_cast(CD);
2616 if (!CurrentClass) {
2618 CurrentClass = Cat->getClassInterface();
2619 else if (ObjCImplDecl *Impl = dyn_cast(CD))
2620 CurrentClass = Impl->getClassInterface();
2621 }
2622 if (GetterMethod)
2624 if (SetterMethod)
2626}
2627
2629 unsigned &Attributes,
2630 bool propertyInPrimaryClass) {
2631
2633 return;
2634
2637 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2638 << "readonly" << "readwrite";
2639
2642
2643
2644 if ((Attributes &
2649 !PropertyDecl->hasAttr()) {
2650 Diag(Loc, diag::err_objc_property_requires_object)
2652 ? "weak"
2654 ? "copy"
2655 : "retain (or strong)");
2656 Attributes &=
2661 }
2662
2663
2668 Diag(Loc, diag::warn_objc_property_assign_on_object);
2669 }
2670
2671
2674 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2675 << "assign" << "copy";
2677 }
2679 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2680 << "assign" << "retain";
2682 }
2684 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2685 << "assign" << "strong";
2687 }
2690 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2691 << "assign" << "weak";
2693 }
2694 if (PropertyDecl->hasAttr())
2695 Diag(Loc, diag::warn_iboutletcollection_property_assign);
2698 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2699 << "unsafe_unretained" << "copy";
2701 }
2703 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2704 << "unsafe_unretained" << "retain";
2706 }
2708 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2709 << "unsafe_unretained" << "strong";
2711 }
2714 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2715 << "unsafe_unretained" << "weak";
2717 }
2720 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2721 << "copy" << "retain";
2723 }
2725 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2726 << "copy" << "strong";
2728 }
2730 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2731 << "copy" << "weak";
2733 }
2736 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "retain"
2737 << "weak";
2741 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "strong"
2742 << "weak";
2744 }
2745
2747
2748 if (auto nullability = PropertyTy->getNullability()) {
2750 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2751 << "nonnull" << "weak";
2752 }
2753 }
2754
2757 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "atomic"
2758 << "nonatomic";
2760 }
2761
2762
2763
2766
2767 } else if (getLangOpts().ObjCAutoRefCount) {
2768
2769
2774
2775
2777 ;
2778 else if (propertyInPrimaryClass) {
2779
2780
2781
2783 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
2784
2785
2787 Diag(Loc, diag::warn_objc_property_default_assign_on_object);
2788 }
2789 }
2790
2791
2792
2793 }
2794
2799 Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
2804 Diag(Loc, diag::warn_objc_property_retain_of_block);
2805
2808 Diag(Loc, diag::warn_objc_readonly_property_has_setter);
2809}
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)
Definition SemaObjCProperty.cpp:1854
static bool areIncompatiblePropertyAttributes(unsigned Attr1, unsigned Attr2, unsigned Kinds)
Definition SemaObjCProperty.cpp:813
static Qualifiers::ObjCLifetime getImpliedARCOwnership(ObjCPropertyAttribute::Kind attrs, QualType type)
getImpliedARCOwnership - Given a set of property attributes and a type, infer an expected lifetime.
Definition SemaObjCProperty.cpp:38
static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc, ObjCPropertyDecl *property, ObjCIvarDecl *ivar)
Definition SemaObjCProperty.cpp:707
static bool LocPropertyAttribute(ASTContext &Context, const char *attrName, SourceLocation LParenLoc, SourceLocation &Loc)
Definition SemaObjCProperty.cpp:307
static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, ObjCPropertyDecl *Property)
AddPropertyAttrs - Propagates attributes from a property to the implicitly-declared getter or setter ...
Definition SemaObjCProperty.cpp:2350
static void checkPropertyDeclWithOwnership(Sema &S, ObjCPropertyDecl *property)
Check the internal consistency of a property declaration with an explicit ownership qualifier.
Definition SemaObjCProperty.cpp:63
static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T)
Definition SemaObjCProperty.cpp:126
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...
Definition SemaObjCProperty.cpp:1745
static void checkAtomicPropertyMismatch(Sema &S, ObjCPropertyDecl *OldProperty, ObjCPropertyDecl *NewProperty, bool PropagateAtomicity)
Check for a mismatch in the atomicity of the given properties.
Definition SemaObjCProperty.cpp:337
static void setImpliedPropertyAttributeForReadOnlyProperty(ObjCPropertyDecl *property, ObjCIvarDecl *ivar)
setImpliedPropertyAttributeForReadOnlyProperty - This routine evaludates life-time attributes for a '...
Definition SemaObjCProperty.cpp:786
static unsigned getOwnershipRule(unsigned attr)
Definition SemaObjCProperty.cpp:158
static ObjCMethodDecl * RedeclarePropertyAccessor(ASTContext &Context, ObjCImplementationDecl *Impl, ObjCMethodDecl *AccessorDecl, SourceLocation AtLoc, SourceLocation PropertyLoc)
Create a synthesized property accessor stub inside the @implementation.
Definition SemaObjCProperty.cpp:1034
static bool hasWrittenStorageAttribute(ObjCPropertyDecl *Prop, ObjCPropertyQueryKind QueryKind)
Determine whether any storage attributes were written on the property.
Definition SemaObjCProperty.cpp:1000
static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, ObjCInterfaceDecl::PropertyMap &PropMap)
CollectSuperClassPropertyImplementations - This routine collects list of properties to be implemented...
Definition SemaObjCProperty.cpp:1812
static const unsigned OwnershipMask
Definition SemaObjCProperty.cpp:152
static void DiagnoseUnimplementedAccessor(Sema &S, ObjCInterfaceDecl *PrimaryClass, Selector Method, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, ObjCCategoryDecl *C, ObjCPropertyDecl *Prop, llvm::SmallPtrSet< const ObjCMethodDecl *, 8 > &SMap)
Definition SemaObjCProperty.cpp:1985
static ObjCPropertyDecl * SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc, ObjCInterfaceDecl *ClassDecl, ObjCPropertyDecl *Property)
SelectPropertyForSynthesisFromProtocols - Finds the most appropriate property declaration that should...
Definition SemaObjCProperty.cpp:824
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.
Definition SemaObjCProperty.cpp:106
static ObjCPropertyAttribute::Kind makePropertyAttributesAsWritten(unsigned Attributes)
Definition SemaObjCProperty.cpp:273
static bool isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2, ObjCPropertyAttribute::Kind Kind)
Definition SemaObjCProperty.cpp:808
This file declares semantic analysis for Objective-C.
Defines the SourceManager interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool propertyTypesAreCompatible(QualType, QualType)
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Attr - This represents one attribute.
A call to an overloaded operator written using operator syntax.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
void makeDeclVisibleInContext(NamedDecl *D)
Makes a declaration visible within this context.
DeclContextLookupResult lookup_result
void addDecl(Decl *D)
Add the declaration D into this context.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
void setAttrs(const AttrVec &Attrs)
bool isUnavailable(std::string *Message=nullptr) const
Determine whether this declaration is marked 'unavailable'.
AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple(), StringRef *RealizedPlatform=nullptr) const
Determine the availability of the given declaration.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
bool isInvalidDecl() const
SourceLocation getLocation() const
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
void setLexicalDeclContext(DeclContext *DC)
SourceLocation getIdentifierLoc() const
void setObjCWeakProperty(bool Val=true)
const IdentifierInfo * getIdentifier() const
This represents one expression.
Represents difference between two FPOptions values.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Represents a function declaration or definition.
One of these records is kept for each identifier that is lexed.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)
Create the initialization entity for the result of a function.
clang::ObjCRuntime ObjCRuntime
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
bool LexFromRawLexer(Token &Result)
LexFromRawLexer - Lex a token from a designated raw lexer (one with no associated preprocessor object...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ObjCCategoryDecl - Represents a category declaration.
ObjCInterfaceDecl * getClassInterface()
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCContainerDecl - Represents a container for method declarations.
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
method_range methods() const
instmeth_range instance_methods() const
llvm::SmallDenseSet< const ObjCProtocolDecl *, 8 > ProtocolPropertySet
ObjCPropertyDecl * getProperty(const IdentifierInfo *Id, bool IsInstance) const
instprop_range instance_properties() const
llvm::MapVector< std::pair< IdentifierInfo *, unsigned >, ObjCPropertyDecl * > PropertyMap
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
llvm::SmallVector< ObjCPropertyDecl *, 8 > PropertyDeclOrder
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
prop_range properties() const
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const
This routine returns 'true' if a user declared setter method was found in the class,...
Captures information about "declaration specifiers" specific to Objective-C.
ObjCPropertyAttribute::Kind getPropertyAttributes() const
SourceLocation getGetterNameLoc() const
SourceLocation getSetterNameLoc() const
void addPropertyImplementation(ObjCPropertyImplDecl *property)
propimpl_range property_impls() const
ObjCPropertyImplDecl * FindPropertyImplDecl(IdentifierInfo *propertyId, ObjCPropertyQueryKind queryKind) const
FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl added to the list of thos...
const ObjCInterfaceDecl * getClassInterface() const
ObjCPropertyImplDecl * FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const
FindPropertyImplIvarDecl - This method lookup the ivar in the list of properties implemented in this ...
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCPropertyDecl * FindPropertyVisibleInPrimaryClass(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyVisibleInPrimaryClass - Finds declaration of the property with name 'PropertyId' in the p...
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
all_protocol_range all_referenced_protocols() const
visible_extensions_range visible_extensions() const
ObjCCategoryDecl * FindCategoryDeclaration(const IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
protocol_range protocols() const
const ObjCInterfaceDecl * isObjCRequiresPropertyDefs() const
isObjCRequiresPropertyDefs - Checks that a class or one of its super classes must not be auto-synthes...
ObjCMethodDecl * lookupPropertyAccessor(const Selector Sel, const ObjCCategoryDecl *Cat, bool IsClassProperty) const
Lookup a setter or getter in the class hierarchy, including in all categories except for category pas...
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const
lookupMethod - This method returns an instance/class method by looking in the class,...
bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, bool lookupCategory, bool RHSIsQualifiedID=false)
ClassImplementsProtocol - Checks that 'lProto' protocol has been implemented in IDecl class,...
ObjCImplementationDecl * getImplementation() const
bool hasDesignatedInitializers() const
Returns true if this interface decl contains at least one initializer marked with the 'objc_designate...
void getDesignatedInitializers(llvm::SmallVectorImpl< const ObjCMethodDecl * > &Methods) const
Returns the designated initializers for the interface.
void collectPropertiesToImplement(PropertyMap &PM) const override
This routine collects list of properties to be implemented in the class.
bool isArcWeakrefUnavailable() const
isArcWeakrefUnavailable - Checks for a class or one of its super classes to be incompatible with __we...
ObjCInterfaceDecl * getSuperClass() const
known_extensions_range known_extensions() const
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
bool getSynthesize() const
static ObjCIvarDecl * Create(ASTContext &C, ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW=nullptr, bool synthesized=false)
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
ObjCMethodDecl - Represents an instance or class method declaration.
void setDefined(bool isDefined)
unsigned param_size() const
void setSelfDecl(ImplicitParamDecl *SD)
bool isPropertyAccessor() const
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
param_const_iterator param_begin() const
void setCmdDecl(ImplicitParamDecl *CD)
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
bool isSynthesizedAccessorStub() const
void setPropertyAccessor(bool isAccessor)
Selector getSelector() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID)
createImplicitParams - Used to lazily create the self and cmd implicit parameters.
QualType getReturnType() const
ParmVarDecl *const * param_iterator
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
Represents one property declaration in an Objective-C interface.
ObjCPropertyQueryKind getQueryKind() const
bool isClassProperty() const
void setPropertyImplementation(PropertyControl pc)
void setSetterName(Selector Sel, SourceLocation Loc=SourceLocation())
ObjCMethodDecl * getGetterMethodDecl() const
bool isInstanceProperty() const
void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal)
bool isReadOnly() const
isReadOnly - Return true iff the property has a setter.
static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, ObjCPropertyQueryKind queryKind)
Lookup a property by name in the specified DeclContext.
bool isDirectProperty() const
Selector getSetterName() const
void setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal)
void overwritePropertyAttributes(unsigned PRVal)
Selector getGetterName() const
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
IdentifierInfo * getDefaultSynthIvarName(ASTContext &Ctx) const
Get the default name of the synthesized ivar.
ObjCPropertyAttribute::Kind getPropertyAttributes() const
static ObjCPropertyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation AtLocation, SourceLocation LParenLocation, QualType T, TypeSourceInfo *TSI, PropertyControl propControl=None)
void setGetterName(Selector Sel, SourceLocation Loc=SourceLocation())
PropertyControl getPropertyImplementation() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Kind getPropertyImplementation() const
void setSetterMethodDecl(ObjCMethodDecl *MD)
ObjCPropertyDecl * getPropertyDecl() const
void setSetterCXXAssignment(Expr *setterCXXAssignment)
static ObjCPropertyImplDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc)
void setGetterMethodDecl(ObjCMethodDecl *MD)
void setGetterCXXConstructor(Expr *getterCXXConstructor)
Represents an Objective-C protocol declaration.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
protocol_range protocols() const
The basic abstraction for the target Objective-C runtime.
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
bool allowsDirectDispatch() const
Does this runtime supports direct dispatch.
bool isFragile() const
The inverse of isNonFragile(): does this runtime follow the set of implied behaviors for a "fragile" ...
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const
Return the name of the macro defined before Loc that has spelling Tokens.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
bool isObjCGCStrong() const
true when Type is objc's strong.
bool isObjCGCWeak() const
true when Type is objc's weak.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasObjCLifetime() const
void addObjCLifetime(ObjCLifetime type)
void setObjCLifetime(ObjCLifetime type)
bool hasFlexibleArrayMember() const
Scope - A scope is a transient data structure that is used while parsing the program.
Smart pointer class that efficiently represents Objective-C method names.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl, SourceLocation AtEnd)
DefaultSynthesizeProperties - This routine default synthesizes all properties which must be synthesiz...
Definition SemaObjCProperty.cpp:1877
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
Definition SemaObjCProperty.cpp:1697
void ProcessPropertyDecl(ObjCPropertyDecl *property)
Process the specified property declaration and create decls for the setters and getters as needed.
Definition SemaObjCProperty.cpp:2365
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.
Definition SemaObjCProperty.cpp:405
void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)
Diagnose any null-resettable synthesized setters.
Definition SemaObjCProperty.cpp:2127
llvm::SmallPtrSet< Selector, 8 > SelectorSet
ObjCPropertyDecl * CreatePropertyDecl(Scope *S, ObjCContainerDecl *CDecl, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, const unsigned Attributes, const unsigned AttributesAsWritten, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
Called by ActOnProperty and HandlePropertyInClassExtension to handle creating the ObjcPropertyDecl fo...
Definition SemaObjCProperty.cpp:551
bool CheckARCMethodDecl(ObjCMethodDecl *method)
Check a method declaration for compatibility with the Objective-C ARC conventions.
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
Definition SemaObjCProperty.cpp:1825
void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D)
Definition SemaObjCProperty.cpp:2247
Decl * ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
Definition SemaObjCProperty.cpp:172
void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, bool SynthesizeProperties)
DiagnoseUnimplementedProperties - This routine warns on those properties which must be implemented by...
Definition SemaObjCProperty.cpp:2022
void AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl)
AtomicPropertySetterGetterRules - This routine enforces the rule (via warning) when atomic property h...
Definition SemaObjCProperty.cpp:2153
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 ...
Definition SemaObjCProperty.cpp:1063
void DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD)
Definition SemaObjCProperty.cpp:2307
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, unsigned &Attributes, bool propertyInPrimaryClass)
Ensure attributes are consistent with type.
Definition SemaObjCProperty.cpp:2628
void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, const IdentifierInfo *Name, bool OverridingProtocolProperty)
DiagnosePropertyMismatch - Compares two properties for their attributes and types and warns on a vari...
Definition SemaObjCProperty.cpp:1622
void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ObjCInterfaceDecl *CurrentClass, ResultTypeCompatibilityKind RTC)
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddInstanceMethodToGlobalPool - All instance methods in a translation unit are added to a global pool...
RAII object to handle the state changes required to synthesize a function body.
Sema - This implements semantic analysis and AST building for C.
bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC)
isObjCPointerConversion - Determines whether this is an Objective-C pointer conversion.
const LangOptions & getLangOpts() const
const LangOptions & LangOpts
@ AbstractSynthesizedIvarType
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
Stores token information for comparing actual tokens with predefined values.
Token - This structure provides full information about a lexed token.
SourceLocation getEndLoc() const
Get the end source location.
SourceLocation getBeginLoc() const
Get the begin source location.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
bool isBlockPointerType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isArithmeticType() const
const T * castAs() const
Member-template castAs.
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
const T * getAs() const
Member-template getAs'.
bool isObjCARCImplicitlyUnretainedType() const
Determines if this type, which must satisfy isObjCLifetimeType(), is implicitly __unsafe_unretained r...
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
void setType(QualType newType)
ObjCPropertyAttribute::Kind - list of property attributes.
@ kind_nullability
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Nullable
Values of this type can be null.
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ NonNull
Values of this type can never be null.
std::pair< FileID, unsigned > FileIDAndOffset
ObjCMethodFamily
A family of Objective-C methods.
@ Property
The type of a property.
const FunctionProtoType * T
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
This little struct is used to capture information about structure field declarators,...
A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...
Qualifiers Quals
The local qualifiers.