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
124}
125
127
128 if (S.getLangOpts().getGC() != LangOptions::NonGC) {
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);
185 }
187
189
190
193 if (ObjCCategoryDecl *CDecl = dyn_cast(ClassDecl)) {
194 if (CDecl->IsClassExtension()) {
196 FD,
199 isReadWrite, Attributes,
201 T, TSI, MethodImplKind);
202 if (!Res)
203 return nullptr;
204 }
205 }
206
207 if (!Res) {
212 MethodImplKind);
213 if (lexicalDC)
215 }
216
217
219 (isa(ClassDecl) ||
220 isa(ClassDecl)));
221
222
225
227 if (ObjCInterfaceDecl *IFace = dyn_cast(ClassDecl)) {
228
229 bool FoundInSuper = false;
235 FoundInSuper = true;
236 break;
237 }
238 CurrentInterfaceDecl = Super;
239 }
240
241 if (FoundInSuper) {
242
243 for (auto *P : CurrentInterfaceDecl->protocols()) {
245 }
246 } else {
247
248 for (auto *P : IFace->all_referenced_protocols()) {
250 }
251 }
252 } else if (ObjCCategoryDecl *Cat = dyn_cast(ClassDecl)) {
253
254
255
256 if (!Cat->IsClassExtension())
257 for (auto *P : Cat->protocols())
259 } else {
263 }
264
266 return Res;
267}
268
271 unsigned attributesAsWritten = 0;
300
302}
303
307 return false;
308
310 std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(LParenLoc);
311
312 bool invalidTemp = false;
313 StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
314 if (invalidTemp)
315 return false;
316 const char *tokenBegin = file.data() + locInfo.second;
317
318
319 Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
321 file.begin(), tokenBegin, file.end());
323 do {
325 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == attrName) {
327 return true;
328 }
329 } while (Tok.isNot(tok::r_paren));
330 return false;
331}
332
333
337 bool PropagateAtomicity) {
338
343 if (OldIsAtomic == NewIsAtomic) return;
344
345
346
348
349 auto Attrs = Property->getPropertyAttributes();
351 return false;
352
353
355 return false;
356
357
358 if (Property->getPropertyAttributesAsWritten() &
360 return false;
361
362 return true;
363 };
364
365
366
369 if (PropagateAtomicity &&
372 Attrs = Attrs & ~AtomicityMask;
373 if (OldIsAtomic)
375 else
377
379 return;
380 }
381
382
383
384 if ((OldIsAtomic && isImplicitlyReadonlyAtomic(OldProperty)) ||
385 (NewIsAtomic && isImplicitlyReadonlyAtomic(NewProperty)))
386 return;
387
388
391 if (auto Category = dyn_cast(OldDC))
392 OldContextName = Category->getClassInterface()->getIdentifier();
393 else
394 OldContextName = cast(OldDC)->getIdentifier();
395
396 S.Diag(NewProperty->getLocation(), diag::warn_property_attribute)
397 << NewProperty->getDeclName() << "atomic"
398 << OldContextName;
399 S.Diag(OldProperty->getLocation(), diag::note_property_declare);
400}
401
406 unsigned &Attributes, const unsigned AttributesAsWritten, QualType T,
409
413
414
415
416 if (!CCPrimary) {
417 Diag(CDecl->getLocation(), diag::err_continuation_class);
418 return nullptr;
419 }
420
421 bool isClassProperty =
424
425
426
429
430
431 if (PIDecl && isa(PIDecl->getDeclContext())) {
432 Diag(AtLoc, diag::err_duplicate_property);
433 Diag(PIDecl->getLocation(), diag::note_property_declare);
434 return nullptr;
435 }
436
437
438 if (PIDecl) {
439
440
441
442 if (!(PIDecl->isReadOnly() && isReadWrite)) {
443
444
445
446
447 unsigned diag =
451 ? diag::err_use_continuation_class_redeclaration_readwrite
452 : diag::err_use_continuation_class;
453 Diag(AtLoc, diag)
455 Diag(PIDecl->getLocation(), diag::note_property_declare);
456 return nullptr;
457 }
458
459
461
463 Diag(AtLoc, diag::warn_property_redecl_getter_mismatch)
465 Diag(PIDecl->getLocation(), diag::note_property_declare);
466 }
467
468
471 }
472
473
474 unsigned ExistingOwnership
477 if (ExistingOwnership && NewOwnership != ExistingOwnership) {
478
480 Diag(AtLoc, diag::warn_property_attr_mismatch);
481 Diag(PIDecl->getLocation(), diag::note_property_declare);
482 }
483
484
485 Attributes = (Attributes & ~OwnershipMask) | ExistingOwnership;
486 }
487
488
494 Diag(AtLoc, diag::warn_property_implicitly_mismatched);
495 Diag(PIDecl->getLocation(), diag::note_property_declare);
496 }
497 }
498
499
500
502 FD, GetterSel, GetterNameLoc,
503 SetterSel, SetterNameLoc,
504 isReadWrite,
505 Attributes, AttributesAsWritten,
506 T, TSI, MethodImplKind, DC);
508
509
510 if (!PIDecl) {
512 return PDecl;
513 }
514
516 bool IncompatibleObjC = false;
518
519
520
521
522
523
526 if (!isa(PrimaryClassPropertyT) ||
527 !isa(ClassExtPropertyT) ||
529 PrimaryClassPropertyT, ConvertedType,
530 IncompatibleObjC)) ||
531 IncompatibleObjC) {
533 diag::err_type_mismatch_continuation_class) << PDecl->getType();
534 Diag(PIDecl->getLocation(), diag::note_property_declare);
535 return nullptr;
536 }
537 }
538
539
540
542
543
545 return PDecl;
546}
547
552 SourceLocation SetterNameLoc, const bool isReadWrite,
553 const unsigned Attributes, const unsigned AttributesAsWritten, QualType T,
558
559
560
561 bool isAssign;
564 isAssign = true;
566 isAssign = false;
567 } else {
568 isAssign = (().ObjCAutoRefCount ||
570 }
571
572
573
578 ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
579 if (IDecl)
583 Diag(AtLoc, diag::warn_implements_nscopying) << PropertyId;
584 }
585 }
586
595 }
596
600 PropertyId, AtLoc,
601 LParenLoc, T, TInfo);
602
603 bool isClassProperty =
606
609 Diag(PDecl->getLocation(), diag::err_duplicate_property);
610 Diag(prevDecl->getLocation(), diag::note_property_declare);
612 }
613 else {
615 if (lexicalDC)
617 }
618
620 Diag(AtLoc, diag::err_property_type) << T;
622 }
623
624
625
630
632
635
638
641
642 if (isReadWrite)
644
647
650
653
656
659
660 if (isAssign)
662
663
666 else
668
669
672 if (isAssign)
674
675 if (MethodImplKind == tok::objc_required)
677 else if (MethodImplKind == tok::objc_optional)
679
682
685
688
690 CDecl->hasAttr()) {
691 if (isa(CDecl)) {
692 Diag(PDecl->getLocation(), diag::err_objc_direct_on_protocol) << true;
695 } else {
696 Diag(PDecl->getLocation(), diag::warn_objc_direct_property_ignored)
698 }
699 }
700
701 return PDecl;
702}
703
708
711
712
716
717
718 if (propertyLifetime == ivarLifetime) return;
719
720
721
725 return;
726
727
728
729
730
740 return;
741 }
742 }
743
744 switch (propertyLifetime) {
746 S.Diag(ivar->getLocation(), diag::err_arc_strong_property_ownership)
747 << property->getDeclName()
749 << ivarLifetime;
750 break;
751
754 << property->getDeclName()
756 break;
757
759 S.Diag(ivar->getLocation(), diag::err_arc_assign_property_ownership)
760 << property->getDeclName() << ivar->getDeclName()
761 << ((property->getPropertyAttributesAsWritten() &
763 break;
764
766 llvm_unreachable("properties cannot be autoreleasing");
767
769
770 return;
771 }
772
773 S.Diag(property->getLocation(), diag::note_property_declare);
774 if (propertyImplLoc.isValid())
775 S.Diag(propertyImplLoc, diag::note_property_synthesize);
776}
777
778
779
780
781
782
789 return;
790
791 if (!ivar) {
792
794 return;
795 }
796
803}
804
807 return (Attr1 & Kind) != (Attr2 & Kind);
808}
809
811 unsigned Kinds) {
812 return ((Attr1 & Kinds) != 0) != ((Attr2 & Kinds) != 0);
813}
814
815
816
817
818
819
824 assert(isa(Property->getDeclContext()) &&
825 "Expected a property from a protocol");
830 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
831 Properties);
832 }
834 while (SDecl) {
835 for (const auto *PI : SDecl->all_referenced_protocols()) {
837 PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
838 Properties);
839 }
840 SDecl = SDecl->getSuperClass();
841 }
842 }
843
844 if (Properties.empty())
846
848 size_t SelectedIndex = 0;
849 for (const auto &Prop : llvm::enumerate(Properties)) {
850
851 if (Property->isReadOnly() && !Prop.value()->isReadOnly()) {
853 SelectedIndex = Prop.index();
854 }
855 }
856 if (Property != OriginalProperty) {
857
858 Properties[SelectedIndex] = OriginalProperty;
859 }
860
862 unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
863 enum MismatchKind {
864 IncompatibleType = 0,
865 HasNoExpectedAttribute,
866 HasUnexpectedAttribute,
867 DifferentGetter,
868 DifferentSetter
869 };
870
871
872 struct MismatchingProperty {
874 MismatchKind Kind;
875 StringRef AttributeName;
876 };
879
880 unsigned Attr = Prop->getPropertyAttributesAsWritten();
881 if (Attr != OriginalAttributes) {
882 auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {
883 MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
884 : HasUnexpectedAttribute;
885 Mismatches.push_back({Prop, Kind, AttributeName});
886 };
887
888
889 bool HasOwnership =
896 if (HasOwnership &&
900 continue;
901 }
903 OriginalAttributes, Attr,
908 "retain (or strong)");
909 continue;
910 }
914 continue;
915 }
916 }
917 if (Property->getGetterName() != Prop->getGetterName()) {
918 Mismatches.push_back({Prop, DifferentGetter, ""});
919 continue;
920 }
921 if (->isReadOnly() && !Prop->isReadOnly() &&
922 Property->getSetterName() != Prop->getSetterName()) {
923 Mismatches.push_back({Prop, DifferentSetter, ""});
924 continue;
925 }
928 bool IncompatibleObjC = false;
931 || IncompatibleObjC) {
932 Mismatches.push_back({Prop, IncompatibleType, ""});
933 continue;
934 }
935 }
936 }
937
938 if (Mismatches.empty())
940
941
942 {
943 bool HasIncompatibleAttributes = false;
944 for (const auto &Note : Mismatches)
945 HasIncompatibleAttributes =
946 Note.Kind != IncompatibleType ? true : HasIncompatibleAttributes;
947
948
950 Property != OriginalProperty || HasIncompatibleAttributes
951 ? diag::err_protocol_property_mismatch
952 : diag::warn_protocol_property_mismatch);
953 Diag << Mismatches[0].Kind;
954 switch (Mismatches[0].Kind) {
955 case IncompatibleType:
957 break;
958 case HasNoExpectedAttribute:
959 case HasUnexpectedAttribute:
960 Diag << Mismatches[0].AttributeName;
961 break;
962 case DifferentGetter:
964 break;
965 case DifferentSetter:
967 break;
968 }
969 }
970 for (const auto &Note : Mismatches) {
972 S.Diag(Note.Prop->getLocation(), diag::note_protocol_property_declare)
973 << Note.Kind;
974 switch (Note.Kind) {
975 case IncompatibleType:
976 Diag << Note.Prop->getType();
977 break;
978 case HasNoExpectedAttribute:
979 case HasUnexpectedAttribute:
981 break;
982 case DifferentGetter:
983 Diag << Note.Prop->getGetterName();
984 break;
985 case DifferentSetter:
986 Diag << Note.Prop->getSetterName();
987 break;
988 }
989 }
991 S.Diag(AtLoc, diag::note_property_synthesize);
992
994}
995
996
1000
1001
1002
1003
1004
1005
1006 if (Prop->isReadOnly()) return false;
1007
1008
1010 if ( ||
->IsClassExtension()) return false;
1011
1012
1013 auto OrigClass = Category->getClassInterface();
1014 for (auto *Found : OrigClass->lookup(Prop->getDeclName())) {
1016 return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;
1017 }
1018
1019
1020 for (const auto *Proto : OrigClass->all_referenced_protocols()) {
1021 if (ObjCPropertyDecl *OrigProp = Proto->FindPropertyDeclaration(
1023 return OrigProp->getPropertyAttributesAsWritten() & OwnershipMask;
1024 }
1025
1026 return false;
1027}
1028
1029
1038 Decl->getSelector(), Decl->getReturnType(),
1039 Decl->getReturnTypeSourceInfo(), Impl, Decl->isInstanceMethod(),
1040 Decl->isVariadic(), Decl->isPropertyAccessor(),
1042 Decl->getImplementationControl(), Decl->hasRelatedResultType());
1049 Decl->getSelectorLocs(SelLocs);
1053 return ImplDecl;
1054}
1055
1056
1057
1058
1059
1067
1068 if (!ClassImpDecl) {
1069 Diag(AtLoc, diag::err_missing_property_context);
1070 return nullptr;
1071 }
1072 if (PropertyIvarLoc.isInvalid())
1073 PropertyIvarLoc = PropertyLoc;
1075 if (PropertyDiagLoc.isInvalid())
1076 PropertyDiagLoc = ClassImpDecl->getBeginLoc();
1079
1080
1083 if ((IC = dyn_cast(ClassImpDecl))) {
1085
1086
1087 assert(IDecl &&
1088 "ActOnPropertyImplDecl - @implementation without @interface");
1089
1090
1092 if (!property) {
1093 Diag(PropertyLoc, diag::err_bad_property_decl) << IDecl->getDeclName();
1094 return nullptr;
1095 }
1096 if (property->isClassProperty() && Synthesize) {
1097 Diag(PropertyLoc, diag::err_synthesize_on_class_property) << PropertyId;
1098 return nullptr;
1099 }
1100 unsigned PIkind = property->getPropertyAttributesAsWritten();
1104 Diag(AtLoc, diag::warn_implicit_atomic_property);
1105 else
1106 Diag(IC->getLocation(), diag::warn_auto_implicit_atomic_property);
1107 Diag(property->getLocation(), diag::note_property_declare);
1108 }
1109
1111 dyn_cast(property->getDeclContext())) {
1112 if (!CD->IsClassExtension()) {
1113 Diag(PropertyLoc, diag::err_category_property) << CD->getDeclName();
1114 Diag(property->getLocation(), diag::note_property_declare);
1115 return nullptr;
1116 }
1117 }
1119 property->hasAttr() && !AtLoc.isValid()) {
1120 bool ReadWriteProperty = false;
1121
1122
1126 PIkind = ExtProp->getPropertyAttributesAsWritten();
1128 ReadWriteProperty = true;
1129 break;
1130 }
1131 }
1132 }
1133
1134 if (!ReadWriteProperty) {
1135 Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property)
1136 << property;
1139 property->getLParenLoc(), readonlyLoc)) {
1142 SourceRange ReadonlySourceRange(readonlyLoc, endLoc);
1143 Diag(property->getLocation(),
1144 diag::note_auto_readonly_iboutlet_fixup_suggest) <<
1146 }
1147 }
1148 }
1149 if (Synthesize && isa(property->getDeclContext()))
1151 property);
1152
1153 } else if ((CatImplClass = dyn_cast(ClassImpDecl))) {
1154 if (Synthesize) {
1155 Diag(AtLoc, diag::err_synthesize_category_decl);
1156 return nullptr;
1157 }
1159 if (!IDecl) {
1160 Diag(AtLoc, diag::err_missing_property_interface);
1161 return nullptr;
1162 }
1165
1166
1167
1169 return nullptr;
1170
1171 property = Category->FindPropertyDeclaration(PropertyId, QueryKind);
1172 if (!property) {
1173 Diag(PropertyLoc, diag::err_bad_category_property_decl)
1175 return nullptr;
1176 }
1177 } else {
1178 Diag(AtLoc, diag::err_bad_property_context);
1179 return nullptr;
1180 }
1182 bool CompleteTypeErr = false;
1183 bool compat = true;
1184
1185 if (Synthesize) {
1186
1187 if (!PropertyIvar)
1188 PropertyIvar = PropertyId;
1189
1192 QualType PropType = property->getType();
1194
1196 diag::err_incomplete_synthesized_property,
1197 property->getDeclName())) {
1198 Diag(property->getLocation(), diag::note_property_declare);
1199 CompleteTypeErr = true;
1200 }
1201
1203 (property->getPropertyAttributesAsWritten() &
1207 }
1208
1210
1211 bool isARCWeak = false;
1213
1215 assert(().ObjCAutoRefCount);
1217 Diag(PropertyDiagLoc, diag::err_gc_weak_property_strong_type);
1218 Diag(property->getLocation(), diag::note_property_declare);
1219 } else {
1220 PropertyIvarType =
1222 }
1223
1224
1225
1226 } else {
1228
1229 if (!Ivar) {
1230 Diag(PropertyDiagLoc,
1232 ? diag::err_synthesizing_arc_weak_property_disabled
1233 : diag::err_synthesizing_arc_weak_property_no_runtime);
1234 Diag(property->getLocation(), diag::note_property_declare);
1235 }
1236 CompleteTypeErr = true;
1237 } else {
1238 isARCWeak = true;
1243 Diag(property->getLocation(),
1244 diag::err_arc_weak_unavailable_property)
1245 << PropertyIvarType;
1246 Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class)
1247 << ClassImpDecl->getName();
1248 }
1249 }
1250 }
1251 }
1252 }
1253
1255
1256
1257
1258
1262 ClassDeclared);
1263 if (originalIvar) {
1264 Diag(PropertyDiagLoc,
1265 diag::warn_autosynthesis_property_ivar_match)
1266 << PropertyId << (Ivar == nullptr) << PropertyIvar
1268 Diag(property->getLocation(), diag::note_property_declare);
1269 Diag(originalIvar->getLocation(), diag::note_ivar_decl);
1270 }
1271 }
1272
1273 if (!Ivar) {
1274
1275
1276 if ((getLangOpts().ObjCAutoRefCount || isARCWeak) &&
1279
1280
1281
1284 Diag(PropertyDiagLoc,
1285 diag::err_arc_objc_property_default_assign_on_object);
1286 Diag(property->getLocation(), diag::note_property_declare);
1287 } else {
1290 assert(lifetime && "no lifetime for property?");
1291
1294 PropertyIvarType = Context.getQualifiedType(PropertyIvarType, qs);
1295 }
1296 }
1297
1299 PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,
1300 PropertyIvarType, nullptr,
1302 (Expr *)nullptr, true);
1304 diag::err_abstract_type_in_decl,
1306 Diag(property->getLocation(), diag::note_property_declare);
1307
1308 CompleteTypeErr = true;
1309 }
1310 if (!CompleteTypeErr) {
1313 Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)
1314 << PropertyIvarType;
1315 CompleteTypeErr = true;
1316 }
1317 }
1318 if (CompleteTypeErr)
1320 ClassImpDecl->addDecl(Ivar);
1322
1324 Diag(PropertyDiagLoc, diag::err_missing_property_ivar_decl)
1325 << PropertyId;
1326
1327
1330 Diag(PropertyDiagLoc, diag::err_ivar_in_superclass_use)
1331 << property->getDeclName() << Ivar->getDeclName()
1333 Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
1334 << Ivar << Ivar->getName();
1335
1336 }
1337 property->setPropertyIvarDecl(Ivar);
1338
1340
1341
1342 if (!Context.hasSameType(PropertyIvarType, IvarType)) {
1343 if (isa(PropertyIvarType)
1344 && isa(IvarType))
1348 else {
1350 PropertyIvarLoc, PropertyIvarType, IvarType) ==
1352 }
1353 if (!compat) {
1354 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1355 << property->getDeclName() << PropType
1358
1359
1360 }
1361 else {
1362
1363
1364
1367 if (lhsType != rhsType &&
1369 Diag(PropertyDiagLoc, diag::err_property_ivar_type)
1370 << property->getDeclName() << PropType
1373
1374 }
1375 }
1376
1379 Diag(PropertyDiagLoc, diag::err_weak_property)
1380 << property->getDeclName() << Ivar->getDeclName();
1382
1383 }
1384
1385 if ((property->getType()->isObjCObjectPointerType() ||
1388 Diag(PropertyDiagLoc, diag::err_strong_property)
1389 << property->getDeclName() << Ivar->getDeclName();
1390
1391 }
1392 }
1393 if (getLangOpts().ObjCAutoRefCount || isARCWeak ||
1396 } else if (PropertyIvar)
1397
1398 Diag(PropertyDiagLoc, diag::err_dynamic_property_ivar_decl);
1399
1400 assert (property && "ActOnPropertyImplDecl - property declaration missing");
1405 Ivar, PropertyIvarLoc);
1406
1407 if (CompleteTypeErr || !compat)
1409
1410 if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
1411 getterMethod->createImplicitParams(Context, IDecl);
1412
1413
1414 if (Synthesize) {
1415
1417 getterMethod->getSelector(), getterMethod->isInstanceMethod());
1418 if (!OMD)
1420 PropertyLoc);
1422 }
1423
1426
1427
1428
1433 PropertyDiagLoc);
1436 Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,
1438 Expr *IvarRefExpr =
1441 PropertyDiagLoc,
1443 LoadSelfExpr, true, true);
1446 getterMethod->getReturnType()),
1447 PropertyDiagLoc, IvarRefExpr);
1450 if (ResExpr)
1453 }
1454 }
1455 if (property->hasAttr() &&
1456 !getterMethod->hasAttr()) {
1457 Diag(getterMethod->getLocation(),
1458 diag::warn_property_getter_owning_mismatch);
1459 Diag(property->getLocation(), diag::note_property_declare);
1460 }
1461 if (getLangOpts().ObjCAutoRefCount && Synthesize)
1462 switch (getterMethod->getMethodFamily()) {
1467 Diag(getterMethod->getLocation(), diag::err_arc_illegal_method_def)
1468 << 1 << getterMethod->getSelector();
1469 break;
1470 default:
1471 break;
1472 }
1473 }
1474
1475 if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
1476 setterMethod->createImplicitParams(Context, IDecl);
1477
1478
1479 if (Synthesize) {
1481 setterMethod->getSelector(), setterMethod->isInstanceMethod());
1482 if (!OMD)
1484 AtLoc, PropertyLoc);
1486 }
1487
1490
1495 PropertyDiagLoc);
1498 Context, SelfDecl->getType(), CK_LValueToRValue, SelfExpr, nullptr,
1503 PropertyDiagLoc,
1505 LoadSelfExpr, true, true);
1514 if (property->getPropertyAttributes() &
1518 dyn_cast_or_null(callExpr))
1519 if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
1520 if (!FuncDecl->isTrivial())
1521 if (property->getType()->isReferenceType()) {
1522 Diag(PropertyDiagLoc,
1523 diag::err_atomic_property_nontrivial_assign_op)
1524 << property->getType();
1525 Diag(FuncDecl->getBeginLoc(), diag::note_callee_decl)
1526 << FuncDecl;
1527 }
1528 }
1530 }
1531 }
1532
1533 if (IC) {
1534 if (Synthesize)
1537 Diag(PropertyLoc, diag::err_duplicate_ivar_use)
1538 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1539 << PropertyIvar;
1540 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1541 }
1542
1545 Diag(PropertyLoc, diag::err_property_implemented) << PropertyId;
1546 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1547 return nullptr;
1548 }
1550 if (getLangOpts().ObjCDefaultSynthProperties &&
1553
1554
1555
1558 if (!Synthesize)
1560 else {
1561 if (PropertyIvar && PropertyIvar != PropertyId)
1563 }
1564
1568 << PropertyId;
1570 }
1571 }
1572 } else {
1573 if (Synthesize)
1576 Diag(PropertyDiagLoc, diag::err_duplicate_ivar_use)
1577 << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
1578 << PropertyIvar;
1579 Diag(PPIDecl->getLocation(), diag::note_previous_use);
1580 }
1581
1584 Diag(PropertyDiagLoc, diag::err_property_implemented) << PropertyId;
1585 Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
1586 return nullptr;
1587 }
1589 }
1590
1594 Diag(PropertyLoc, diag::err_objc_direct_dynamic_property);
1596 diag::note_previous_declaration);
1597 return nullptr;
1598 }
1599
1600 return PIDecl;
1601}
1602
1603
1604
1605
1606
1607
1608
1609
1613 bool OverridingProtocolProperty) {
1617
1618
1619
1620
1621 if (!OverridingProtocolProperty &&
1623 ;
1624 else {
1627 Diag(Property->getLocation(), diag::warn_readonly_property)
1628 << Property->getDeclName() << inheritedName;
1631 Diag(Property->getLocation(), diag::warn_property_attribute)
1632 << Property->getDeclName() << "copy" << inheritedName;
1638 bool CStrong = (CAttrRetain != 0);
1639 bool SStrong = (SAttrRetain != 0);
1640 if (CStrong != SStrong)
1641 Diag(Property->getLocation(), diag::warn_property_attribute)
1642 << Property->getDeclName() << "retain (or strong)" << inheritedName;
1643 }
1644 }
1645
1646
1647
1648
1650
1651
1654 isa(SuperProperty->getDeclContext()))) {
1655 Diag(Property->getLocation(), diag::warn_property_attribute)
1656 << Property->getDeclName() << "setter" << inheritedName;
1657 Diag(SuperProperty->getLocation(), diag::note_property_declare);
1658 }
1660 Diag(Property->getLocation(), diag::warn_property_attribute)
1661 << Property->getDeclName() << "getter" << inheritedName;
1662 Diag(SuperProperty->getLocation(), diag::note_property_declare);
1663 }
1664
1669
1671
1672
1673 bool IncompatibleObjC = false;
1676 IncompatibleObjC) ||
1677 IncompatibleObjC) {
1678 Diag(Property->getLocation(), diag::warn_property_types_are_incompatible)
1679 << Property->getType() << SuperProperty->getType() << inheritedName;
1680 Diag(SuperProperty->getLocation(), diag::note_property_declare);
1681 }
1682 }
1683}
1684
1689 if (!GetterMethod)
1690 return false;
1692 QualType PropertyRValueType =
1693 property->getType().getNonReferenceType().getAtomicUnqualifiedType();
1694 bool compat = Context.hasSameType(PropertyRValueType, GetterType);
1695 if (!compat) {
1698 if ((propertyObjCPtr =
1704 Diag(Loc, diag::err_property_accessor_type)
1705 << property->getDeclName() << PropertyRValueType
1706 << GetterMethod->getSelector() << GetterType;
1707 Diag(GetterMethod->getLocation(), diag::note_declared_at);
1708 return true;
1709 } else {
1710 compat = true;
1714 compat = false;
1715 }
1716 }
1717
1718 if (!compat) {
1719 Diag(Loc, diag::warn_accessor_property_type_mismatch)
1720 << property->getDeclName()
1722 Diag(GetterMethod->getLocation(), diag::note_declared_at);
1723 return true;
1724 }
1725
1726 return false;
1727}
1728
1729
1730
1731static void
1735 bool CollectClassPropsOnly = false,
1736 bool IncludeProtocols = true) {
1737 if (ObjCInterfaceDecl *IDecl = dyn_cast(CDecl)) {
1738 for (auto *Prop : IDecl->properties()) {
1739 if (CollectClassPropsOnly && !Prop->isClassProperty())
1740 continue;
1741 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1742 Prop;
1743 }
1744
1745
1746 for (auto *Ext : IDecl->visible_extensions())
1748 CollectClassPropsOnly, IncludeProtocols);
1749
1750 if (IncludeProtocols) {
1751
1752 for (auto *PI : IDecl->all_referenced_protocols())
1754 CollectClassPropsOnly);
1755 }
1756 }
1757 if (ObjCCategoryDecl *CATDecl = dyn_cast(CDecl)) {
1758 for (auto *Prop : CATDecl->properties()) {
1759 if (CollectClassPropsOnly && !Prop->isClassProperty())
1760 continue;
1761 PropMap[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] =
1762 Prop;
1763 }
1764 if (IncludeProtocols) {
1765
1766 for (auto *PI : CATDecl->protocols())
1768 CollectClassPropsOnly);
1769 }
1770 }
1771 else if (ObjCProtocolDecl *PDecl = dyn_cast(CDecl)) {
1772 for (auto *Prop : PDecl->properties()) {
1773 if (CollectClassPropsOnly && !Prop->isClassProperty())
1774 continue;
1776 SuperPropMap[std::make_pair(Prop->getIdentifier(),
1777 Prop->isClassProperty())];
1778
1779
1780 if (!PropertyFromSuper ||
1781 PropertyFromSuper->getIdentifier() != Prop->getIdentifier()) {
1783 PropMap[std::make_pair(Prop->getIdentifier(),
1784 Prop->isClassProperty())];
1785 if (!PropEntry)
1786 PropEntry = Prop;
1787 }
1788 }
1789
1790 for (auto *PI : PDecl->protocols())
1792 CollectClassPropsOnly);
1793 }
1794}
1795
1796
1797
1798
1802 while (SDecl) {
1803 SDecl->collectPropertiesToImplement(PropMap);
1804 SDecl = SDecl->getSuperClass();
1805 }
1806 }
1807}
1808
1809
1810
1811
1816 return false;
1820 return false;
1821
1822
1823
1827 (Property->getPropertyIvarDecl() == IV))
1828 return true;
1829 }
1830
1831
1833 for (const auto *Property : Ext->instance_properties())
1836 (Property->getPropertyIvarDecl() == IV))
1837 return true;
1838 return false;
1839}
1840
1843 bool SuperClassImplementsGetter = false;
1844 bool SuperClassImplementsSetter = false;
1846 SuperClassImplementsSetter = true;
1847
1851 SuperClassImplementsGetter = true;
1852
1854 SuperClassImplementsSetter = true;
1855 if (SuperClassImplementsGetter && SuperClassImplementsSetter)
1856 return true;
1858 }
1859 return false;
1860}
1861
1862
1863
1870 if (PropMap.empty())
1871 return;
1874
1875 for (const auto &PropEntry : PropMap) {
1877
1881 continue;
1882
1885 continue;
1887 if (ImpMethod && !ImpMethod->getBody()) {
1889 continue;
1891 if (ImpMethod && !ImpMethod->getBody())
1892 continue;
1893 }
1896 Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
1898 if (PID->getLocation().isValid())
1899 Diag(PID->getLocation(), diag::note_property_synthesize);
1900 continue;
1901 }
1903 SuperPropMap[std::make_pair(Prop->getIdentifier(),
1906 dyn_cast(Prop->getDeclContext())) {
1907
1908
1909
1910
1913 diag::warn_auto_synthesizing_protocol_property)
1914 << Prop << Proto;
1916 std::string FixIt =
1917 (Twine("@synthesize ") + Prop->getName() + ";\n\n").str();
1918 Diag(AtEnd, diag::note_add_synthesize_directive)
1920 }
1921 continue;
1922 }
1923
1924 if (PropInSuperClass) {
1931 Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
1933 Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
1934 } else {
1935 Diag(Prop->getLocation(), diag::warn_autosynthesis_property_in_superclass)
1937 Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
1938 Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
1939 }
1940 continue;
1941 }
1942
1943
1944
1945
1948 true,
1953 Diag(Prop->getLocation(), diag::warn_missing_explicit_synthesis);
1954 Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
1955 }
1956 }
1957}
1958
1961 if (().ObjCDefaultSynthProperties ||
1963 return;
1965 if (!IC)
1966 return;
1968 if (!IDecl->isObjCRequiresPropertyDefs())
1970}
1971
1977
1978
1982 });
1983
1984
1985
1986
1987 if (I == SMap.end() &&
1988 (PrimaryClass == nullptr ||
1991 unsigned diag =
1992 isa(CDecl)
1994 ? diag::warn_impl_required_in_category_for_class_property
1995 : diag::warn_setter_getter_impl_required_in_category)
1997 ? diag::warn_impl_required_for_class_property
1998 : diag::warn_setter_getter_impl_required);
2000 S.Diag(Prop->getLocation(), diag::note_property_declare);
2001 if (S.LangOpts.ObjCDefaultSynthProperties &&
2004 if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs())
2005 S.Diag(RID->getLocation(), diag::note_suppressed_class_declare);
2006 }
2007}
2008
2011 bool SynthesizeProperties) {
2014
2015
2016
2018
2019
2020 if (!IDecl)
2022
2023
2024
2025 if ((IDecl = C->getClassInterface())) {
2027 }
2028 }
2029 if (IDecl)
2031
2032
2034 SynthesizeProperties);
2035
2036
2037
2038
2039 if (IDecl) {
2040 std::unique_ptrObjCContainerDecl::PropertyMap LazyMap;
2041
2043 if (!PDecl->hasAttr())
2044 continue;
2045
2046
2047
2048
2049
2050
2051
2052 if (!LazyMap) {
2056 false,
2057 false);
2058 }
2059
2060
2061 for (auto *PropDecl : PDecl->properties()) {
2062 if ((*LazyMap)[std::make_pair(PropDecl->getIdentifier(),
2063 PropDecl->isClassProperty())])
2064 continue;
2065 PropMap[std::make_pair(PropDecl->getIdentifier(),
2066 PropDecl->isClassProperty())] = PropDecl;
2067 }
2068 }
2069 }
2070
2071 if (PropMap.empty())
2072 return;
2073
2074 llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;
2076 PropImplMap.insert(I->getPropertyDecl());
2077
2079
2080 for (const auto *I : IMPDecl->methods())
2081 InsMap.insert(I);
2082
2085 if (C && ->IsClassExtension())
2086 if ((PrimaryClass = C->getClassInterface()))
2087
2089
2090
2091
2092 for (const auto *I : IMP->methods())
2093 InsMap.insert(I);
2094 }
2095
2096 for (ObjCContainerDecl::PropertyMap::iterator
2097 P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
2099
2102 PropImplMap.count(Prop) ||
2104 continue;
2105
2106
2108 IMPDecl, CDecl, C, Prop, InsMap);
2112 Prop, InsMap);
2113 }
2114}
2115
2118 for (const auto *propertyImpl : impDecl->property_impls()) {
2119 const auto *property = propertyImpl->getPropertyDecl();
2120
2121
2122 if (propertyImpl->getPropertyImplementation() ==
2124 (property->getPropertyAttributes() &
2126 property->getGetterMethodDecl() && property->getSetterMethodDecl()) {
2127 auto *getterImpl = propertyImpl->getGetterMethodDecl();
2128 auto *setterImpl = propertyImpl->getSetterMethodDecl();
2129 if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) &&
2130 (!setterImpl || setterImpl->isSynthesizedAccessorStub())) {
2134
2135 Diag(loc, diag::warn_null_resettable_setter)
2136 << setterImpl->getSelector() << property->getDeclName();
2137 }
2138 }
2139 }
2140}
2141
2144
2146 return;
2148 for (auto *Prop : IDecl->properties())
2149 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2151 for (auto *Prop : Ext->properties())
2152 PM[std::make_pair(Prop->getIdentifier(), Prop->isClassProperty())] = Prop;
2153
2154 for (ObjCContainerDecl::PropertyMap::iterator I = PM.begin(), E = PM.end();
2155 I != E; ++I) {
2159
2160 unsigned Attributes = Property->getPropertyAttributes();
2161 unsigned AttributesAsWritten = Property->getPropertyAttributesAsWritten();
2162
2165 GetterMethod = Property->isClassProperty() ?
2168 SetterMethod = Property->isClassProperty() ?
2172 GetterMethod = nullptr;
2174 SetterMethod = nullptr;
2175 if (GetterMethod) {
2177 diag::warn_default_atomic_custom_getter_setter)
2178 << Property->getIdentifier() << 0;
2179 Diag(Property->getLocation(), diag::note_property_declare);
2180 }
2181 if (SetterMethod) {
2183 diag::warn_default_atomic_custom_getter_setter)
2184 << Property->getIdentifier() << 1;
2185 Diag(Property->getLocation(), diag::note_property_declare);
2186 }
2187 }
2188
2189
2192 continue;
2196 continue;
2197 GetterMethod = PIDecl->getGetterMethodDecl();
2198 SetterMethod = PIDecl->getSetterMethodDecl();
2200 GetterMethod = nullptr;
2202 SetterMethod = nullptr;
2203 if ((bool)GetterMethod ^ (bool)SetterMethod) {
2205 (GetterMethod ? GetterMethod->getLocation()
2206 : SetterMethod->getLocation());
2207 Diag(MethodLoc, diag::warn_atomic_property_rule)
2208 << Property->getIdentifier() << (GetterMethod != nullptr)
2209 << (SetterMethod != nullptr);
2210
2211 if (Property->getLParenLoc().isValid() &&
2213
2216 StringRef NonatomicStr = AttributesAsWritten? "nonatomic, "
2217 : "nonatomic";
2219 diag::note_atomic_property_fixup_suggest)
2221 } else if (Property->getLParenLoc().isInvalid()) {
2222
2224 Property->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
2226 diag::note_atomic_property_fixup_suggest)
2228 } else
2229 Diag(MethodLoc, diag::note_atomic_property_fixup_suggest);
2230 Diag(Property->getLocation(), diag::note_property_declare);
2231 }
2232 }
2233 }
2234}
2235
2239 return;
2240
2241 for (const auto *PID : D->property_impls()) {
2243 if (PD && !PD->hasAttr() &&
2247 continue;
2249 if (!method)
2250 continue;
2255 Diag(PD->getLocation(), diag::err_cocoa_naming_owned_rule);
2256 else
2257 Diag(PD->getLocation(), diag::warn_cocoa_naming_owned_rule);
2258
2259
2260
2263 for (auto *getterRedecl : method->redecls()) {
2264 if (getterRedecl->isImplicit())
2265 continue;
2266 if (getterRedecl->getDeclContext() != PD->getDeclContext())
2267 continue;
2268 noteLoc = getterRedecl->getLocation();
2269 fixItLoc = getterRedecl->getEndLoc();
2270 }
2271
2274 tok::kw___attribute, tok::l_paren, tok::l_paren,
2277 tok::r_paren, tok::r_paren
2278 };
2279 StringRef spelling = "__attribute__((objc_method_family(none)))";
2281 if (!macroName.empty())
2282 spelling = macroName;
2283
2284 auto noteDiag = Diag(noteLoc, diag::note_cocoa_naming_declare_family)
2286 if (fixItLoc.isValid()) {
2288 fixItText += spelling;
2290 }
2291 }
2292 }
2293 }
2294}
2295
2300 if (!SuperD)
2301 return;
2302
2305 if (I->getMethodFamily() == OMF_init)
2306 InitSelSet.insert(I->getSelector());
2307
2311 I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
2313 if (!InitSelSet.count(MD->getSelector())) {
2314
2315
2316 bool Ignore = false;
2319 } else {
2320
2322 if (auto *IMD = Ext->getInstanceMethod(MD->getSelector())) {
2323 Ignore = IMD->isUnavailable();
2324 break;
2325 }
2326 }
2327 if (!Ignore) {
2329 diag::warn_objc_implementation_missing_designated_init_override)
2331 Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here);
2332 }
2333 }
2334 }
2335}
2336
2337
2338
2341
2342 for (const auto *A : Property->attrs()) {
2343 if (isa(A) ||
2344 isa(A) ||
2345 isa(A))
2347 }
2348}
2349
2350
2351
2352
2353
2359 return;
2360
2361 bool IsClassProperty = property->isClassProperty();
2362 GetterMethod = IsClassProperty ?
2365
2366
2367
2368 if (!GetterMethod)
2369 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD))
2370 if (CatDecl->IsClassExtension())
2373 CatDecl->getClassInterface()->
2375
2376 SetterMethod = IsClassProperty ?
2379 if (!SetterMethod)
2380 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD))
2381 if (CatDecl->IsClassExtension())
2384 CatDecl->getClassInterface()->
2388
2389
2390
2391 if (!GetterMethod) {
2392 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD)) {
2393 auto *ExistingGetter = CatDecl->getClassInterface()->lookupMethod(
2394 property->getGetterName(), !IsClassProperty, true, false, CatDecl);
2395 if (ExistingGetter) {
2396 if (ExistingGetter->isDirectMethod() || property->isDirectProperty()) {
2397 Diag(property->getLocation(), diag::err_objc_direct_duplicate_decl)
2398 << property->isDirectProperty() << 1
2399 << ExistingGetter->isDirectMethod()
2400 << ExistingGetter->getDeclName();
2401 Diag(ExistingGetter->getLocation(), diag::note_previous_declaration);
2402 }
2403 }
2404 }
2405 }
2406
2407 if (!property->isReadOnly() && !SetterMethod) {
2408 if (const ObjCCategoryDecl *CatDecl = dyn_cast(CD)) {
2409 auto *ExistingSetter = CatDecl->getClassInterface()->lookupMethod(
2410 property->getSetterName(), !IsClassProperty, true, false, CatDecl);
2411 if (ExistingSetter) {
2412 if (ExistingSetter->isDirectMethod() || property->isDirectProperty()) {
2413 Diag(property->getLocation(), diag::err_objc_direct_duplicate_decl)
2414 << property->isDirectProperty() << 1
2415 << ExistingSetter->isDirectMethod()
2416 << ExistingSetter->getDeclName();
2417 Diag(ExistingSetter->getLocation(), diag::note_previous_declaration);
2418 }
2419 }
2420 }
2421 }
2422
2423 if (!property->isReadOnly() && SetterMethod) {
2426 Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
2427 if (SetterMethod->param_size() != 1 ||
2429 (*SetterMethod->param_begin())->getType().getNonReferenceType(),
2432 diag::warn_accessor_property_type_mismatch)
2433 << property->getDeclName()
2435 Diag(SetterMethod->getLocation(), diag::note_declared_at);
2436 }
2437 }
2438
2439
2440
2441
2442
2443
2444
2445 if (!GetterMethod) {
2446
2447
2448
2450
2451
2452
2453 QualType resultTy = property->getType().getAtomicUnqualifiedType();
2454
2455
2458 QualType modifiedTy = resultTy;
2462 modifiedTy, modifiedTy);
2463 }
2464 }
2465
2468 !IsClassProperty, false,
2469 true, false,
2470 true, false,
2474 CD->addDecl(GetterMethod);
2475
2477
2479 GetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2480
2481 if (property->hasAttr())
2482 GetterMethod->addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context,
2484
2485 if (property->hasAttr())
2487 ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc));
2488
2489 if (const SectionAttr *SA = property->getAttr())
2490 GetterMethod->addAttr(SectionAttr::CreateImplicit(
2491 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2492
2494
2497 } else
2498
2499
2501
2504 property->setGetterMethodDecl(GetterMethod);
2505
2506
2508
2509 if (!SetterMethod) {
2510
2511
2512
2513
2515
2518 CD, !IsClassProperty,
2519 false,
2520 true,
2521 false,
2522 true,
2523 false,
2527
2528
2530 property->getType().getUnqualifiedType().getAtomicUnqualifiedType();
2531
2532
2533
2536 QualType modifiedTy = paramTy;
2540 modifiedTy, modifiedTy);
2541 }
2542 }
2543
2544
2545
2549 paramTy,
2550 nullptr,
2552 nullptr);
2554
2556
2558 SetterMethod->addAttr(ObjCDirectAttr::CreateImplicit(Context, Loc));
2559
2560 CD->addDecl(SetterMethod);
2561 if (const SectionAttr *SA = property->getAttr())
2562 SetterMethod->addAttr(SectionAttr::CreateImplicit(
2563 Context, SA->getName(), Loc, SectionAttr::GNU_section));
2564
2566
2567
2568
2571 } else
2572
2573
2575
2578 property->setSetterMethodDecl(SetterMethod);
2579 }
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592 if (!IsClassProperty) {
2593 if (GetterMethod)
2595 if (SetterMethod)
2597 } else {
2598 if (GetterMethod)
2600 if (SetterMethod)
2602 }
2603
2604 ObjCInterfaceDecl *CurrentClass = dyn_cast(CD);
2605 if (!CurrentClass) {
2607 CurrentClass = Cat->getClassInterface();
2608 else if (ObjCImplDecl *Impl = dyn_cast(CD))
2609 CurrentClass = Impl->getClassInterface();
2610 }
2611 if (GetterMethod)
2613 if (SetterMethod)
2615}
2616
2618 unsigned &Attributes,
2619 bool propertyInPrimaryClass) {
2620
2622 return;
2623
2626 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2627 << "readonly" << "readwrite";
2628
2629 ObjCPropertyDecl *PropertyDecl = cast(PDecl);
2631
2632
2633 if ((Attributes &
2638 !PropertyDecl->hasAttr()) {
2639 Diag(Loc, diag::err_objc_property_requires_object)
2641 ? "weak"
2643 ? "copy"
2644 : "retain (or strong)");
2645 Attributes &=
2650 }
2651
2652
2657 Diag(Loc, diag::warn_objc_property_assign_on_object);
2658 }
2659
2660
2663 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2664 << "assign" << "copy";
2665 Attributes &= ~ObjCPropertyAttribute::kind_copy;
2666 }
2668 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2669 << "assign" << "retain";
2670 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2671 }
2673 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2674 << "assign" << "strong";
2675 Attributes &= ~ObjCPropertyAttribute::kind_strong;
2676 }
2679 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2680 << "assign" << "weak";
2681 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2682 }
2683 if (PropertyDecl->hasAttr())
2684 Diag(Loc, diag::warn_iboutletcollection_property_assign);
2687 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2688 << "unsafe_unretained" << "copy";
2689 Attributes &= ~ObjCPropertyAttribute::kind_copy;
2690 }
2692 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2693 << "unsafe_unretained" << "retain";
2694 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2695 }
2697 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2698 << "unsafe_unretained" << "strong";
2699 Attributes &= ~ObjCPropertyAttribute::kind_strong;
2700 }
2703 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2704 << "unsafe_unretained" << "weak";
2705 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2706 }
2709 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2710 << "copy" << "retain";
2711 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2712 }
2714 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2715 << "copy" << "strong";
2716 Attributes &= ~ObjCPropertyAttribute::kind_strong;
2717 }
2719 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2720 << "copy" << "weak";
2721 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2722 }
2725 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "retain"
2726 << "weak";
2727 Attributes &= ~ObjCPropertyAttribute::kind_retain;
2730 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "strong"
2731 << "weak";
2732 Attributes &= ~ObjCPropertyAttribute::kind_weak;
2733 }
2734
2736
2737 if (auto nullability = PropertyTy->getNullability()) {
2739 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
2740 << "nonnull" << "weak";
2741 }
2742 }
2743
2746 Diag(Loc, diag::err_objc_property_attr_mutually_exclusive) << "atomic"
2747 << "nonatomic";
2748 Attributes &= ~ObjCPropertyAttribute::kind_atomic;
2749 }
2750
2751
2752
2755
2756 } else if (getLangOpts().ObjCAutoRefCount) {
2757
2758
2763
2764
2766 ;
2767 else if (propertyInPrimaryClass) {
2768
2769
2770
2772 Diag(Loc, diag::warn_objc_property_no_assignment_attribute);
2773
2774
2776 Diag(Loc, diag::warn_objc_property_default_assign_on_object);
2777 }
2778 }
2779
2780
2781
2782 }
2783
2788 Diag(Loc, diag::warn_objc_property_copy_missing_on_block);
2793 Diag(Loc, diag::warn_objc_property_retain_of_block);
2794
2797 Diag(Loc, diag::warn_objc_readonly_property_has_setter);
2798}
llvm::DenseMap< const Stmt *, CFGBlock * > SMap
enum clang::sema::@1725::IndirectLocalPathEntry::EntryKind Kind
Defines the clang::Expr interface and subclasses for C++ expressions.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines the clang::Preprocessor interface.
static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl, ObjCPropertyDecl *Prop)
static bool areIncompatiblePropertyAttributes(unsigned Attr1, unsigned Attr2, unsigned Kinds)
static Qualifiers::ObjCLifetime getImpliedARCOwnership(ObjCPropertyAttribute::Kind attrs, QualType type)
getImpliedARCOwnership - Given a set of property attributes and a type, infer an expected lifetime.
static void checkARCPropertyImpl(Sema &S, SourceLocation propertyImplLoc, ObjCPropertyDecl *property, ObjCIvarDecl *ivar)
static bool LocPropertyAttribute(ASTContext &Context, const char *attrName, SourceLocation LParenLoc, SourceLocation &Loc)
static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod, ObjCPropertyDecl *Property)
AddPropertyAttrs - Propagates attributes from a property to the implicitly-declared getter or setter ...
static void checkPropertyDeclWithOwnership(Sema &S, ObjCPropertyDecl *property)
Check the internal consistency of a property declaration with an explicit ownership qualifier.
static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T)
static void CollectImmediateProperties(ObjCContainerDecl *CDecl, ObjCContainerDecl::PropertyMap &PropMap, ObjCContainerDecl::PropertyMap &SuperPropMap, bool CollectClassPropsOnly=false, bool IncludeProtocols=true)
CollectImmediateProperties - This routine collects all properties in the class and its conforming pro...
static void checkAtomicPropertyMismatch(Sema &S, ObjCPropertyDecl *OldProperty, ObjCPropertyDecl *NewProperty, bool PropagateAtomicity)
Check for a mismatch in the atomicity of the given properties.
static void setImpliedPropertyAttributeForReadOnlyProperty(ObjCPropertyDecl *property, ObjCIvarDecl *ivar)
setImpliedPropertyAttributeForReadOnlyProperty - This routine evaludates life-time attributes for a '...
static unsigned getOwnershipRule(unsigned attr)
static ObjCMethodDecl * RedeclarePropertyAccessor(ASTContext &Context, ObjCImplementationDecl *Impl, ObjCMethodDecl *AccessorDecl, SourceLocation AtLoc, SourceLocation PropertyLoc)
Create a synthesized property accessor stub inside the @implementation.
static bool hasWrittenStorageAttribute(ObjCPropertyDecl *Prop, ObjCPropertyQueryKind QueryKind)
Determine whether any storage attributes were written on the property.
static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, ObjCInterfaceDecl::PropertyMap &PropMap)
CollectSuperClassPropertyImplementations - This routine collects list of properties to be implemented...
static const unsigned OwnershipMask
static void DiagnoseUnimplementedAccessor(Sema &S, ObjCInterfaceDecl *PrimaryClass, Selector Method, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, ObjCCategoryDecl *C, ObjCPropertyDecl *Prop, llvm::SmallPtrSet< const ObjCMethodDecl *, 8 > &SMap)
static ObjCPropertyDecl * SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc, ObjCInterfaceDecl *ClassDecl, ObjCPropertyDecl *Property)
SelectPropertyForSynthesisFromProtocols - Finds the most appropriate property declaration that should...
static void CheckPropertyAgainstProtocol(Sema &S, ObjCPropertyDecl *Prop, ObjCProtocolDecl *Proto, llvm::SmallPtrSetImpl< ObjCProtocolDecl * > &Known)
Check this Objective-C property against a property declared in the given protocol.
static ObjCPropertyAttribute::Kind makePropertyAttributesAsWritten(unsigned Attributes)
static bool isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2, ObjCPropertyAttribute::Kind Kind)
This file declares semantic analysis for Objective-C.
Defines the SourceManager interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType, const Attr *attr=nullptr) 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
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.
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(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
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
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.
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.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
void DefaultSynthesizeProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl, SourceLocation AtEnd)
DefaultSynthesizeProperties - This routine default synthesizes all properties which must be synthesiz...
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc)
void ProcessPropertyDecl(ObjCPropertyDecl *property)
Process the specified property declaration and create decls for the setters and getters as needed.
ObjCPropertyDecl * HandlePropertyInClassExtension(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, unsigned &Attributes, const unsigned AttributesAsWritten, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind)
Called by ActOnProperty to handle @property declarations in class extensions.
void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)
Diagnose any null-resettable synthesized setters.
ObjCPropertyDecl * CreatePropertyDecl(Scope *S, ObjCContainerDecl *CDecl, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, Selector GetterSel, SourceLocation GetterNameLoc, Selector SetterSel, SourceLocation SetterNameLoc, const bool isReadWrite, const unsigned Attributes, const unsigned AttributesAsWritten, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
Called by ActOnProperty and HandlePropertyInClassExtension to handle creating the ObjcPropertyDecl fo...
bool CheckARCMethodDecl(ObjCMethodDecl *method)
Check a method declaration for compatibility with the Objective-C ARC conventions.
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D)
Decl * ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC=nullptr)
void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl *IMPDecl, ObjCContainerDecl *CDecl, bool SynthesizeProperties)
DiagnoseUnimplementedProperties - This routine warns on those properties which must be implemented by...
void AtomicPropertySetterGetterRules(ObjCImplDecl *IMPDecl, ObjCInterfaceDecl *IDecl)
AtomicPropertySetterGetterRules - This routine enforces the rule (via warning) when atomic property h...
Decl * ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, SourceLocation PropertyLoc, bool ImplKind, IdentifierInfo *PropertyId, IdentifierInfo *PropertyIvar, SourceLocation PropertyIvarLoc, ObjCPropertyQueryKind QueryKind)
ActOnPropertyImplDecl - This routine performs semantic checks and builds the AST node for a property ...
void DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD)
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, unsigned &Attributes, bool propertyInPrimaryClass)
Ensure attributes are consistent with type.
void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, const IdentifierInfo *Name, bool OverridingProtocolProperty)
DiagnosePropertyMismatch - Compares two properties for their attributes and types and warns on a vari...
void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ObjCInterfaceDecl *CurrentClass, ResultTypeCompatibilityKind RTC)
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddInstanceMethodToGlobalPool - All instance methods in a translation unit are added to a global pool...
RAII object to handle the state changes required to synthesize a function body.
Sema - This implements semantic analysis and AST building for C.
Preprocessor & getPreprocessor() const
bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType &ConvertedType, bool &IncompatibleObjC)
isObjCPointerConversion - Determines whether this is an Objective-C pointer conversion.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() const
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
const LangOptions & LangOpts
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.
void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base=nullptr)
Perform reference-marking and odr-use handling for a DeclRefExpr.
TypeSourceInfo * GetTypeForDeclarator(Declarator &D)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
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
void ProcessAPINotes(Decl *D)
Map any API notes provided for this declaration to attributes on the declaration.
AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, QualType LHSType, QualType RHSType)
CheckAssignmentConstraints - Perform type checking for assignment, argument passing,...
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.
bool isObjCObjectType() const
bool isFunctionType() const
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)
@ 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 '@'.
The JSON file list parser is used to communicate input to InstallAPI.
@ 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.
ObjCMethodFamily
A family of Objective-C methods.
@ Property
The type of a property.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const FunctionProtoType * T
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.