clang: lib/Sema/SemaDeclObjC.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
30#include "llvm/ADT/DenseMap.h"
31#include "llvm/ADT/DenseSet.h"
32
33using namespace clang;
34
35
36
37
38
39
40
41
42
43
45 QualType receiverTypeIfCall) {
48
49
50
51
52
53
54
57
59 return false;
61
62 } else {
64 assert(resultClass && "unexpected object type!");
65
66
67
69 if (receiverTypeIfCall.isNull() &&
70 !isa(method->getDeclContext()))
71 return false;
72
73
74 } else {
75
76
78 if (isa(method->getDeclContext())) {
79 if (receiverTypeIfCall.isNull())
80 return false;
81
83 ->getInterfaceDecl();
84
85
86 if (!receiverClass) return false;
87 } else {
89 assert(receiverClass && "method not associated with a class!");
90 }
91
92
95 return false;
96 }
97 }
98
100
101
102
103 if (receiverTypeIfCall.isNull() &&
105 method->addAttr(UnavailableAttr::CreateImplicit(Context, "",
106 UnavailableAttr::IR_ARCInitReturnsUnrelated, loc));
107 return true;
108 }
109
110
111 Diag(loc, diag::err_arc_init_method_unrelated_result_type);
113 return true;
114}
115
116
117
120 if (OldD->hasAttr() && !NewD->hasAttr()) {
121 S.Diag(NewD->getLocation(), diag::warn_overriding_method_missing_noescape);
122 S.Diag(OldD->getLocation(), diag::note_overridden_marked_noescape);
123 return false;
124 }
125
126 return true;
127}
128
129
130
135 S.Diag(CD->getLocation(), diag::note_cat_conform_to_noescape_prot)
138}
139
145
146
147
148
151
152
154 = dyn_cast(NewMethod->getDeclContext());
155 if (!CurrentClass) {
158 CurrentClass = Cat->getClassInterface();
159 else if (ObjCImplDecl *Impl = dyn_cast(DC))
160 CurrentClass = Impl->getClassInterface();
162 = dyn_cast(DC))
163 CurrentClass = CatImpl->getClassInterface();
164 }
165
166 if (CurrentClass) {
168 diag::warn_related_result_type_compatibility_class)
170 << ResultType
171 << ResultTypeRange;
172 } else {
174 diag::warn_related_result_type_compatibility_protocol)
175 << ResultType
176 << ResultTypeRange;
177 }
178
181 diag::note_related_result_type_family)
182 << 0
183 << Family;
184 else
186 diag::note_related_result_type_overridden);
187 }
188
189 if ((NewMethod->hasAttr() !=
190 Overridden->hasAttr())) {
193 ? diag::err_nsreturns_retained_attribute_mismatch
194 : diag::warn_nsreturns_retained_attribute_mismatch)
195 << 1;
196 Diag(Overridden->getLocation(), diag::note_previous_decl) << "method";
197 }
198 if ((NewMethod->hasAttr() !=
199 Overridden->hasAttr())) {
202 ? diag::err_nsreturns_retained_attribute_mismatch
203 : diag::warn_nsreturns_retained_attribute_mismatch)
204 << 0;
205 Diag(Overridden->getLocation(), diag::note_previous_decl) << "method";
206 }
207
212 ni != ne && oi != oe; ++ni, ++oi) {
215 if (newDecl->hasAttr() !=
216 oldDecl->hasAttr()) {
219 ? diag::err_nsconsumed_attribute_mismatch
220 : diag::warn_nsconsumed_attribute_mismatch);
221 Diag(oldDecl->getLocation(), diag::note_previous_decl) << "parameter";
222 }
223
225 }
226}
227
228
229
233 switch (family) {
243 return false;
244
249 Diag(method->getLocation(), diag::err_dealloc_bad_result_type)
252 else
253 Diag(method->getLocation(), diag::err_dealloc_bad_result_type)
256 return true;
257 }
258 return false;
259
261
263 return true;
264
265 method->addAttr(NSConsumesSelfAttr::CreateImplicit(Context));
266
267
268
269 if (method->hasAttr())
270 return false;
271 break;
272
277 if (method->hasAttr() ||
278 method->hasAttr() ||
279 method->hasAttr())
280 return false;
281 break;
282 }
283
284 method->addAttr(NSReturnsRetainedAttr::CreateImplicit(Context));
285 return false;
286}
287
290 if (!ND)
291 return;
292 bool IsCategory = false;
293 StringRef RealizedPlatform;
295 nullptr, VersionTuple(),
296 &RealizedPlatform);
298 if (isa(ND)) {
300 return;
301 if (RealizedPlatform.empty())
303
304
305 if (RealizedPlatform.ends_with("_app_extension"))
306 return;
307 S.Diag(ImplLoc, diag::warn_unavailable_def);
310 return;
311 }
312 if (const auto *CD = dyn_cast(ND)) {
313 if (!CD->getClassInterface()->isDeprecated())
314 return;
315 ND = CD->getClassInterface();
316 IsCategory = true;
317 } else
318 return;
319 }
320 S.Diag(ImplLoc, diag::warn_deprecated_def)
321 << (isa(ND)
322 ? 0
323 : isa(ND) || IsCategory ? 2
324 : 1);
325 if (isa(ND))
328 else
330 << (isa(ND) ? "category" : "class");
331}
332
333
334
336 ObjCMethodDecl *MDecl = dyn_cast_or_null(D);
337
338
339 if (!MDecl)
340 return;
343 else
345}
346
347
348
349static bool
352
357 } else {
358 return true;
359 }
360
361
362
363 return .getLocalQualifiers().hasObjCLifetime();
364}
365
366
367
372 ObjCMethodDecl *MDecl = dyn_cast_or_null(D);
373
376
377
378 if (!MDecl)
379 return;
380
385 diag::err_func_def_incomplete_result))
387
388
391
392
393
394
395
397
400
401
403 false);
404
405
406 for (auto *Param : MDecl->parameters()) {
407 if (!Param->isInvalidDecl() && getLangOpts().ObjCAutoRefCount &&
409 Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) <<
410 Param->getType();
411
412 if (Param->getIdentifier())
414 }
415
416
423 Diag(MDecl->getLocation(), diag::err_arc_illegal_method_def)
425 break;
426
438 break;
439 }
440 }
441
442
443
447
448 if (IMD) {
453 ObjCImplDecl *ImplDeclOfMethodDecl = nullptr;
454 if (ObjCInterfaceDecl *OID = dyn_cast(ContDeclOfMethodDecl))
455 ImplDeclOfMethodDecl = OID->getImplementation();
456 else if (ObjCCategoryDecl *CD = dyn_cast(ContDeclOfMethodDecl)) {
457 if (CD->IsClassExtension()) {
459 ImplDeclOfMethodDecl = OID->getImplementation();
460 } else
461 ImplDeclOfMethodDecl = CD->getImplementation();
462 }
463
464
465 if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef)
467 }
468
473 IC->getSuperClass() != nullptr;
474 } else if (IC->hasDesignatedInitializers()) {
477 }
478 }
479
480
481
482
483
490
494
495 } else {
497 SuperClass->lookupMethod(MDecl->getSelector(),
500 (SuperMethod && SuperMethod->hasAttr());
501 }
502 }
503 }
504
505
506
508}
509
510namespace {
511
512
513
514
516 public:
517 ObjCInterfaceValidatorCCC() : CurrentIDecl(nullptr) {}
519 : CurrentIDecl(IDecl) {}
520
521 bool ValidateCandidate(const TypoCorrection &candidate) override {
524 }
525
526 std::unique_ptr clone() override {
527 return std::make_unique(*this);
528 }
529
530 private:
532};
533
534}
535
539 unsigned NumProtoRefs,
541 assert(ProtoRefs);
542
544 for (unsigned i = 0; i < NumProtoRefs; ++i) {
546 nullptr,
547 false,
548 true);
549 }
550}
551
558
561
562 if (!PrevDecl) {
563
564
565 ObjCInterfaceValidatorCCC CCC(IDecl);
570 << SuperName << ClassName);
572 }
573 }
574
576 Diag(SuperLoc, diag::err_recursive_superclass)
577 << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
579 } else {
581 dyn_cast_or_null(PrevDecl);
583
584
585 if (SuperClassDecl) {
588 }
589
590 if (PrevDecl && !SuperClassDecl) {
591
592
594 dyn_cast_or_null(PrevDecl)) {
595 QualType T = TDecl->getUnderlyingType();
598 SuperClassDecl = dyn_cast(IDecl);
600
601
602
603
604
607 }
608 }
609 }
610
611
612
613
614
615
616 if (!SuperClassDecl) {
617 Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
618 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
619 }
620 }
621
622 if (!isa_and_nonnull(PrevDecl)) {
623 if (!SuperClassDecl)
624 Diag(SuperLoc, diag::err_undef_superclass)
625 << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
627 SuperLoc, SuperClassType, diag::err_forward_superclass,
628 SuperClassDecl->getDeclName(), ClassName,
629 SourceRange(AtInterfaceLoc, ClassLoc))) {
630 SuperClassDecl = nullptr;
632 }
633 }
634
635 if (SuperClassType.isNull()) {
636 assert(!SuperClassDecl && "Failed to set SuperClassType?");
637 return;
638 }
639
640
642 if (!SuperTypeArgs.empty()) {
645 SuperTypeArgsRange.getBegin(), SuperTypeArgs,
648 if (!fullSuperClassType.isUsable())
649 return;
650
651 SuperClassType =
653 }
654
655 if (!SuperClassTInfo) {
657 SuperLoc);
658 }
659
662 }
663}
664
670
672 if (parsedTypeBound) {
673
677
679
680
684 diag::err_objc_type_param_bound_missing_pointer)
685 << typeBound << paramName
687
688
689
692
693
698
699
701 } else {
702
704 diag::err_objc_type_param_bound_nonobject)
705 << typeBound << paramName;
706
707
708 typeBoundInfo = nullptr;
709 }
710
711
712
713 if (typeBoundInfo) {
717 bool diagnosed = false;
719 if (qual) {
721 rangeToRemove = attr.getLocalSourceRange();
722 if (attr.getTypePtr()->getImmediateNullability()) {
724 diag::err_objc_type_param_bound_explicit_nullability)
725 << paramName << typeBound
727 diagnosed = true;
728 }
729 }
730 }
731
732 if (!diagnosed) {
735 diag::err_objc_type_param_bound_qualified)
736 << paramName << typeBound
739 }
740
741
742
743
746 if (!quals.empty()) {
747 typeBoundInfo =
749 }
750 }
751 }
752 }
753
754
755
756 if (!typeBoundInfo) {
759 }
760
761
763 varianceLoc, index, paramLoc, paramName,
764 colonLoc, typeBoundInfo);
765}
766
772
774 typeParams(
775 reinterpret_cast<ObjCTypeParamDecl * const *>(typeParamsIn.data()),
776 typeParamsIn.size());
777
778
779
780
781
782 llvm::SmallDenseMap<IdentifierInfo *, ObjCTypeParamDecl *> knownParams;
783 for (auto *typeParam : typeParams) {
784 auto known = knownParams.find(typeParam->getIdentifier());
785 if (known != knownParams.end()) {
786 Diag(typeParam->getLocation(), diag::err_objc_type_param_redecl)
787 << typeParam->getIdentifier()
788 << SourceRange(known->second->getLocation());
789
790 typeParam->setInvalidDecl();
791 } else {
792 knownParams.insert(std::make_pair(typeParam->getIdentifier(), typeParam));
793
794
796 }
797 }
798
799
801}
802
805 for (auto *typeParam : *typeParamList) {
806 if (!typeParam->isInvalidDecl()) {
807 S->RemoveDecl(typeParam);
809 }
810 }
811}
812
813namespace {
814
815
816 enum class TypeParamListContext {
817 ForwardDeclaration,
820 Extension
821 };
822}
823
824
825
826
830 TypeParamListContext newContext) {
831
832 if (prevTypeParams->size() != newTypeParams->size()) {
834 if (newTypeParams->size() > prevTypeParams->size()) {
836 } else {
838 }
839
840 S.Diag(diagLoc, diag::err_objc_type_param_arity_mismatch)
841 << static_cast<unsigned>(newContext)
842 << (newTypeParams->size() > prevTypeParams->size())
843 << prevTypeParams->size()
844 << newTypeParams->size();
845
846 return true;
847 }
848
849
850 for (unsigned i = 0, n = prevTypeParams->size(); i != n; ++i) {
853
854
857 newContext != TypeParamListContext::Definition) {
858
859
863 !(isa(prevTypeParam->getDeclContext()) &&
864 cast(prevTypeParam->getDeclContext())
865 ->getDefinition() == prevTypeParam->getDeclContext())) {
866
867
868
869 } else {
870 {
871
875
876 auto diag = S.Diag(diagLoc,
877 diag::err_objc_type_param_variance_conflict)
878 << static_cast<unsigned>(newTypeParam->getVariance())
880 << static_cast<unsigned>(prevTypeParam->getVariance())
885 break;
886
889 StringRef newVarianceStr
891 ? "__covariant"
892 : "__contravariant";
896 (newVarianceStr + " ").str());
897 } else {
899 newVarianceStr);
900 }
901 }
902 }
903 }
904
905 S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)
907
908
910 }
911 }
912
913
916 continue;
917
918
919
923 S.Diag(newBoundRange.getBegin(), diag::err_objc_type_param_bound_conflict)
931 newBoundRange,
934
935 S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)
937
938
939
941 continue;
942 }
943
944
945
946
947 if (newContext == TypeParamListContext::ForwardDeclaration ||
948 newContext == TypeParamListContext::Definition) {
949
952 std::string newCode
956 diag::err_objc_type_param_bound_missing)
959 << (newContext == TypeParamListContext::ForwardDeclaration)
961
962 S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)
964 }
965
966
968 }
969
970 return false;
971}
972
978 Decl *const *ProtoRefs, unsigned NumProtoRefs,
981 assert(ClassName && "Missing class identifier");
982
984
988
989 if (PrevDecl && !isa(PrevDecl)) {
990 Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
991 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
992 }
993
994
995 ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null(PrevDecl);
996
997 if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1011 }
1012
1013
1014
1015 if (PrevIDecl) {
1017 if (typeParamList) {
1018
1020 typeParamList,
1021 TypeParamListContext::Definition)) {
1022 typeParamList = nullptr;
1023 }
1024 } else {
1025 Diag(ClassLoc, diag::err_objc_parameterized_forward_class_first)
1026 << ClassName;
1027 Diag(prevTypeParamList->getLAngleLoc(), diag::note_previous_decl)
1028 << ClassName;
1029
1030
1032 for (auto *typeParam : *prevTypeParamList) {
1038 typeParam->getUnderlyingType())));
1039 }
1040
1043 clonedTypeParams,
1045 }
1046 }
1047 }
1048
1051 ClassName, typeParamList, PrevIDecl, ClassLoc);
1052 if (PrevIDecl) {
1053
1057 SkipBody->New = IDecl;
1059 } else {
1060 Diag(AtInterfaceLoc, diag::err_duplicate_class_def)
1062 Diag(Def->getLocation(), diag::note_previous_definition);
1064 }
1065 }
1066 }
1067
1071
1072
1073 if (PrevIDecl)
1075
1077
1078
1079
1084
1085 if (SuperName) {
1086
1088
1090 ClassName, ClassLoc,
1091 SuperName, SuperLoc, SuperTypeArgs,
1092 SuperTypeArgsRange);
1093 } else {
1095 }
1096
1097
1098 if (NumProtoRefs) {
1100 NumProtoRefs, ProtoLocs);
1102 ProtoLocs, Context);
1104 }
1105
1108 return IDecl;
1109}
1110
1111
1112
1113
1118 if (!SuperName)
1119 return;
1122 if (!IDecl)
1123 return;
1124
1125 if (const TypedefNameDecl *TDecl = dyn_cast_or_null(IDecl)) {
1126 QualType T = TDecl->getUnderlyingType();
1129 ProtocolRefs.append(OPT->qual_begin(), OPT->qual_end());
1130
1131
1132
1133
1134 ProtocolLocs.append(OPT->getNumProtocols(), SuperLoc);
1135 }
1136 }
1137}
1138
1139
1140
1147
1151 if (ADecl) {
1152 Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
1153 Diag(ADecl->getLocation(), diag::note_previous_declaration);
1154 return nullptr;
1155 }
1156
1161 dyn_cast_or_null(CDeclU)) {
1162 QualType T = TDecl->getUnderlyingType();
1165 ClassName = IDecl->getIdentifier();
1169 }
1170 }
1171 }
1172 ObjCInterfaceDecl *CDecl = dyn_cast_or_null(CDeclU);
1173 if (!CDecl) {
1174 Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
1175 if (CDeclU)
1176 Diag(CDeclU->getLocation(), diag::note_previous_declaration);
1177 return nullptr;
1178 }
1179
1180
1183
1186
1188}
1189
1193
1194 bool res = false;
1196 E = PList.end(); I != E; ++I) {
1198 if (PDecl->getIdentifier() == PName) {
1199 Diag(Ploc, diag::err_protocol_has_circular_dependency);
1200 Diag(PrevLoc, diag::note_previous_definition);
1201 res = true;
1202 }
1203
1204 if (!PDecl->hasDefinition())
1205 continue;
1206
1208 PDecl->getLocation(), PDecl->getReferencedProtocols()))
1209 res = true;
1210 }
1211 }
1212 return res;
1213}
1214
1217 SourceLocation ProtocolLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs,
1221 bool err = false;
1222
1223 assert(ProtocolName && "Missing protocol identifier");
1228
1229
1230
1231
1233 ProtocolLoc, AtProtoInterfaceLoc,
1234 Def);
1235
1238 SkipBody->New = PDecl;
1240 } else {
1241
1242 Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
1243 Diag(Def->getLocation(), diag::note_previous_definition);
1244 }
1245
1246
1247
1251 } else {
1252 if (PrevDecl) {
1253
1254
1258 ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList);
1259 }
1260
1261
1263 ProtocolLoc, AtProtoInterfaceLoc,
1264 PrevDecl);
1265
1268 }
1269
1273
1274
1275 if (PrevDecl)
1277
1278 if (!err && NumProtoRefs ) {
1279
1281 NumProtoRefs, ProtoLocs);
1283 ProtoLocs, Context);
1284 }
1285
1288 return PDecl;
1289}
1290
1295 UndefinedProtocol = PDecl;
1296 return true;
1297 }
1298
1299 for (auto *PI : PDecl->protocols())
1301 UndefinedProtocol = PI;
1302 return true;
1303 }
1304 return false;
1305}
1306
1307
1308
1309
1311 bool ForObjCContainer,
1316 if (!PDecl) {
1324 PDiag(diag::err_undeclared_protocol_suggest)
1325 << Pair.first);
1326 }
1327
1328 if (!PDecl) {
1329 Diag(Pair.second, diag::err_undeclared_protocol) << Pair.first;
1330 continue;
1331 }
1332
1335
1336
1337
1338 if (!ForObjCContainer) {
1340 }
1341
1342
1343
1344
1346
1347 if (WarnOnDeclarations &&
1349 Diag(Pair.second, diag::warn_undef_protocolref) << Pair.first;
1350 Diag(UndefinedProtocol->getLocation(), diag::note_protocol_decl_undefined)
1351 << UndefinedProtocol;
1352 }
1353 Protocols.push_back(PDecl);
1354 }
1355}
1356
1357namespace {
1358
1359
1360class ObjCTypeArgOrProtocolValidatorCCC final
1364 public:
1365 ObjCTypeArgOrProtocolValidatorCCC(ASTContext &context,
1367 : Context(context), LookupKind(lookupKind) { }
1368
1369 bool ValidateCandidate(const TypoCorrection &candidate) override {
1370
1373 return true;
1374 }
1375
1376
1378
1380
1381
1382
1383 if (isa(typeDecl) && !Context.getLangOpts().CPlusPlus)
1384 return false;
1385
1386
1387
1389 if (type->isObjCObjectPointerType() ||
1390 type->isBlockPointerType() ||
1391 type->isDependentType() ||
1392 type->isObjCObjectType())
1393 return true;
1394
1395 return false;
1396 }
1397
1398
1399
1401 return true;
1402
1403 return false;
1404 }
1405
1406 return false;
1407 }
1408
1409 std::unique_ptr clone() override {
1410 return std::make_unique(*this);
1411 }
1412};
1413}
1414
1419 bool SelectProtocolFirst) {
1420 Diag(TypeArgLoc, diag::err_objc_type_args_and_protocols)
1421 << SelectProtocolFirst << TypeArgId << ProtocolId
1423}
1424
1432 bool warnOnIncompleteProtocols) {
1434
1435
1436 unsigned numProtocolsResolved = 0;
1437 auto resolvedAsProtocols = [&] {
1438 assert(numProtocolsResolved == identifiers.size() && "Unresolved protocols");
1439
1440
1441
1442
1445 bool allAreTypeNames = false;
1447 if (!base.isNull()) {
1449 baseClass = objcObjectType->getInterface();
1450 if (baseClass) {
1452 if (typeParams->size() == numProtocolsResolved) {
1453
1454 allAreTypeNames = true;
1455 }
1456 }
1457 }
1458 }
1459 }
1460
1461 for (unsigned i = 0, n = protocols.size(); i != n; ++i) {
1464
1465
1466 if (!warnOnIncompleteProtocols) {
1468 }
1469
1470
1473
1474
1475
1476
1478 if (warnOnIncompleteProtocols &&
1480 Diag(identifierLocs[i], diag::warn_undef_protocolref)
1482 Diag(forwardDecl->getLocation(), diag::note_protocol_decl_undefined)
1483 << forwardDecl;
1484 }
1485
1486
1487
1488
1489 if (allAreTypeNames) {
1490 if (auto *decl =
1493 if (isa(decl)) {
1494 if (firstClassNameLoc.isInvalid())
1495 firstClassNameLoc = identifierLocs[i];
1496 } else if (!isa(decl)) {
1497
1498 allAreTypeNames = false;
1499 }
1500 } else {
1501 allAreTypeNames = false;
1502 }
1503 }
1504 }
1505
1506
1507
1508
1509
1510 if (allAreTypeNames && firstClassNameLoc.isValid()) {
1513 bool allProtocolsDeclared = true;
1514 for (auto *proto : protocols) {
1515 if (knownProtocols.count(static_cast<ObjCProtocolDecl *>(proto)) == 0) {
1516 allProtocolsDeclared = false;
1517 break;
1518 }
1519 }
1520
1521 if (allProtocolsDeclared) {
1522 Diag(firstClassNameLoc, diag::warn_objc_redundant_qualified_class_type)
1526 }
1527 }
1528
1529 protocolLAngleLoc = lAngleLoc;
1530 protocolRAngleLoc = rAngleLoc;
1531 assert(protocols.size() == identifierLocs.size());
1532 };
1533
1534
1535 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1537 protocols.push_back(proto);
1538 if (proto)
1539 ++numProtocolsResolved;
1540 }
1541
1542
1543 if (numProtocolsResolved == identifiers.size())
1544 return resolvedAsProtocols();
1545
1546
1547
1548
1549
1550 typedef llvm::PointerUnion<TypeDecl *, ObjCInterfaceDecl *> TypeOrClassDecl;
1552 unsigned numTypeDeclsResolved = 0;
1553 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1556 if () {
1557 typeDecls.push_back(TypeOrClassDecl());
1558 continue;
1559 }
1560
1561 if (auto typeDecl = dyn_cast(decl)) {
1562 typeDecls.push_back(typeDecl);
1563 ++numTypeDeclsResolved;
1564 continue;
1565 }
1566
1567 if (auto objcClass = dyn_cast(decl)) {
1568 typeDecls.push_back(objcClass);
1569 ++numTypeDeclsResolved;
1570 continue;
1571 }
1572
1573 typeDecls.push_back(TypeOrClassDecl());
1574 }
1575
1577
1578
1579
1580 auto resolveTypeReference = [&](TypeOrClassDecl typeDecl, SourceLocation loc)
1582
1584 const char* prevSpec;
1585 unsigned diagID;
1587 if (auto *actualTypeDecl = typeDecl.dyn_cast<TypeDecl *>())
1589 else
1595
1598
1599
1601
1602
1603
1612 starLoc);
1613
1614
1615 Diag(loc, diag::err_objc_type_arg_missing_star)
1618 }
1619
1620
1622 };
1623
1624
1625
1626 auto resolvedAsTypeDecls = [&] {
1627
1628 protocols.clear();
1629
1630 assert(numTypeDeclsResolved == identifiers.size() && "Unresolved type decl");
1631
1632 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1633
1634 TypeResult type = resolveTypeReference(typeDecls[i], identifierLocs[i]);
1635 if (.isUsable()) {
1636 typeArgs.clear();
1637 return;
1638 }
1639
1640 typeArgs.push_back(type.get());
1641 }
1642
1643 typeArgsLAngleLoc = lAngleLoc;
1644 typeArgsRAngleLoc = rAngleLoc;
1645 };
1646
1647
1648
1649 if (numTypeDeclsResolved == identifiers.size())
1650 return resolvedAsTypeDecls();
1651
1652
1653
1654
1656 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1657
1658
1659 if (protocols[i] || typeDecls[i]) {
1660
1661
1663
1664
1665 if (protocols[i] && typeDecls[i])
1666 continue;
1667
1668
1669
1672 continue;
1673 }
1674
1675
1676
1678 continue;
1679
1680
1681
1683 continue;
1684
1685
1686
1688 identifiers[i], identifierLocs[i],
1689 protocols[i] != nullptr);
1690
1691 protocols.clear();
1692 typeArgs.clear();
1693 return;
1694 }
1695
1696
1697 ObjCTypeArgOrProtocolValidatorCCC CCC(Context, lookupKind);
1701 if (corrected) {
1702
1705 PDiag(diag::err_undeclared_protocol_suggest)
1706 << identifiers[i]);
1708 protocols[i] = proto;
1709 ++numProtocolsResolved;
1710 continue;
1711 }
1712
1713
1716 PDiag(diag::err_unknown_typename_suggest)
1717 << identifiers[i]);
1719 typeDecls[i] = typeDecl;
1720 ++numTypeDeclsResolved;
1721 continue;
1722 }
1723
1724
1727 PDiag(diag::err_unknown_type_or_class_name_suggest)
1728 << identifiers[i] << true);
1730 typeDecls[i] = objcClass;
1731 ++numTypeDeclsResolved;
1732 continue;
1733 }
1734 }
1735
1736
1737 Diag(identifierLocs[i],
1740 ? diag::err_undeclared_protocol
1741 : diag::err_unknown_typename))
1742 << identifiers[i];
1743 protocols.clear();
1744 typeArgs.clear();
1745 return;
1746 }
1747
1748
1749
1750 if (numProtocolsResolved == identifiers.size())
1751 return resolvedAsProtocols();
1752
1753
1754 assert(numTypeDeclsResolved == identifiers.size() && "Not all types?");
1755 return resolvedAsTypeDecls();
1756}
1757
1758
1759
1760
1763 if (!ID)
1764 return;
1765
1766 llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
1767 for (auto *MD : ID->methods())
1768 MethodMap[MD->getSelector()] = MD;
1769
1770 if (MethodMap.empty())
1771 return;
1772 for (const auto *Method : CAT->methods()) {
1773 const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
1774 if (PrevMethod &&
1775 (PrevMethod->isInstanceMethod() == Method->isInstanceMethod()) &&
1777 Diag(Method->getLocation(), diag::err_duplicate_method_decl)
1778 << Method->getDeclName();
1779 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
1780 }
1781 }
1782}
1783
1784
1796 IdentPair.second, AtProtocolLoc, PrevDecl);
1797
1800
1803
1804 if (PrevDecl)
1806
1807 DeclsInGroup.push_back(PDecl);
1808 }
1809
1811}
1812
1817 Decl *const *ProtoRefs, unsigned NumProtoRefs,
1823
1824
1825
1826 if (!IDecl ||
1828 diag::err_category_forward_interface,
1829 CategoryName == nullptr)) {
1830
1831
1832
1834 AtInterfaceLoc, ClassLoc, CategoryLoc,
1835 CategoryName, IDecl, typeParamList);
1838
1839 if (!IDecl)
1840 Diag(ClassLoc, diag::err_undef_interface) << ClassName;
1842 return CDecl;
1843 }
1844
1846 Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;
1848 diag::note_implementation_declared);
1849 }
1850
1851 if (CategoryName) {
1852
1855
1856 Diag(CategoryLoc, diag::warn_dup_category_def)
1857 << ClassName << CategoryName;
1858 Diag(Previous->getLocation(), diag::note_previous_definition);
1859 }
1860 }
1861
1862
1863 if (typeParamList) {
1866 SemaRef, prevTypeParamList, typeParamList,
1867 CategoryName ? TypeParamListContext::Category
1868 : TypeParamListContext::Extension))
1869 typeParamList = nullptr;
1870 } else {
1872 diag::err_objc_parameterized_category_nonclass)
1873 << (CategoryName != nullptr)
1874 << ClassName
1876
1877 typeParamList = nullptr;
1878 }
1879 }
1880
1882 ClassLoc, CategoryLoc, CategoryName, IDecl,
1883 typeParamList);
1884
1886
1887
1888
1889
1892
1893 if (NumProtoRefs) {
1895 NumProtoRefs, ProtoLocs);
1897 ProtoLocs, Context);
1898
1901 NumProtoRefs, Context);
1902 }
1903
1906 return CDecl;
1907}
1908
1909
1910
1911
1921 if (!CatIDecl) {
1922
1923
1924 CatIDecl =
1926 ClassLoc, CatLoc, CatName, IDecl,
1927 nullptr);
1929 }
1930 }
1931
1934 ClassLoc, AtCatImplLoc, CatLoc);
1935
1936 if (!IDecl) {
1937 Diag(ClassLoc, diag::err_undef_interface) << ClassName;
1941 diag::err_undef_interface)) {
1943 }
1944
1947
1948
1950
1951
1952
1953 if (IDecl && IDecl->hasAttr()) {
1954 Diag(ClassLoc, diag::err_objc_runtime_visible_category)
1956 }
1957
1958
1959 if (CatIDecl) {
1961 Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName
1962 << CatName;
1964 diag::note_previous_definition);
1966 } else {
1968
1969
1972 }
1973 }
1974
1977 return CDecl;
1978}
1979
1986
1990 if (PrevDecl && !isa(PrevDecl)) {
1991 Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
1992 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
1993 } else if ((IDecl = dyn_cast_or_null(PrevDecl))) {
1994
1995
1997 diag::warn_undef_interface);
1998 } else {
1999
2000
2001 ObjCInterfaceValidatorCCC CCC{};
2006
2007
2008
2010 Corrected, PDiag(diag::warn_undef_interface_suggest) << ClassName,
2011 false);
2012 } else {
2013 Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
2014 }
2015 }
2016
2017
2019 if (SuperClassname) {
2020
2021 PrevDecl =
2024 if (PrevDecl && !isa(PrevDecl)) {
2025 Diag(SuperClassLoc, diag::err_redefinition_different_kind)
2026 << SuperClassname;
2027 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
2028 } else {
2029 SDecl = dyn_cast_or_null(PrevDecl);
2031 SDecl = nullptr;
2032 if (!SDecl)
2033 Diag(SuperClassLoc, diag::err_undef_superclass)
2034 << SuperClassname << ClassName;
2036
2037
2038 Diag(SuperClassLoc, diag::err_conflicting_super_class)
2040 Diag(SDecl->getLocation(), diag::note_previous_definition);
2041 }
2042 }
2043 }
2044
2045 if (!IDecl) {
2046
2047
2048
2049
2050
2051 IDecl =
2053 ClassName, nullptr,
2054 nullptr, ClassLoc, true);
2057 if (SDecl) {
2060 SuperClassLoc));
2062 } else {
2064 }
2065
2067 } else {
2068
2069
2070
2073 }
2074
2077 ClassLoc, AtClassImplLoc, SuperClassLoc);
2078
2081
2084 return IMPDecl;
2085 }
2086
2087
2089
2090 Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
2092 diag::note_previous_definition);
2094 } else {
2097
2098
2100 }
2101
2102
2103
2106 Diag(ClassLoc, diag::err_objc_runtime_visible_subclass)
2109 }
2110
2112 return IMPDecl;
2113}
2114
2119 DeclsInGroup.reserve(Decls.size() + 1);
2120
2121 for (unsigned i = 0, e = Decls.size(); i != e; ++i) {
2122 Decl *Dcl = Decls[i];
2123 if (!Dcl)
2124 continue;
2127 DeclsInGroup.push_back(Dcl);
2128 }
2129
2130 DeclsInGroup.push_back(ObjCImpDecl);
2131
2133}
2134
2138 assert(ImpDecl && "missing implementation decl");
2141 if (!IDecl)
2142 return;
2143
2144
2145
2148
2149 for (unsigned i = 0, e = numIvars; i != e; ++i) {
2151
2152
2153
2154
2157 ImpDecl->addDecl(ivars[i]);
2158 }
2159
2160 return;
2161 }
2162
2163 if (numIvars == 0)
2164 return;
2165
2166 assert(ivars && "missing @implementation ivars");
2169 Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use);
2170 for (unsigned i = 0; i < numIvars; i++) {
2174 Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
2175 Diag(ClsIvar->getLocation(), diag::note_previous_definition);
2176 continue;
2177 }
2178
2181 CDecl->getIvarDecl(ImplIvar->getIdentifier())) {
2182 Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
2183 Diag(ClsExtIvar->getLocation(), diag::note_previous_definition);
2184 continue;
2185 }
2186 }
2187
2190 ImpDecl->addDecl(ImplIvar);
2191 }
2192 return;
2193 }
2194
2195
2196
2197 unsigned j = 0;
2200 for (; numIvars > 0 && IVI != IVE; ++IVI) {
2203 assert (ImplIvar && "missing implementation ivar");
2204 assert (ClsIvar && "missing class ivar");
2205
2206
2208 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
2211 Diag(ClsIvar->getLocation(), diag::note_previous_definition);
2215 diag::err_conflicting_ivar_bitwidth)
2218 diag::note_previous_definition);
2219 }
2220
2222 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
2224 Diag(ClsIvar->getLocation(), diag::note_previous_definition);
2225 }
2226 --numIvars;
2227 }
2228
2229 if (numIvars > 0)
2230 Diag(ivars[j]->getLocation(), diag::err_inconsistent_ivar_count);
2231 else if (IVI != IVE)
2232 Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count);
2233}
2234
2236
2238}
2239
2242 unsigned DiagID,
2243 NamedDecl *NeededFor = nullptr) {
2245 return;
2246
2247
2248
2249
2250
2251
2252 {
2255 B << method;
2256 if (NeededFor)
2257 B << NeededFor;
2258
2259
2260 std::string FixItStr;
2261 llvm::raw_string_ostream Out(FixItStr);
2263 Out << " {\n}\n\n";
2264
2267 }
2268
2269
2271 if (MethodLoc.isValid())
2272 S.Diag(MethodLoc, diag::note_method_declared_at) << method;
2273}
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2311 bool rejectId) {
2312
2313 if (rejectId && B->isObjCIdType()) return false;
2314
2315
2316
2317
2318
2322 }
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2338}
2339
2342}
2343
2344
2348 (y & ~Decl::OBJC_TQ_CSNullability);
2349}
2350
2354 bool IsProtocolMethodDecl,
2355 bool IsOverridingMode,
2356 bool Warn) {
2357 if (IsProtocolMethodDecl &&
2360 if (Warn) {
2362 (IsOverridingMode
2363 ? diag::warn_conflicting_overriding_ret_type_modifiers
2364 : diag::warn_conflicting_ret_type_modifiers))
2367 S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
2369 }
2370 else
2371 return false;
2372 }
2373 if (Warn && IsOverridingMode &&
2374 !isa(MethodImpl->getDeclContext()) &&
2377 false)) {
2381 diag::warn_conflicting_nullability_attr_overriding_ret_types)
2388 S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
2389 }
2390
2393 return true;
2394 if (!Warn)
2395 return false;
2396
2397 unsigned DiagID =
2398 IsOverridingMode ? diag::warn_conflicting_overriding_ret_types
2399 : diag::warn_conflicting_ret_types;
2400
2401
2402
2407
2408
2409
2410
2412 return false;
2413
2414 DiagID =
2415 IsOverridingMode ? diag::warn_non_covariant_overriding_ret_types
2416 : diag::warn_non_covariant_ret_types;
2417 }
2418 }
2419
2425 ? diag::note_previous_declaration
2426 : diag::note_previous_definition)
2428 return false;
2429}
2430
2436 bool IsProtocolMethodDecl,
2437 bool IsOverridingMode,
2438 bool Warn) {
2439 if (IsProtocolMethodDecl &&
2442 if (Warn) {
2443 if (IsOverridingMode)
2445 diag::warn_conflicting_overriding_param_modifiers)
2449 diag::warn_conflicting_param_modifiers)
2452 S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration)
2454 }
2455 else
2456 return false;
2457 }
2458
2461 if (Warn && IsOverridingMode &&
2462 !isa(MethodImpl->getDeclContext()) &&
2465 diag::warn_conflicting_nullability_attr_overriding_param_types)
2472 S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration);
2473 }
2475 return true;
2476
2477 if (!Warn)
2478 return false;
2479 unsigned DiagID =
2480 IsOverridingMode ? diag::warn_conflicting_overriding_param_types
2481 : diag::warn_conflicting_param_types;
2482
2483
2484
2489
2490
2491
2492
2494 return false;
2495
2496 DiagID =
2497 IsOverridingMode ? diag::warn_non_contravariant_overriding_param_types
2498 : diag::warn_non_contravariant_param_types;
2499 }
2500 }
2501
2504 << MethodImpl->getDeclName() << IfaceTy << ImplTy;
2506 (IsOverridingMode ? diag::note_previous_declaration
2507 : diag::note_previous_definition))
2509 return false;
2510}
2511
2512
2513
2518 if (implFamily == declFamily) return false;
2519
2520
2521
2522
2524
2525
2526 if (impl->isInvalidDecl() || decl->isInvalidDecl()) return true;
2527
2530 unsigned errorID = diag::err_arc_lost_method_convention;
2531 unsigned noteID = diag::note_arc_lost_method_convention;
2532 if (declFamily == OMF_None) {
2533 unmatched = decl;
2534 family = implFamily;
2535 errorID = diag::err_arc_gained_method_convention;
2536 noteID = diag::note_arc_gained_method_convention;
2537 }
2538
2539
2540 enum FamilySelector {
2541 F_alloc, F_copy, F_mutableCopy = F_copy, F_init, F_new
2542 };
2543 FamilySelector familySelector = FamilySelector();
2544
2545 switch (family) {
2546 case OMF_None: llvm_unreachable("logic error, no method convention");
2556
2557
2558 return false;
2559
2560 case OMF_init: familySelector = F_init; break;
2561 case OMF_alloc: familySelector = F_alloc; break;
2562 case OMF_copy: familySelector = F_copy; break;
2563 case OMF_mutableCopy: familySelector = F_mutableCopy; break;
2564 case OMF_new: familySelector = F_new; break;
2565 }
2566
2567 enum ReasonSelector { R_NonObjectReturn, R_UnrelatedReturn };
2568 ReasonSelector reasonSelector;
2569
2570
2571
2573 reasonSelector = R_UnrelatedReturn;
2574 } else {
2575 reasonSelector = R_NonObjectReturn;
2576 }
2577
2578 S.Diag(impl->getLocation(), errorID) << int(familySelector) << int(reasonSelector);
2579 S.Diag(decl->getLocation(), noteID) << int(familySelector) << int(reasonSelector);
2580
2581 return true;
2582}
2583
2586 bool IsProtocolMethodDecl) {
2589 return;
2590
2592 IsProtocolMethodDecl, false, true);
2593
2597 IM != EM && IF != EF; ++IM, ++IF) {
2599 IsProtocolMethodDecl, false, true);
2600 }
2601
2604 diag::warn_conflicting_variadic);
2605 Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
2606 }
2607}
2608
2611 bool IsProtocolMethodDecl) {
2612
2614 true, true);
2615
2619 IM != EM && IF != EF; ++IM, ++IF) {
2621 IsProtocolMethodDecl, true, true);
2622 }
2623
2626 diag::warn_conflicting_overriding_variadic);
2627 Diag(Overridden->getLocation(), diag::note_previous_declaration);
2628 }
2629}
2630
2631
2632
2635 bool IsProtocolMethodDecl) {
2637
2638
2639
2642 return;
2643
2644
2645 if (MethodDecl->hasAttr() ||
2646 MethodDecl->hasAttr())
2647 return;
2648
2650 IsProtocolMethodDecl, false, false);
2655 IM != EM && IF != EF; ++IM, ++IF) {
2657 *IF, IsProtocolMethodDecl, false, false);
2659 break;
2660 }
2666
2669 diag::warn_category_method_impl_match);
2670 Diag(MethodDecl->getLocation(), diag::note_method_declared_at)
2672 }
2673}
2674
2675
2676
2677
2678
2679
2680
2683
2686 if (PDecl->hasAttr())
2688 for (const auto *PI : PDecl->protocols())
2690}
2691
2692
2693
2694
2697 if (!Super)
2698 return;
2699
2702
2704}
2705
2706
2707
2714 : dyn_cast(CDecl);
2715 assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");
2716
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731 if (PDecl->hasAttr()) {
2732 if (!ProtocolsExplictImpl) {
2735 }
2736 if (ProtocolsExplictImpl->contains(PDecl->getIdentifier()))
2737 return;
2738
2739
2740
2741 Super = nullptr;
2742 }
2743
2745
2746
2747
2748
2749
2750
2751
2754 if (InsMap.count(fISelector))
2755
2756
2758 }
2759
2760
2764
2765
2766
2767
2768
2769
2770
2771 if (!NSIDecl)
2773 if (method->getImplementationControl() !=
2775 !method->isPropertyAccessor() &&
2776 !InsMap.count(method->getSelector()) &&
2778 method->getSelector(), true ,
2779 false , true ,
2780 nullptr ))) {
2781
2782
2783
2784
2785
2786
2787
2788
2789
2791 method->getSelector(), true ,
2792 true , false ))
2793 if (C || MethodInClass->isPropertyAccessor())
2794 continue;
2795 unsigned DIAG = diag::warn_unimplemented_protocol_method;
2798 }
2799 }
2800 }
2801
2803 if (method->getImplementationControl() !=
2805 !ClsMap.count(method->getSelector()) &&
2807 method->getSelector(), false ,
2808 false ,
2809 true , nullptr ))) {
2810
2811 if (C && IDecl->lookupMethod(method->getSelector(),
2812 false ,
2813 true ,
2814 false ))
2815 continue;
2816
2817 unsigned DIAG = diag::warn_unimplemented_protocol_method;
2820 }
2821 }
2822 }
2823
2824 for (auto *PI : PDecl->protocols())
2826 ProtocolsExplictImpl);
2827}
2828
2829
2830
2831
2835 ObjCContainerDecl *CDecl, bool &IncompleteImpl, bool ImmediateClass,
2836 bool WarnCategoryMethodImpl) {
2837
2838
2840 if (!InsMapSeen.insert(I->getSelector()).second)
2841 continue;
2842 if (!I->isPropertyAccessor() &&
2843 !InsMap.count(I->getSelector())) {
2844 if (ImmediateClass)
2846 diag::warn_undef_method_impl);
2847 continue;
2848 } else {
2851 assert(CDecl->getInstanceMethod(I->getSelector(), true) &&
2852 "Expected to find the method through lookup as well");
2853
2854 if (ImpMethodDecl) {
2855
2857 continue;
2858 if (!WarnCategoryMethodImpl)
2860 isa(CDecl));
2861 else if (!I->isPropertyAccessor())
2863 }
2864 }
2865 }
2866
2867
2868
2870 if (!ClsMapSeen.insert(I->getSelector()).second)
2871 continue;
2872 if (!I->isPropertyAccessor() &&
2873 !ClsMap.count(I->getSelector())) {
2874 if (ImmediateClass)
2876 diag::warn_undef_method_impl);
2877 } else {
2880 assert(CDecl->getClassMethod(I->getSelector(), true) &&
2881 "Expected to find the method through lookup as well");
2882
2883 if (ImpMethodDecl) {
2884
2886 continue;
2887 if (!WarnCategoryMethodImpl)
2889 isa(CDecl));
2890 else if (!I->isPropertyAccessor())
2892 }
2893 }
2894 }
2895
2896 if (ObjCProtocolDecl *PD = dyn_cast (CDecl)) {
2897
2898
2899 for (auto *PI : PD->protocols())
2901 IMPDecl, PI, IncompleteImpl, false,
2902 WarnCategoryMethodImpl);
2903 }
2904
2905 if (ObjCInterfaceDecl *I = dyn_cast (CDecl)) {
2906
2907
2908
2909 if (!WarnCategoryMethodImpl) {
2910 for (auto *Cat : I->visible_categories())
2912 IMPDecl, Cat, IncompleteImpl,
2913 ImmediateClass && Cat->IsClassExtension(),
2914 WarnCategoryMethodImpl);
2915 } else {
2916
2917 for (auto *Ext : I->visible_extensions())
2919 IMPDecl, Ext, IncompleteImpl, false,
2920 WarnCategoryMethodImpl);
2921 }
2922
2923
2924 for (auto *PI : I->all_referenced_protocols())
2926 IMPDecl, PI, IncompleteImpl, false,
2927 WarnCategoryMethodImpl);
2928
2929
2930
2931 if (!WarnCategoryMethodImpl && I->getSuperClass())
2933 IMPDecl,
2934 I->getSuperClass(), IncompleteImpl, false);
2935 }
2936}
2937
2938
2939
2940
2943
2945 if (!CatDecl)
2946 return;
2948 if (!IDecl)
2949 return;
2952
2954 Selector Sel = I->getSelector();
2955
2956
2957
2958 if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true))
2959 continue;
2960 InsMap.insert(Sel);
2961 }
2962
2963 for (const auto *I : CatIMPDecl->class_methods()) {
2964 Selector Sel = I->getSelector();
2965 if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false))
2966 continue;
2967 ClsMap.insert(Sel);
2968 }
2969 if (InsMap.empty() && ClsMap.empty())
2970 return;
2971
2973 bool IncompleteImpl = false;
2975 CatIMPDecl, IDecl,
2976 IncompleteImpl, false,
2977 true );
2978}
2979
2982 bool IncompleteImpl) {
2984
2985
2987 InsMap.insert(I->getSelector());
2988
2989
2990 for (const auto *PImpl : IMPDecl->property_impls()) {
2991
2993 continue;
2994
2995 const auto *P = PImpl->getPropertyDecl();
2996 if () continue;
2997
2998 InsMap.insert(P->getGetterName());
2999 if (->getSetterName().isNull())
3000 InsMap.insert(P->getSetterName());
3001 }
3002
3003
3004
3005
3006 if (const ObjCInterfaceDecl *IDecl = dyn_cast(CDecl)) {
3007 bool SynthesizeProperties = getLangOpts().ObjCDefaultSynthProperties &&
3009 !IDecl->isObjCRequiresPropertyDefs();
3011 }
3012
3013
3015
3018 ClsMap.insert(I->getSelector());
3019
3020
3021
3024 IMPDecl, CDecl,
3025 IncompleteImpl, true);
3026
3027
3028
3030 dyn_cast(IMPDecl))
3032
3033
3034
3035
3036
3037
3039
3040 if (ObjCInterfaceDecl *I = dyn_cast (CDecl)) {
3041 for (auto *PI : I->all_referenced_protocols())
3043 ClsMap, I, ExplicitImplProtocols);
3044 } else if (ObjCCategoryDecl *C = dyn_cast(CDecl)) {
3045
3046
3047 if (->IsClassExtension()) {
3048 for (auto *P : C->protocols())
3050 ClsMap, CDecl, ExplicitImplProtocols);
3052 false);
3053 }
3054 } else
3055 llvm_unreachable("invalid ObjCContainerDecl type.");
3056}
3057
3061 unsigned NumElts) {
3064 for (unsigned i = 0; i != NumElts; ++i) {
3065
3069 if (PrevDecl && !isa(PrevDecl)) {
3070
3071
3072
3073
3074
3075
3076
3077 TypedefNameDecl *TDD = dyn_cast(PrevDecl);
3079 Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
3080 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
3081 } else {
3082
3083
3084
3085
3087 Diag(AtClassLoc, diag::warn_forward_class_redefinition)
3088 << IdentList[i];
3089 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
3090 continue;
3091 }
3092 }
3093 }
3094
3095
3097 = dyn_cast_or_null(PrevDecl);
3098
3100 if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3114 }
3115
3116
3117
3119 if (PrevIDecl && TypeParams) {
3121
3123 SemaRef, PrevTypeParams, TypeParams,
3124 TypeParamListContext::ForwardDeclaration)) {
3125 TypeParams = nullptr;
3126 }
3128
3129 Diag(IdentLocs[i], diag::err_objc_parameterized_forward_class)
3130 << ClassName
3132 Diag(Def->getLocation(), diag::note_defined_here)
3133 << ClassName;
3134
3135 TypeParams = nullptr;
3136 }
3137 }
3138
3141 PrevIDecl, IdentLocs[i]);
3143
3144 if (PrevIDecl)
3146
3149 DeclsInGroup.push_back(IDecl);
3150 }
3151
3153}
3154
3157 const Type *left, const Type *right);
3158
3162 const Type *left =
3164 const Type *right =
3166
3167 if (left == right) return true;
3168
3169
3171 return false;
3172
3174
3175
3176
3177
3178
3182 return false;
3183
3185 return false;
3186
3187
3188
3189
3190
3191 if (isa(left)) return isa(right);
3192 if (isa(right)) return false;
3193
3194
3195
3196
3197
3200
3201
3202
3211
3212
3213
3214
3215 return (leftSK == rightSK);
3216}
3217
3220 const Type *lt, const Type *rt) {
3221 assert(lt && rt && lt != rt);
3222
3223 if (!isa(lt) || !isa(rt)) return false;
3224 RecordDecl *left = cast(lt)->getDecl();
3225 RecordDecl *right = cast(rt)->getDecl();
3226
3227
3228 if (left->isUnion() != right->isUnion()) return false;
3229
3230
3231 if ((isa(left) && !cast(left)->isPOD()) ||
3232 (isa(right) && !cast(right)->isPOD()))
3233 return false;
3234
3235
3239 return false;
3240
3242 return false;
3243
3244
3247 for (; li != le && ri != re; ++li, ++ri) {
3248 if ((Context, strategy, li->getType(), ri->getType()))
3249 return false;
3250 }
3251 return (li == le && ri == re);
3252}
3253
3254
3255
3256
3263 return false;
3264
3265
3267 return false;
3268
3270 return false;
3271
3273 (left->hasAttr()
3274 != right->hasAttr() ||
3275 left->hasAttr()
3276 != right->hasAttr()))
3277 return false;
3278
3282
3283 for (; li != le && ri != re; ++li, ++ri) {
3284 assert(ri != right->param_end() && "Param mismatch");
3285 const ParmVarDecl *lparm = *li, *rparm = *ri;
3286
3287 if ((Context, strategy, lparm->getType(), rparm->getType()))
3288 return false;
3289
3291 lparm->hasAttr() != rparm->hasAttr())
3292 return false;
3293 }
3294 return true;
3295}
3296
3299 auto *MethodProtocol = dyn_cast(Method->getDeclContext());
3300 auto *MethodInListProtocol =
3301 dyn_cast(MethodInList->getDeclContext());
3302
3303
3304 if ((MethodProtocol && !MethodInListProtocol) ||
3305 (!MethodProtocol && MethodInListProtocol))
3306 return false;
3307
3308 if (MethodProtocol && MethodInListProtocol)
3309 return true;
3310
3314 return MethodInterface == MethodInListInterface;
3315}
3316
3319
3320
3322 dyn_cast(Method->getDeclContext()))
3323 if (!CD->IsClassExtension() && List->getBits() < 2)
3324 List->setBits(List->getBits() + 1);
3325
3326
3327 if (List->getMethod() == nullptr) {
3328 List->setMethod(Method);
3329 List->setNext(nullptr);
3330 return;
3331 }
3332
3333
3334
3337 for (; List; Previous = List, List = List->getNext()) {
3338
3340 continue;
3341
3343 List->getMethod());
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354 if (!SameDeclaration ||
3356
3357
3358
3360 List->setHasMoreThanOneDecl(true);
3361
3362
3363
3364 if (Method->isDeprecated() && SameDeclaration &&
3365 !ListWithSameDeclaration && !List->getMethod()->isDeprecated())
3366 ListWithSameDeclaration = List;
3367
3368 if (Method->isUnavailable() && SameDeclaration &&
3369 !ListWithSameDeclaration &&
3370 List->getMethod()->getAvailability() < AR_Deprecated)
3371 ListWithSameDeclaration = List;
3372 continue;
3373 }
3374
3376
3377
3380 else {
3381
3382
3383
3384
3385 List->setHasMoreThanOneDecl(true);
3386 }
3387
3388
3389
3392 List->setMethod(Method);
3393 }
3394
3395
3398 List->setMethod(Method);
3399 }
3400
3401 return;
3402 }
3403
3404
3405
3407
3408
3409 if (ListWithSameDeclaration) {
3410 auto *List = new (Mem) ObjCMethodList(*ListWithSameDeclaration);
3411
3412 ListWithSameDeclaration->setMethod(Method);
3413 ListWithSameDeclaration->setNext(List);
3414 return;
3415 }
3416
3418}
3419
3420
3421
3425}
3426
3429 return;
3431}
3432
3433void SemaObjC::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
3434 bool instance) {
3435
3436 if (cast(Method->getDeclContext())->isInvalidDecl())
3437 return;
3438
3441
3443
3445
3446 ObjCMethodList &Entry = instance ? Lists.first : Lists.second;
3448}
3449
3450
3451
3452
3453
3454
3458 return false;
3459
3461 return false;
3462
3465 return false;
3466
3467
3468
3470}
3471
3472
3475 if (!TypeBound)
3476 return true;
3477
3479
3480 return true;
3481
3482 auto *BoundInterface = TypeBound->getInterface();
3483 assert(BoundInterface && "unexpected object type!");
3484
3485
3486
3487 auto *MethodProtocol = dyn_cast(Method->getDeclContext());
3488 if (MethodProtocol) {
3489 return true;
3490 }
3491
3492
3493
3495
3496
3497
3498 return MethodInterface == BoundInterface ||
3499 MethodInterface->isSuperClassOf(BoundInterface) ||
3500 BoundInterface->isSuperClassOf(MethodInterface);
3501 }
3502 llvm_unreachable("unknown method context");
3503}
3504
3505
3506
3509 bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound) {
3512
3513 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3515 return false;
3516
3517
3518 ObjCMethodList &MethList = InstanceFirst ? Pos->second.first :
3519 Pos->second.second;
3521 if (M->getMethod() && M->getMethod()->isUnconditionallyVisible()) {
3523 Methods.push_back(M->getMethod());
3524 }
3525
3526
3527 if (!Methods.empty())
3528 return Methods.size() > 1;
3529
3530 if (!CheckTheOther)
3531 return false;
3532
3533
3534 ObjCMethodList &MethList2 = InstanceFirst ? Pos->second.second :
3535 Pos->second.first;
3537 if (M->getMethod() && M->getMethod()->isUnconditionallyVisible()) {
3539 Methods.push_back(M->getMethod());
3540 }
3541
3542 return Methods.size() > 1;
3543}
3544
3548
3550 FilteredMethods.push_back(BestMethod);
3551
3552 for (auto *M : Methods)
3553 if (M != BestMethod && !M->hasAttr())
3554 FilteredMethods.push_back(M);
3555
3556 if (FilteredMethods.size() > 1)
3558 receiverIdOrClass);
3559
3560 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3561
3562
3564 return true;
3566 BestMethod->isInstanceMethod() ? Pos->second.first : Pos->second.second;
3568}
3569
3571 bool receiverIdOrClass,
3572 bool instance) {
3575
3576 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3578 return nullptr;
3579
3580
3581 ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
3584 if (M->getMethod() && M->getMethod()->isUnconditionallyVisible())
3585 return M->getMethod();
3586 }
3587 return nullptr;
3588}
3589
3592 bool receiverIdOrClass) {
3593
3594 bool issueDiagnostic = false, issueError = false;
3595
3596
3597
3598 bool strictSelectorMatch =
3599 receiverIdOrClass &&
3602 if (strictSelectorMatch) {
3603 for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
3605 issueDiagnostic = true;
3606 break;
3607 }
3608 }
3609 }
3610
3611
3612
3613
3614 if (!strictSelectorMatch ||
3615 (issueDiagnostic && getLangOpts().ObjCAutoRefCount))
3616 for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
3617
3620 issueDiagnostic = true;
3622 issueError = true;
3623 break;
3624 }
3625 }
3626
3627 if (issueDiagnostic) {
3628 if (issueError)
3629 Diag(R.getBegin(), diag::err_arc_multiple_method_decl) << Sel << R;
3630 else if (strictSelectorMatch)
3631 Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;
3632 else
3633 Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
3634
3635 Diag(Methods[0]->getBeginLoc(),
3636 issueError ? diag::note_possibility : diag::note_using)
3637 << Methods[0]->getSourceRange();
3638 for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
3639 Diag(Methods[I]->getBeginLoc(), diag::note_also_found)
3640 << Methods[I]->getSourceRange();
3641 }
3642 }
3643}
3644
3646 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3648 return nullptr;
3649
3650 auto &Methods = Pos->second;
3651 for (const ObjCMethodList *Method = &Methods.first; Method;
3652 Method = Method->getNext())
3653 if (Method->getMethod() &&
3654 (Method->getMethod()->isDefined() ||
3656 return Method->getMethod();
3657
3658 for (const ObjCMethodList *Method = &Methods.second; Method;
3659 Method = Method->getNext())
3660 if (Method->getMethod() &&
3661 (Method->getMethod()->isDefined() ||
3663 return Method->getMethod();
3664 return nullptr;
3665}
3666
3667static void
3671 const unsigned MaxEditDistance = 1;
3672 unsigned BestEditDistance = MaxEditDistance + 1;
3674
3675 unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size());
3676 if (MinPossibleEditDistance > 0 &&
3677 Typo.size() / MinPossibleEditDistance < 1)
3678 return;
3679 unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance);
3680 if (EditDistance > MaxEditDistance)
3681 return;
3682 if (EditDistance == BestEditDistance)
3683 BestMethod.push_back(Method);
3684 else if (EditDistance < BestEditDistance) {
3685 BestMethod.clear();
3686 BestMethod.push_back(Method);
3687 }
3688}
3689
3692 if (ObjectType.isNull())
3693 return true;
3695 true ))
3696 return true;
3698 false ) != nullptr;
3699}
3700
3703 unsigned NumArgs = Sel.getNumArgs();
3705 bool ObjectIsId = true, ObjectIsClass = true;
3706 if (ObjectType.isNull())
3707 ObjectIsId = ObjectIsClass = false;
3709 return nullptr;
3712 ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
3713 ObjectIsId = ObjectIsClass = false;
3714 }
3716 ObjectIsClass = false;
3718 ObjectIsId = false;
3719 else
3720 return nullptr;
3721
3722 for (GlobalMethodPool::iterator b = MethodPool.begin(),
3724
3725 for (ObjCMethodList *M = &b->second.first; M; M=M->getNext())
3726 if (M->getMethod() &&
3727 (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&
3728 (M->getMethod()->getSelector() != Sel)) {
3729 if (ObjectIsId)
3730 Methods.push_back(M->getMethod());
3731 else if (!ObjectIsClass &&
3733 SemaRef, M->getMethod()->getSelector(), ObjectType))
3734 Methods.push_back(M->getMethod());
3735 }
3736
3737 for (ObjCMethodList *M = &b->second.second; M; M=M->getNext())
3738 if (M->getMethod() &&
3739 (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&
3740 (M->getMethod()->getSelector() != Sel)) {
3741 if (ObjectIsClass)
3742 Methods.push_back(M->getMethod());
3743 else if (!ObjectIsId &&
3745 SemaRef, M->getMethod()->getSelector(), ObjectType))
3746 Methods.push_back(M->getMethod());
3747 }
3748 }
3749
3751 for (unsigned i = 0, e = Methods.size(); i < e; i++) {
3754 }
3755 return (SelectedMethods.size() == 1) ? SelectedMethods[0] : nullptr;
3756}
3757
3758
3759
3760
3761
3762
3765 for (auto *Ivar : ID->ivars()) {
3766 if (Ivar->isInvalidDecl())
3767 continue;
3770 if (prevIvar) {
3771 Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
3772 Diag(prevIvar->getLocation(), diag::note_previous_declaration);
3773 Ivar->setInvalidDecl();
3774 }
3775 }
3776 }
3777}
3778
3779
3782
3783 for (auto ivar = ID->getClassInterface()->all_declared_ivar_begin();
3784 ivar; ivar = ivar->getNextIvar()) {
3785 if (ivar->isInvalidDecl()) continue;
3788 S.Diag(ivar->getLocation(), diag::err_arc_weak_disabled);
3789 } else {
3790 S.Diag(ivar->getLocation(), diag::err_arc_weak_no_runtime);
3791 }
3792 }
3793 }
3794}
3795
3796
3800 return;
3801
3802 for (auto ivar = ID->all_declared_ivar_begin(); ivar;
3803 ivar = ivar->getNextIvar()) {
3804 if (ivar->isInvalidDecl())
3805 continue;
3806 QualType IvarTy = ivar->getType();
3810 S.Diag(ivar->getLocation(), diag::err_flexible_array_arc_retainable);
3811 ivar->setInvalidDecl();
3812 }
3813 }
3814}
3815
3818 case Decl::ObjCInterface:
3820 case Decl::ObjCProtocol:
3822 case Decl::ObjCCategory:
3823 if (cast(SemaRef.CurContext)->IsClassExtension())
3826 case Decl::ObjCImplementation:
3828 case Decl::ObjCCategoryImpl:
3830
3831 default:
3833 }
3834}
3835
3838 return true;
3840 return (RecordTy && RecordTy->getDecl()->hasFlexibleArrayMember());
3841}
3842
3847 if ((IntfDecl = dyn_cast(OCD))) {
3848 Ivars = IntfDecl->ivars();
3849 } else if (auto *ImplDecl = dyn_cast(OCD)) {
3850 IntfDecl = ImplDecl->getClassInterface();
3851 Ivars = ImplDecl->ivars();
3852 } else if (auto *CategoryDecl = dyn_cast(OCD)) {
3853 if (CategoryDecl->IsClassExtension()) {
3854 IntfDecl = CategoryDecl->getClassInterface();
3855 Ivars = CategoryDecl->ivars();
3856 }
3857 }
3858
3859
3860 if (!isa(OCD)) {
3861 for (auto *ivar : Ivars) {
3863 S.Diag(ivar->getLocation(), diag::warn_variable_sized_ivar_visibility)
3864 << ivar->getDeclName() << ivar->getType();
3865 }
3866 }
3867 }
3868
3869
3870 if (!IntfDecl)
3871 return;
3872
3873
3876 if (ivar->isInvalidDecl() || !ivar->getNextIvar())
3877 continue;
3878 QualType IvarTy = ivar->getType();
3879 bool IsInvalidIvar = false;
3881 S.Diag(ivar->getLocation(), diag::err_flexible_array_not_at_end)
3882 << ivar->getDeclName() << IvarTy
3883 << llvm::to_underlying(TagTypeKind::Class);
3884 IsInvalidIvar = true;
3886 if (RecordTy->getDecl()->hasFlexibleArrayMember()) {
3887 S.Diag(ivar->getLocation(),
3888 diag::err_objc_variable_sized_type_not_at_end)
3889 << ivar->getDeclName() << IvarTy;
3890 IsInvalidIvar = true;
3891 }
3892 }
3893 if (IsInvalidIvar) {
3894 S.Diag(ivar->getNextIvar()->getLocation(),
3895 diag::note_next_ivar_declaration)
3896 << ivar->getNextIvar()->getSynthesize();
3897 ivar->setInvalidDecl();
3898 }
3899 }
3900
3901
3902
3903
3905 (Ivars.begin() == Ivars.end()) ? nullptr : *Ivars.begin();
3908 while (SuperClass && SuperClass->ivar_empty())
3910 if (SuperClass) {
3911 auto IvarIter = SuperClass->ivar_begin();
3912 std::advance(IvarIter, SuperClass->ivar_size() - 1);
3916 diag::warn_superclass_variable_sized_type_not_at_end)
3919 S.Diag(LastIvar->getLocation(), diag::note_entity_declared_at)
3921 }
3922 }
3923 }
3924}
3925
3928
3931 const llvm::iterator_rangeObjCProtocolList::iterator &Protocols) {
3932 for (auto *PI : Protocols)
3934}
3935
3940
3943 for (auto *MD : PDecl->methods()) {
3944 if (!MD->isPropertyAccessor()) {
3945 if (const auto *CMD =
3946 IDecl->getMethod(MD->getSelector(), MD->isInstanceMethod())) {
3947 if (CMD->isDirectMethod())
3948 DirectMembers.push_back(CMD);
3949 }
3950 }
3951 }
3952 for (auto *PD : PDecl->properties()) {
3953 if (const auto *CPD = IDecl->FindPropertyVisibleInPrimaryClass(
3954 PD->getIdentifier(),
3955 PD->isClassProperty()
3958 if (CPD->isDirectProperty())
3959 DirectMembers.push_back(CPD);
3960 }
3961 }
3962 if (!DirectMembers.empty()) {
3963 S.Diag(CDecl->getLocation(), diag::err_objc_direct_protocol_conformance)
3965 for (const auto *MD : DirectMembers)
3966 S.Diag(MD->getLocation(), diag::note_direct_member_here);
3967 return;
3968 }
3969
3970
3973}
3974
3975
3981 return nullptr;
3982
3983 assert(AtEnd.isValid() && "Invalid location for '@end'");
3984
3986 Decl *ClassDecl = OCD;
3987
3988 bool isInterfaceDeclKind =
3989 isa(ClassDecl) || isa(ClassDecl)
3990 || isa(ClassDecl);
3991 bool checkIdenticalMethods = isa(ClassDecl);
3992
3993
3994
3995
3996
3997 if (auto *OID = dyn_cast(SemaRef.CurContext)) {
3998 for (auto *PropImpl : OID->property_impls()) {
3999 if (auto *Getter = PropImpl->getGetterMethodDecl())
4000 if (Getter->isSynthesizedAccessorStub())
4001 OID->addDecl(Getter);
4002 if (auto *Setter = PropImpl->getSetterMethodDecl())
4003 if (Setter->isSynthesizedAccessorStub())
4004 OID->addDecl(Setter);
4005 }
4006 }
4007
4008
4009 llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
4010 llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
4011
4012 for (unsigned i = 0, e = allMethods.size(); i != e; i++ ) {
4014 cast_or_null(allMethods[i]);
4015
4016 if (!Method) continue;
4018
4021 : false;
4022 if ((isInterfaceDeclKind && PrevMethod && )
4023 || (checkIdenticalMethods && match)) {
4024 Diag(Method->getLocation(), diag::err_duplicate_method_decl)
4026 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
4028 } else {
4029 if (PrevMethod) {
4033 Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
4035 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
4036 }
4038
4040 }
4041 } else {
4042
4045 : false;
4046 if ((isInterfaceDeclKind && PrevMethod && )
4047 || (checkIdenticalMethods && match)) {
4048 Diag(Method->getLocation(), diag::err_duplicate_method_decl)
4050 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
4052 } else {
4053 if (PrevMethod) {
4057 Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
4059 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
4060 }
4063 }
4064 }
4065 }
4066 if (isa(ClassDecl)) {
4067
4068 } else if (ObjCCategoryDecl *C = dyn_cast(ClassDecl)) {
4069
4070
4071
4072
4073 if (C->IsClassExtension()) {
4076 }
4077
4079 C->protocols());
4080 }
4081 if (ObjCContainerDecl *CDecl = dyn_cast(ClassDecl)) {
4082 if (CDecl->getIdentifier())
4083
4084
4085
4086 for (auto *I : CDecl->properties())
4088 CDecl->setAtEndRange(AtEnd);
4089 }
4091 IC->setAtEndRange(AtEnd);
4093
4094
4095
4096
4097
4098 for (const auto *Ext : IDecl->visible_extensions()) {
4099 for (const auto *Property : Ext->instance_properties()) {
4100
4102 = IC->FindPropertyImplDecl(Property->getIdentifier(),
4104 if (PIDecl->getPropertyImplementation()
4106 continue;
4107
4108 for (const auto *Ext : IDecl->visible_extensions()) {
4110 Ext->getInstanceMethod(Property->getGetterName()))
4111 GetterMethod->setPropertyAccessor(true);
4112 if (->isReadOnly())
4114 = Ext->getInstanceMethod(Property->getSetterName()))
4115 SetterMethod->setPropertyAccessor(true);
4116 }
4117 }
4118 }
4123 if (IDecl->hasDesignatedInitializers())
4127
4128 bool HasRootClassAttr = IDecl->hasAttr();
4129 if (IDecl->getSuperClass() == nullptr) {
4130
4131
4132 if (!HasRootClassAttr) {
4135 Diag(DeclLoc, diag::warn_objc_root_class_missing)
4136 << IDecl->getIdentifier();
4137
4138
4142 ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null(IF);
4143 if (NSObjectDecl && NSObjectDecl->getDefinition()) {
4144 Diag(SuperClassLoc, diag::note_objc_needs_superclass)
4146 } else {
4147 Diag(SuperClassLoc, diag::note_objc_needs_superclass);
4148 }
4149 }
4150 } else if (HasRootClassAttr) {
4151
4152 Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass);
4153 }
4154
4156
4157
4158
4159
4160 if (IDecl->hasAttr() &&
4161 Super->hasAttr()) {
4162 Diag(IC->getLocation(), diag::err_restricted_superclass_mismatch);
4163 Diag(Super->getLocation(), diag::note_class_declared);
4164 }
4165 }
4166
4167 if (IDecl->hasAttr())
4168 Diag(IC->getLocation(), diag::err_implementation_of_class_stub);
4169
4171 while (IDecl->getSuperClass()) {
4173 IDecl = IDecl->getSuperClass();
4174 }
4175 }
4176 }
4179 dyn_cast(ClassDecl)) {
4180 CatImplClass->setAtEndRange(AtEnd);
4181
4182
4183
4184 if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) {
4186 = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier())) {
4188 }
4189 }
4190 } else if (const auto *IntfDecl = dyn_cast(ClassDecl)) {
4192 if (!IntfDecl->hasAttr() &&
4193 Super->hasAttr()) {
4194 Diag(IntfDecl->getLocation(), diag::err_restricted_superclass_mismatch);
4195 Diag(Super->getLocation(), diag::note_class_declared);
4196 }
4197 }
4198
4199 if (IntfDecl->hasAttr() &&
4200 !IntfDecl->hasAttr())
4201 Diag(IntfDecl->getLocation(), diag::err_class_stub_subclassing_mismatch);
4202 }
4204 if (isInterfaceDeclKind) {
4205
4206 for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
4209 if (VarDecl *VDecl = dyn_cast(*I)) {
4210 if (!VDecl->hasExternalStorage())
4211 Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass);
4212 }
4213 }
4214 }
4216
4217 for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
4220 (*I)->setTopLevelDeclInObjCContainer();
4222 }
4223
4225 return ClassDecl;
4226}
4227
4228
4229
4233}
4234
4235
4236
4237
4242
4243
4244
4245
4248
4249 if (ResultObjectType->isObjCIdType() ||
4250 ResultObjectType->isObjCQualifiedIdType())
4252
4253 if (CurrentClass) {
4255 = ResultObjectType->getInterfaceDecl()) {
4256
4259
4260
4261 if (ResultClass->isSuperClassOf(CurrentClass))
4263 }
4264 } else {
4265
4266
4268 }
4269 }
4270
4272}
4273
4274namespace {
4275
4276
4277class OverrideSearch {
4278public:
4281 bool Recursive;
4282
4283public:
4284 OverrideSearch(Sema &S, const ObjCMethodDecl *method) : Method(method) {
4286
4287
4288
4289 SemaObjC::GlobalMethodPool::iterator it =
4294
4297 return;
4298 }
4300 method->isInstanceMethod() ? it->second.first : it->second.second;
4302
4304 = cast(method->getDeclContext());
4305
4306
4307
4308
4310 dyn_cast(container)) {
4311 searchFromContainer(container);
4314 } else {
4315 searchFromContainer(container);
4316 }
4317 }
4318
4319 typedef decltype(Overridden)::iterator iterator;
4320 iterator begin() const { return Overridden.begin(); }
4321 iterator end() const { return Overridden.end(); }
4322
4323private:
4326
4328#define OBJCCONTAINER(type, base) \
4329 case Decl::type: \
4330 searchFrom(cast<type##Decl>(container)); \
4331 break;
4332#define ABSTRACT_DECL(expansion)
4333#define DECL(type, base) \
4334 case Decl::type:
4335#include "clang/AST/DeclNodes.inc"
4336 llvm_unreachable("not an ObjC container!");
4337 }
4338 }
4339
4342 return;
4343
4344
4345
4347 }
4348
4350
4351
4352
4354 }
4355
4357
4358
4359
4361 search(category);
4364
4365
4368 }
4369 }
4370
4372
4374 return;
4375
4376
4378 search(Cat);
4379
4380
4382 search(super);
4383
4384
4386 }
4387
4389
4390
4393 }
4394
4396 for (const auto *Proto : protocols)
4397 search(Proto);
4398 }
4399
4401
4404 true);
4405
4406
4407 if (meth) {
4408 Overridden.insert(meth);
4409 return;
4410 }
4411
4412
4413
4414
4415
4416 Recursive = true;
4417
4418 searchFromContainer(container);
4419 }
4420};
4421}
4422
4426 const auto *attr = overridden->getAttr();
4427 Diag(method->getLocation(), diag::err_objc_override_direct_method);
4428 Diag(attr->getLocation(), diag::note_previous_declaration);
4430 const auto *attr = method->getAttr();
4431 Diag(attr->getLocation(), diag::err_objc_direct_on_override)
4432 << isa(overridden->getDeclContext());
4433 Diag(overridden->getLocation(), diag::note_previous_declaration);
4434 }
4435}
4436
4441 if (!ObjCMethod)
4442 return;
4443 auto IsMethodInCurrentClass = [CurrentClass](const ObjCMethodDecl *M) {
4444
4445 return M->getClassInterface()->getCanonicalDecl() ==
4447 };
4448
4449 OverrideSearch overrides(SemaRef, ObjCMethod);
4450
4451
4452
4453
4454
4455 bool hasOverriddenMethodsInBaseOrProtocol = false;
4457 if (!hasOverriddenMethodsInBaseOrProtocol) {
4458 if (isa(overridden->getDeclContext()) ||
4459 !IsMethodInCurrentClass(overridden) || overridden->isOverriding()) {
4461 hasOverriddenMethodsInBaseOrProtocol = true;
4462 } else if (isa(ObjCMethod->getDeclContext())) {
4463
4464
4465
4466
4467
4468
4469
4470 GlobalMethodPool::iterator It =
4474 ObjCMethod->isInstanceMethod()? It->second.first: It->second.second;
4475 unsigned CategCount = List.getBits();
4476 if (CategCount > 0) {
4477
4478
4479 if (CategCount > 1 ||
4480 !isa(overridden->getDeclContext())) {
4481 OverrideSearch overrides(SemaRef, overridden);
4483 if (isa(SuperOverridden->getDeclContext()) ||
4484 !IsMethodInCurrentClass(SuperOverridden)) {
4486 hasOverriddenMethodsInBaseOrProtocol = true;
4487 overridden->setOverriding(true);
4488 break;
4489 }
4490 }
4491 }
4492 }
4493 }
4494 }
4495 }
4496
4497
4500
4501
4503
4504 if (ObjCMethod->isImplicit() && overridden->isImplicit())
4505 continue;
4506
4507
4508 if (isa(ObjCMethod->getDeclContext()) ||
4509 isa(ObjCMethod->getDeclContext()))
4511 isa(overridden->getDeclContext()));
4512
4513 if (CurrentClass && overridden->getDeclContext() != CurrentClass &&
4514 isa(overridden->getDeclContext()) &&
4515 !overridden->isImplicit() ) {
4519 PrevE = overridden->param_end();
4520 for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) {
4521 assert(PrevI != overridden->param_end() && "Param mismatch");
4524
4525
4527 Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super)
4528 << T1 << T2;
4529 Diag(overridden->getLocation(), diag::note_previous_declaration);
4530 break;
4531 }
4532 }
4533 }
4534 }
4535
4536 ObjCMethod->setOverriding(hasOverriddenMethodsInBaseOrProtocol);
4537}
4538
4539
4540
4543 bool usesCSKeyword,
4546 bool prevUsesCSKeyword) {
4547
4548 auto nullability = type->getNullability();
4550
4551
4552 if (nullability.has_value() == prevNullability.has_value()) {
4553
4554 if (!nullability)
4555 return type;
4556
4557
4558 if (*nullability == *prevNullability)
4559 return type;
4560
4561
4562 S.Diag(loc, diag::err_nullability_conflicting)
4565 return type;
4566 }
4567
4568
4569 if (nullability)
4570 return type;
4571
4572
4574}
4575
4576
4577
4578
4582
4583 if (prevMethod->hasAttr() &&
4584 !method->hasAttr()) {
4585
4587 ObjCRequiresSuperAttr::CreateImplicit(S.Context,
4589 }
4590
4591
4601
4602
4603 unsigned numParams = method->param_size();
4604 unsigned numPrevParams = prevMethod->param_size();
4605 for (unsigned i = 0, n = std::min(numParams, numPrevParams); i != n; ++i) {
4608
4609
4616 param->setType(newParamType);
4617 }
4618}
4619
4620
4621
4625 llvm::Triple::x86 &&
4626 "x86-specific check invoked for a different target");
4630 if (P->getType()->isVectorType()) {
4633 break;
4634 }
4635 }
4640 } else
4641 return;
4642 }
4643
4644
4645
4647 VersionTuple AcceptedInVersion;
4648 if (Triple.getOS() == llvm::Triple::IOS)
4649 AcceptedInVersion = VersionTuple(9);
4650 else if (Triple.isMacOSX())
4651 AcceptedInVersion = VersionTuple(10, 11);
4652 else
4653 return;
4655 AcceptedInVersion)
4656 return;
4657 SemaRef.Diag(Loc, diag::err_objc_method_unsupported_param_ret_type)
4659 : 0)
4660 << (Triple.isMacOSX() ? "macOS 10.11" : "iOS 9");
4661}
4662
4665 CD->hasAttr()) {
4668 }
4669}
4670
4676 bool diagnosed = false;
4677
4679 if (diagnosed || IMD->isImplicit())
4680 return;
4681 if (Method->isDirectMethod() || IMD->isDirectMethod()) {
4682 S.Diag(Method->getLocation(), diag::err_objc_direct_duplicate_decl)
4683 << Method->isDirectMethod() << 0 << IMD->isDirectMethod()
4685 S.Diag(IMD->getLocation(), diag::note_previous_declaration);
4686 diagnosed = true;
4687 }
4688 };
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703 if (auto *IMD = IDecl->getMethod(Sel, isInstance))
4704 diagClash(IMD);
4706 if (Impl != ImpDecl)
4708 diagClash(IMD);
4709
4711 if (auto *IMD = Cat->getMethod(Sel, isInstance))
4712 diagClash(IMD);
4713 else if (auto CatImpl = Cat->getImplementation())
4714 if (CatImpl != ImpDecl)
4715 if (auto *IMD = Cat->getMethod(Sel, isInstance))
4716 diagClash(IMD);
4717}
4718
4721 int ParamIndex,
4722 bool MethodDefinition) {
4726
4727 if (!ArgInfo.Type) {
4729 DI = nullptr;
4730 } else {
4732 }
4739 if (S->isDeclScope(PrevDecl)) {
4741 (MethodDefinition ? diag::warn_method_param_redefinition
4742 : diag::warn_method_param_declaration))
4743 << ArgInfo.Name;
4744 Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
4745 }
4746 }
4749
4750
4751
4752
4759
4760
4763 if (Param->hasAttr()) {
4764 Diag(Param->getLocation(), diag::err_block_on_nonlocal);
4766 }
4767
4768 S->AddDecl(Param);
4770 return Param;
4771}
4772
4777
4778
4780 unsigned CNumArgs,
4782 bool isVariadic, bool MethodDefinition) {
4784
4786 Diag(MethodLoc, diag::err_missing_method_context);
4787 return nullptr;
4788 }
4789
4792
4793 bool HasRelatedResultType = false;
4795 if (ReturnType) {
4797
4799 return nullptr;
4800
4801 QualType bareResultType = resultDeclType;
4803 HasRelatedResultType = (bareResultType == Context.getObjCInstanceType());
4804 } else {
4806 Diag(MethodLoc, diag::warn_missing_method_return_type)
4808 }
4809
4811 Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo,
4813 false, false,
4814 false, false,
4815 MethodDeclKind == tok::objc_optional
4818 HasRelatedResultType);
4819
4821 for (unsigned I = 0; I < Sel.getNumArgs(); ++I) {
4825 Params.push_back(Param);
4826 }
4827
4828 for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
4829 ParmVarDecl *Param = cast(CParamInfo[i].Param);
4831 if (ArgType.isNull())
4833 else
4834
4836
4838 Params.push_back(Param);
4839 }
4840
4841 ObjCMethod->setMethodParams(Context, Params, SelectorLocs);
4844
4848
4849
4851 if (ObjCImplDecl *ImpDecl = dyn_cast(ClassDecl)) {
4852 if (MethodType == tok::minus) {
4853 PrevMethod = ImpDecl->getInstanceMethod(Sel);
4854 ImpDecl->addInstanceMethod(ObjCMethod);
4855 } else {
4856 PrevMethod = ImpDecl->getClassMethod(Sel);
4857 ImpDecl->addClassMethod(ObjCMethod);
4858 }
4859
4860
4861
4862
4863
4864
4866 if (auto *Setter = PropertyImpl->getSetterMethodDecl())
4867 if (Setter->getSelector() == Sel &&
4868 Setter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) {
4869 assert(Setter->isSynthesizedAccessorStub() && "autosynth stub expected");
4870 PropertyImpl->setSetterMethodDecl(ObjCMethod);
4871 }
4872 if (auto *Getter = PropertyImpl->getGetterMethodDecl())
4873 if (Getter->getSelector() == Sel &&
4874 Getter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) {
4875 assert(Getter->isSynthesizedAccessorStub() && "autosynth stub expected");
4876 PropertyImpl->setGetterMethodDecl(ObjCMethod);
4877 break;
4878 }
4879 }
4880
4881
4882
4883
4884
4885
4886
4890 const auto *attr = CanonicalMD->getAttr();
4892 ObjCDirectAttr::CreateImplicit(Context, attr->getLocation()));
4893 }
4894 }
4895
4896
4897
4899 if (auto *IMD = IDecl->lookupMethod(ObjCMethod->getSelector(),
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919 if (IDecl == IMD->getClassInterface()) {
4920 auto diagContainerMismatch = [&] {
4921 int decl = 0, impl = 0;
4922
4923 if (auto *Cat = dyn_cast(IMD->getDeclContext()))
4924 decl = Cat->IsClassExtension() ? 1 : 2;
4925
4926 if (isa(ImpDecl))
4927 impl = 1 + (decl != 0);
4928
4930 diag::err_objc_direct_impl_decl_mismatch)
4931 << decl << impl;
4932 Diag(IMD->getLocation(), diag::note_previous_declaration);
4933 };
4934
4936 const auto *attr = ObjCMethod->getAttr();
4938 diagContainerMismatch();
4939 } else if (!IMD->isDirectMethod()) {
4940 Diag(attr->getLocation(), diag::err_objc_direct_missing_on_decl);
4941 Diag(IMD->getLocation(), diag::note_previous_declaration);
4942 }
4943 } else if (IMD->isDirectMethod()) {
4944 const auto *attr = IMD->getAttr();
4946 diagContainerMismatch();
4947 } else {
4949 ObjCDirectAttr::CreateImplicit(Context, attr->getLocation()));
4950 }
4951 }
4952 }
4953
4954
4955 if (isa(ImpDecl) && IMD->isOverriding() &&
4957 Diag(ObjCMethod->getLocation(), diag::warn_dealloc_in_category)
4959 }
4960 } else {
4963 }
4964
4965
4966
4967
4968 for (auto *C : IDecl->visible_categories())
4969 for (auto &P : C->protocols())
4970 if (auto *IMD = P->lookupMethod(ObjCMethod->getSelector(),
4972 assert(ObjCMethod->parameters().size() ==
4973 IMD->parameters().size() &&
4974 "Methods have different number of parameters");
4975 auto OI = IMD->param_begin(), OE = IMD->param_end();
4977 for (; OI != OE; ++OI, ++NI)
4979 }
4980 }
4981 } else {
4982 if (!isa(ClassDecl)) {
4984
4985 ObjCInterfaceDecl *IDecl = dyn_cast(ClassDecl);
4986 if (!IDecl)
4987 IDecl = cast(ClassDecl)->getClassInterface();
4988
4989
4990
4991 if (IDecl)
4993 }
4994
4995 cast(ClassDecl)->addDecl(ObjCMethod);
4996 }
4997
4998 if (PrevMethod) {
4999
5000 Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl)
5002 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
5004 return ObjCMethod;
5005 }
5006
5007
5008
5009
5010 ObjCInterfaceDecl *CurrentClass = dyn_cast(ClassDecl);
5011 if (!CurrentClass) {
5012 if (ObjCCategoryDecl *Cat = dyn_cast(ClassDecl))
5013 CurrentClass = Cat->getClassInterface();
5014 else if (ObjCImplDecl *Impl = dyn_cast(ClassDecl))
5015 CurrentClass = Impl->getClassInterface();
5017 = dyn_cast(ClassDecl))
5018 CurrentClass = CatImpl->getClassInterface();
5019 }
5020
5023
5025
5026 bool ARCError = false;
5029
5030
5033 getLangOpts().ObjCInferRelatedResultType) {
5034 bool InferRelatedResultType = false;
5045 break;
5046
5049 InferRelatedResultType = ObjCMethod->isClassMethod();
5050 break;
5051
5057 break;
5058 }
5059
5060 if (InferRelatedResultType &&
5063 }
5064
5065 if (MethodDefinition &&
5068
5069
5070
5071 if (const auto *attr = ObjCMethod->getAttr()) {
5074 Diag(attr->getLocation(), diag::warn_availability_on_static_initializer)
5075 << 0;
5076 ObjCMethod->dropAttr();
5077 }
5078 }
5079
5080
5082
5084
5085 return ObjCMethod;
5086}
5087
5089
5090
5092 return false;
5093
5094
5095
5096 if (isa(
5098 return false;
5099
5100 Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
5102
5103 return true;
5104}
5105
5106
5107
5112
5115 Diag(DeclStart, diag::err_undef_interface) << ClassName;
5116 return;
5117 }
5119 Diag(DeclStart, diag::err_atdef_nonfragile_interface);
5120 return;
5121 }
5122
5123
5126
5127 for (unsigned i = 0; i < Ivars.size(); i++) {
5131 ID->getLocation(),
5132 ID->getLocation(),
5133 ID->getIdentifier(), ID->getType(),
5134 ID->getBitWidth());
5135 Decls.push_back(FD);
5136 }
5137
5138
5141 FieldDecl *FD = cast(*D);
5145 Record->addDecl(FD);
5146 }
5147}
5148
5149
5156
5157
5158
5159
5161 Diag(IdLoc, diag::err_arg_with_address_space);
5163 }
5164
5165
5166
5168
5170
5173 Diag(IdLoc, diag::err_illegal_qualifiers_on_catch_parm);
5175
5178 Diag(IdLoc, diag::err_catch_param_not_objc_type);
5181 Diag(IdLoc, diag::err_catch_param_not_objc_type);
5182 }
5183
5187
5188
5191
5194 return New;
5195}
5196
5198 const DeclSpec &DS = D.getDeclSpec();
5199
5200
5201
5208 }
5212 if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
5213 Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
5214 diag::err_invalid_thread)
5216 D.getMutableDeclSpec().ClearStorageClassSpecs();
5217
5219
5220
5221
5224
5227
5230 D.getIdentifierLoc(),
5231 D.getIdentifier(),
5232 D.isInvalidType());
5233
5234
5235 if (D.getCXXScopeSpec().isSet()) {
5236 Diag(D.getIdentifierLoc(), diag::err_qualified_objc_catch_parm)
5237 << D.getCXXScopeSpec().getRange();
5239 }
5240
5241
5242 S->AddDecl(New);
5243 if (D.getIdentifier())
5245
5247
5248 if (New->hasAttr())
5250 return New;
5251}
5252
5253
5254
5262 Ivars.push_back(Iv);
5263 }
5264}
5265
5268
5272 for (unsigned I = 0, N = Sels.size(); I != N; ++I)
5274 }
5275
5276
5277
5278
5281 return;
5283 Selector Sel = SelectorAndLocation.first;
5286 Diag(Loc, diag::warn_unimplemented_selector) << Sel;
5287 }
5288}
5289
5294 return nullptr;
5296 if (!IDecl)
5297 return nullptr;
5299 false,
5300 false);
5302 return nullptr;
5305
5306
5307
5308 IV = const_cast<ObjCInterfaceDecl *>(IDecl)->lookupInstanceVariable(
5309 IV->getIdentifier());
5310 return IV;
5311 }
5312 return nullptr;
5313}
5314
5315namespace {
5316
5317
5319public:
5323 bool AccessedIvar;
5324 bool InvokedSelfMethod;
5325
5328 : S(S), Method(Method), IvarD(IvarD), AccessedIvar(false),
5329 InvokedSelfMethod(false) {
5330 assert(IvarD);
5331 }
5332
5334 if (E->getDecl() == IvarD) {
5335 AccessedIvar = true;
5336 return false;
5337 }
5338 return true;
5339 }
5340
5343 S.ObjC().isSelfExpr(E->getInstanceReceiver(), Method)) {
5344 InvokedSelfMethod = true;
5345 }
5346 return true;
5347 }
5348};
5349}
5350
5353 if (S->hasUnrecoverableErrorOccurred())
5354 return;
5355
5357 unsigned DIAG = diag::warn_unused_property_backing_ivar;
5360 continue;
5361
5364 if (!IV)
5365 continue;
5366
5367 if (CurMethod->isSynthesizedAccessorStub())
5368 continue;
5369
5370 UnusedBackingIvarChecker Checker(SemaRef, CurMethod, IV);
5371 Checker.TraverseStmt(CurMethod->getBody());
5372 if (Checker.AccessedIvar)
5373 continue;
5374
5375
5376
5377
5378
5379 if (!IV->isReferenced() || !Checker.InvokedSelfMethod) {
5381 Diag(PDecl->getLocation(), diag::note_property_declare);
5382 }
5383 }
5384}
5385
5389
5392 return T;
5393
5395
5396
5397
5398
5400 if (.isConstQualified()) {
5404 NameLoc, diag::err_arc_array_param_no_ownership, T, false));
5405 else
5406 Diag(NameLoc, diag::err_arc_array_param_no_ownership)
5408 }
5410 } else {
5412 }
5414
5415 return T;
5416}
5417
5420 bool DoTypoCorrection) {
5421
5422
5425
5426 if (!IDecl && DoTypoCorrection) {
5427
5428
5436 }
5437 }
5438 ObjCInterfaceDecl *Def = dyn_cast_or_null(IDecl);
5439
5442 return Def;
5443}
5444
5450
5451 unsigned kind = -1U;
5452 if (VarDecl *var = dyn_cast(decl)) {
5453 if (var->hasAttr())
5454 kind = 0;
5455 else if (!var->hasLocalStorage())
5456 kind = 1;
5457 } else if (isa(decl)) {
5458 kind = 3;
5459 } else if (isa(decl)) {
5460 kind = 2;
5461 }
5462
5463 if (kind != -1U) {
5464 Diag(decl->getLocation(), diag::err_arc_autoreleasing_var) << kind;
5465 }
5467
5468 if (->isObjCLifetimeType())
5469 return false;
5470
5471 lifetime = type->getObjCARCImplicitLifetime();
5474 }
5475
5476 if (VarDecl *var = dyn_cast(decl)) {
5477
5479 var->getTLSKind()) {
5480 Diag(var->getLocation(), diag::err_arc_thread_ownership)
5481 << var->getType();
5482 return true;
5483 }
5484 }
5485
5486 return false;
5487}
5488
5490 return (dyn_cast_or_null(SemaRef.CurContext));
5491}
5492
5495 return;
5500 if (ivars.empty())
5501 return;
5503 for (unsigned i = 0; i < ivars.size(); i++) {
5505 if (Field->isInvalidDecl())
5506 continue;
5507
5512
5515 InitSeq.Perform(SemaRef, InitEntity, InitKind, {});
5517
5518
5519 if (!MemberInit.get() || MemberInit.isInvalid())
5520 continue;
5521
5522 Member = new (Context)
5525 AllToInit.push_back(Member);
5526
5527
5530 ->getAs()) {
5531 CXXRecordDecl *RD = cast(RecordTy->getDecl());
5536 PDiag(diag::err_access_dtor_ivar)
5538 }
5539 }
5540 }
5542 AllToInit.size());
5543 }
5544}
5545
5546
5547
5550 switch (ivarVisibility) {
5551 default:
5552 llvm_unreachable("Unknown visitibility kind");
5553 case tok::objc_private:
5555 case tok::objc_public:
5557 case tok::objc_protected:
5559 case tok::objc_package:
5561 }
5562}
5563
5564
5565
5568
5571 if (II)
5572 Loc = D.getIdentifierLoc();
5573
5574
5575
5576
5579
5580 if (BitWidth) {
5581
5582 BitWidth =
5585 if (!BitWidth)
5586 D.setInvalidType();
5587 } else {
5588
5589
5590
5591 }
5593 Diag(Loc, diag::err_ivar_reference_type);
5594 D.setInvalidType();
5595 }
5596
5597
5600 TInfo, T, Loc, diag::err_typecheck_ivar_variable_size))
5601 D.setInvalidType();
5602 }
5603
5604
5608
5611 if (!EnclosingDecl || EnclosingDecl->isInvalidDecl())
5612 return nullptr;
5615 dyn_cast(EnclosingDecl)) {
5617
5618
5619 EnclosingContext = IMPDecl->getClassInterface();
5620 assert(EnclosingContext && "Implementation has no class interface!");
5621 } else
5622 EnclosingContext = EnclosingDecl;
5623 } else {
5624 if (ObjCCategoryDecl *CDecl = dyn_cast(EnclosingDecl)) {
5626 Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension();
5627 return nullptr;
5628 }
5629 }
5630 EnclosingContext = EnclosingDecl;
5631 }
5632
5633
5636 II, T, TInfo, ac, BitWidth);
5637
5640
5641 if (II) {
5644 RedeclarationKind::ForVisibleRedeclaration);
5646 !isa(PrevDecl)) {
5647 Diag(Loc, diag::err_duplicate_member) << II;
5648 Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
5650 }
5651 }
5652
5653
5655
5656 if (D.isInvalidType())
5658
5659
5662
5663 if (D.getDeclSpec().isModulePrivateSpecified())
5665
5666 if (II) {
5667
5668
5669 S->AddDecl(NewID);
5671 }
5672
5674 isa(EnclosingDecl))
5675 Diag(Loc, diag::warn_ivars_in_interface);
5676
5677 return NewID;
5678}
Defines the clang::ASTContext interface.
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY)
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
llvm::MachO::Record Record
static bool IsVariableSizedType(QualType T)
static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD)
static bool HasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param)
HasExplicitOwnershipAttr - returns true when pointer to ObjC pointer has explicit ownership attribute...
static void checkObjCDirectMethodClashes(Sema &S, ObjCInterfaceDecl *IDecl, ObjCMethodDecl *Method, ObjCImplDecl *ImpDecl=nullptr)
static bool CheckMethodOverrideParam(Sema &S, ObjCMethodDecl *MethodImpl, ObjCMethodDecl *MethodDecl, ParmVarDecl *ImplVar, ParmVarDecl *IfaceVar, bool IsProtocolMethodDecl, bool IsOverridingMode, bool Warn)
static SourceRange getTypeRange(TypeSourceInfo *TSI)
std::unique_ptr< ProtocolNameSet > LazyProtocolNameSet
static bool CheckMethodOverrideReturn(Sema &S, ObjCMethodDecl *MethodImpl, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl, bool IsOverridingMode, bool Warn)
static void DiagnoseCategoryDirectMembersProtocolConformance(Sema &S, ObjCProtocolDecl *PDecl, ObjCCategoryDecl *CDecl)
static bool checkTypeParamListConsistency(Sema &S, ObjCTypeParamList *prevTypeParams, ObjCTypeParamList *newTypeParams, TypeParamListContext newContext)
Check consistency between two Objective-C type parameter lists, e.g., between a category/extension an...
static void HelperSelectorsForTypoCorrection(SmallVectorImpl< const ObjCMethodDecl * > &BestMethod, StringRef Typo, const ObjCMethodDecl *Method)
static bool objcModifiersConflict(Decl::ObjCDeclQualifier x, Decl::ObjCDeclQualifier y)
Determine whether two set of Objective-C declaration qualifiers conflict.
static bool shouldWarnUndefinedMethod(const ObjCMethodDecl *M)
static bool FilterMethodsByTypeBound(ObjCMethodDecl *Method, const ObjCObjectType *TypeBound)
Return true if the given method is wthin the type bound.
static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, SourceLocation ImplLoc)
static void findProtocolsWithExplicitImpls(const ObjCProtocolDecl *PDecl, ProtocolNameSet &PNS)
static bool matchTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strategy, QualType leftQT, QualType rightQT)
static void DiagnoseRetainableFlexibleArrayMember(Sema &S, ObjCInterfaceDecl *ID)
Diagnose attempts to use flexible array member with retainable object type.
static void mergeInterfaceMethodToImpl(Sema &S, ObjCMethodDecl *method, ObjCMethodDecl *prevMethod)
Merge information from the declaration of a method in the @interface (or a category/extension) into t...
static bool HelperIsMethodInObjCType(Sema &S, Selector Sel, QualType ObjectType)
static SemaObjC::ResultTypeCompatibilityKind CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method, ObjCInterfaceDecl *CurrentClass)
Check whether the declared result type of the given Objective-C method declaration is compatible with...
static ObjCIvarDecl::AccessControl TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility)
TranslateIvarVisibility - Translate visibility from a token ID to an AST enum value.
static void CheckProtocolMethodDefs(Sema &S, ObjCImplDecl *Impl, ObjCProtocolDecl *PDecl, bool &IncompleteImpl, const SemaObjC::SelectorSet &InsMap, const SemaObjC::SelectorSet &ClsMap, ObjCContainerDecl *CDecl, LazyProtocolNameSet &ProtocolsExplictImpl)
CheckProtocolMethodDefs - This routine checks unimplemented methods Declared in protocol,...
static void WarnUndefinedMethod(Sema &S, ObjCImplDecl *Impl, ObjCMethodDecl *method, bool &IncompleteImpl, unsigned DiagID, NamedDecl *NeededFor=nullptr)
static bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl, ObjCProtocolDecl *&UndefinedProtocol)
static bool isObjCTypeSubstitutable(ASTContext &Context, const ObjCObjectPointerType *A, const ObjCObjectPointerType *B, bool rejectId)
Determines if type B can be substituted for type A.
llvm::DenseSet< IdentifierInfo * > ProtocolNameSet
FIXME: Type hierarchies in Objective-C can be deep.
static QualType mergeTypeNullabilityForRedecl(Sema &S, SourceLocation loc, QualType type, bool usesCSKeyword, SourceLocation prevLoc, QualType prevType, bool prevUsesCSKeyword)
Merge type nullability from for a redeclaration of the same entity, producing the updated type of the...
static bool diagnoseNoescape(const ParmVarDecl *NewD, const ParmVarDecl *OldD, Sema &S)
Issue a warning if the parameter of the overridden method is non-escaping but the parameter of the ov...
static bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen, ObjCMethodDecl *other)
Determines if this is an "acceptable" loose mismatch in the global method pool.
static void mergeObjCDirectMembers(Sema &S, Decl *CD, ObjCMethodDecl *Method)
static void DiagnoseWeakIvars(Sema &S, ObjCImplementationDecl *ID)
Diagnose attempts to define ARC-__weak ivars when __weak is disabled.
static void checkObjCMethodX86VectorTypes(Sema &SemaRef, const ObjCMethodDecl *Method)
Verify that the method parameters/return value have types that are supported by the x86 target.
static bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl, ObjCMethodDecl *decl)
In ARC, check whether the conventional meanings of the two methods match.
static bool isMethodContextSameForKindofLookup(ObjCMethodDecl *Method, ObjCMethodDecl *MethodInList)
static bool tryMatchRecordTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strategy, const Type *left, const Type *right)
static Decl::ObjCDeclQualifier CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal)
CvtQTToAstBitMask - utility routine to produce an AST bitmask for objective-c's type qualifier from t...
static void diagnoseUseOfProtocols(Sema &TheSema, ObjCContainerDecl *CD, ObjCProtocolDecl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs)
This file declares semantic analysis for Objective-C.
Defines the SourceManager interface.
__DEVICE__ long long abs(long long __n)
virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D)
Handle the specified top-level declaration that occurred inside and ObjC container.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
bool AnyObjCImplementation()
Return true if there is at least one @implementation in the TU.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig, ObjCTypeParamDecl *New) const
bool ObjCQualifiedIdTypesAreCompatible(const ObjCObjectPointerType *LHS, const ObjCObjectPointerType *RHS, bool ForCompare)
ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an ObjCQualifiedIDType.
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 canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const LangOptions & getLangOpts() const
SelectorTable & Selectors
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass, SmallVectorImpl< const ObjCIvarDecl * > &Ivars) const
DeepCollectObjCIvars - This routine first collects all declared, but not synthesized,...
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
const clang::PrintingPolicy & getPrintingPolicy() const
QualType getObjCIdType() const
Represents the Objective-CC id type.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getAdjustedParameterType(QualType T) const
Perform adjustment on the parameter type of a function.
const TargetInfo & getTargetInfo() const
QualType getLifetimeQualifiedType(QualType type, Qualifiers::ObjCLifetime lifetime)
Return a type with the given lifetime qualifier.
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
bool hasSameNullabilityTypeQualifier(QualType SubT, QualType SuperT, bool IsParam) const
void CollectInheritedProtocols(const Decl *CDecl, llvm::SmallPtrSet< ObjCProtocolDecl *, 8 > &Protocols)
CollectInheritedProtocols - Collect all protocols in current class and those inherited by it.
The result of parsing/analyzing an expression, statement etc.
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
Type source information for an attributed type.
static std::optional< NullabilityKind > stripOuterNullability(QualType &T)
Strip off the top-level nullability annotation on the given type, if it's there.
Represents a C++ base or member initializer.
Represents a C++ destructor within a class.
Represents a C++ struct/union/class.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
bool isFileContext() const
void makeDeclVisibleInContext(NamedDecl *D)
Makes a declaration visible within this context.
bool isObjCContainer() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
void addDecl(Decl *D)
Add the declaration D into this context.
Decl::Kind getDeclKind() const
Simple template class for restricting typo correction candidates to ones having a single Decl* of the...
Captures information about "declaration specifiers".
static const TST TST_typename
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
void SetRangeEnd(SourceLocation Loc)
void SetRangeStart(SourceLocation Loc)
SCS
storage-class-specifier
bool isInlineSpecified() const
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
SourceLocation getInlineSpecLoc() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
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 isUnconditionallyVisible() const
Determine whether this declaration is definitely visible to name lookup, independent of whether the o...
void setTopLevelDeclInObjCContainer(bool V=true)
bool isReferenced() const
Whether any declaration of this entity was referenced.
ObjCDeclQualifier
ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...
@ OBJC_TQ_CSNullability
The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...
bool isInvalidDecl() const
SourceLocation getLocation() const
bool isDeprecated(std::string *Message=nullptr) const
Determine whether this declaration is marked 'deprecated'.
void setImplicit(bool I=true)
DeclContext * getDeclContext()
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
void setLexicalDeclContext(DeclContext *DC)
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
TypeSourceInfo * getTypeSourceInfo() const
Information about one declarator, including the parsed type information and the identifier.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Recursive AST visitor that supports extension via dynamic dispatch.
This represents one expression.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
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 CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
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.
One of these records is kept for each identifier that is lexed.
void RemoveDecl(NamedDecl *D)
RemoveDecl - Unlink the decl from its shadowed decl chain.
void AddDecl(NamedDecl *D)
AddDecl - Link the decl to its shadowed decl chain.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateDefault(SourceLocation InitLoc)
Create a default initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeMember(FieldDecl *Member, const InitializedEntity *Parent=nullptr, bool Implicit=false)
Create the initialization entity for a member subobject.
clang::ObjCRuntime ObjCRuntime
Represents the results of name lookup.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void setModulePrivate()
Specify that this declaration was marked as being private to the module in which it was defined.
static ObjCAtDefsFieldDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW)
ObjCCategoryDecl - Represents a category declaration.
static ObjCCategoryDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation())
void setProtocolList(ObjCProtocolDecl *const *List, unsigned Num, const SourceLocation *Locs, ASTContext &C)
setProtocolList - Set the list of protocols that this interface implements.
ObjCCategoryImplDecl * getImplementation() const
ObjCInterfaceDecl * getClassInterface()
bool IsClassExtension() const
const ObjCProtocolList & getReferencedProtocols() const
void setImplementation(ObjCCategoryImplDecl *ImplD)
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCategoryDecl * getCategoryDecl() const
static ObjCCategoryImplDecl * Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc)
ObjCCompatibleAliasDecl - Represents alias of a class.
static ObjCCompatibleAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl *aliasedClass)
ObjCContainerDecl - Represents a container for method declarations.
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
method_range methods() const
SourceRange getAtEndRange() const
instmeth_range instance_methods() const
ObjCIvarDecl * getIvarDecl(IdentifierInfo *Id) const
getIvarDecl - This method looks up an ivar in this ContextDecl.
void setAtEndRange(SourceRange atEnd)
ObjCMethodDecl * getClassMethod(Selector Sel, bool AllowHidden=false) const
prop_range properties() const
classmeth_range class_methods() const
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Captures information about "declaration specifiers" specific to Objective-C.
ObjCDeclQualifier
ObjCDeclQualifier - Qualifier used on types in method declarations.
ObjCDeclQualifier getObjCDeclQualifier() const
propimpl_range property_impls() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
static ObjCImplementationDecl * Create(ASTContext &C, DeclContext *DC, ObjCInterfaceDecl *classInterface, ObjCInterfaceDecl *superDecl, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation superLoc=SourceLocation(), SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation())
void setIvarInitializers(ASTContext &C, CXXCtorInitializer **initializers, unsigned numInitializers)
const ObjCInterfaceDecl * getSuperClass() const
Represents an ObjC class declaration.
void mergeClassExtensionProtocolList(ObjCProtocolDecl *const *List, unsigned Num, ASTContext &C)
mergeClassExtensionProtocolList - Merge class extension's protocol list into the protocol list for th...
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameters of this class.
ObjCInterfaceDecl * lookupInheritedClass(const IdentifierInfo *ICName)
lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super class whose name is passe...
ivar_iterator ivar_end() const
llvm::iterator_range< specific_decl_iterator< ObjCIvarDecl > > ivar_range
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
unsigned ivar_size() const
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
void setProtocolList(ObjCProtocolDecl *const *List, unsigned Num, const SourceLocation *Locs, ASTContext &C)
setProtocolList - Set the list of protocols that this interface implements.
bool hasDefinition() const
Determine whether this class has been defined.
all_protocol_range all_referenced_protocols() const
visible_extensions_range visible_extensions() const
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
ObjCCategoryDecl * FindCategoryDeclaration(const IdentifierInfo *CategoryId) const
FindCategoryDeclaration - Finds category declaration in the list of categories for this class and ret...
ivar_iterator ivar_begin() const
void setImplementation(ObjCImplementationDecl *ImplD)
known_categories_range known_categories() const
void setSuperClass(TypeSourceInfo *superClass)
const ObjCProtocolList & getReferencedProtocols() const
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,...
ObjCImplementationDecl * getImplementation() const
void setEndOfDefinitionLoc(SourceLocation LE)
void startDefinition()
Starts the definition of this Objective-C class, taking it from a forward declaration (@class) to a d...
visible_categories_range visible_categories() const
ObjCInterfaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C class.
ObjCInterfaceDecl * getSuperClass() const
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
void startDuplicateDefinitionForComparison()
Starts the definition without sharing it with other redeclarations.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Interfaces are the core concept in Objective-C for object oriented design.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCIvarDecl * getNextIvar()
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)
ObjCIvarRefExpr - A reference to an ObjC instance variable.
ObjCList - This is a simple template class used to hold various lists of decls etc,...
void set(T *const *InList, unsigned Elts, ASTContext &Ctx)
An expression that sends a message to the given Objective-C object or class.
@ Instance
The receiver is an object instance.
ObjCMethodDecl - Represents an instance or class method declaration.
bool isDesignatedInitializerForTheInterface(const ObjCMethodDecl **InitMethod=nullptr) const
Returns true if the method selector resolves to a designated initializer in the class's interface.
ImplicitParamDecl * getSelfDecl() const
void setObjCDeclQualifier(ObjCDeclQualifier QV)
void setDefined(bool isDefined)
ObjCDeclQualifier getObjCDeclQualifier() const
ArrayRef< ParmVarDecl * > parameters() const
unsigned param_size() const
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)
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
param_const_iterator param_end() const
param_const_iterator param_begin() const
ObjCMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod)
void setRelatedResultType(bool RRT=true)
Note whether this method has a related result type.
bool isSynthesizedAccessorStub() const
SourceLocation getSelectorLoc(unsigned Index) const
SourceRange getReturnTypeSourceRange() const
void setOverriding(bool IsOver)
const ParmVarDecl *const * param_const_iterator
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver's type.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
bool isInstanceMethod() const
void setReturnType(QualType T)
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
ObjCImplementationControl getImplementationControl() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Wraps an ObjCPointerType with source location information.
void setStarLoc(SourceLocation Loc)
Represents a pointer to an Objective C object.
bool isObjCQualifiedIdType() const
True if this is equivalent to 'id.
bool isObjCIdType() const
True if this is equivalent to the 'id' type, i.e.
const ObjCInterfaceType * getInterfaceType() const
If this pointer points to an Objective C @interface type, gets the type for that interface.
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
ObjCIvarDecl * getPropertyIvarDecl() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Represents an Objective-C protocol declaration.
void startDuplicateDefinitionForComparison()
Starts the definition without sharing it with other redeclarations.
bool hasDefinition() const
Determine whether this protocol has a definition.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
static ObjCProtocolDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl)
const ObjCProtocolList & getReferencedProtocols() const
void setProtocolList(ObjCProtocolDecl *const *List, unsigned Num, const SourceLocation *Locs, ASTContext &C)
setProtocolList - Set the list of protocols that this interface implements.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
void startDefinition()
Starts the definition of this Objective-C protocol.
protocol_range protocols() const
A list of Objective-C protocols, along with the source locations at which they were referenced.
The basic abstraction for the target Objective-C runtime.
bool isNeXTFamily() const
Is this runtime basically of the NeXT family of runtimes?
bool isNonFragile() const
Does this runtime follow the set of implied behaviors for a "non-fragile" ABI?
bool isFragile() const
The inverse of isNonFragile(): does this runtime follow the set of implied behaviors for a "fragile" ...
Represents the declaration of an Objective-C type parameter.
static ObjCTypeParamDecl * Create(ASTContext &ctx, DeclContext *dc, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, SourceLocation nameLoc, IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo)
bool hasExplicitBound() const
Whether this type parameter has an explicitly-written type bound, e.g., "T : NSView".
ObjCTypeParamVariance getVariance() const
Determine the variance of this type parameter.
void setVariance(ObjCTypeParamVariance variance)
Set the variance of this type parameter.
SourceLocation getVarianceLoc() const
Retrieve the location of the variance keyword.
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
SourceRange getSourceRange() const
unsigned size() const
Determine the number of type parameters in this list.
ObjCTypeParamDecl * back() const
static ObjCTypeParamList * create(ASTContext &ctx, SourceLocation lAngleLoc, ArrayRef< ObjCTypeParamDecl * > typeParams, SourceLocation rAngleLoc)
Create a new Objective-C type parameter list.
SourceLocation getLAngleLoc() const
Represents a parameter to a function.
void setObjCDeclQualifier(ObjCDeclQualifier QTVal)
ObjCDeclQualifier getObjCDeclQualifier() const
void setObjCMethodScopeInfo(unsigned parameterIndex)
static const ParsedAttributesView & none()
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool hasQualifiers() const
Determine whether this type has any qualifiers.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
The collection of all-type qualifiers we support.
void removeCVRQualifiers(unsigned mask)
@ 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.
std::string getAsString() const
Represents a struct/union/class.
field_iterator field_end() const
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
std::string getAsString() const
Derive the full selector name (e.g.
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool isUnarySelector() const
unsigned getNumArgs() const
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
Decl * ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D, Expr *BitWidth, tok::ObjCKeywordKind visibility)
ActOnIvar - Each ivar field of an objective-c class is passed into this in order to create an IvarDec...
void ActOnStartOfObjCMethodDef(Scope *S, Decl *D)
ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible and user declared,...
void ActOnSuperClassOfClassInterface(Scope *S, SourceLocation AtInterfaceLoc, ObjCInterfaceDecl *IDecl, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, ArrayRef< ParsedType > SuperTypeArgs, SourceRange SuperTypeArgsRange)
VarDecl * BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, bool Invalid=false)
Build a type-check a new Objective-C exception variable declaration.
void DiagnoseUnusedBackingIvarInAccessor(Scope *S, const ObjCImplementationDecl *ImplD)
DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which backs the property is n...
void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation)
SetIvarInitializers - This routine builds initialization ASTs for the Objective-C implementation whos...
void WarnExactTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl)
WarnExactTypedMethods - This routine issues a warning if method implementation declaration matches ex...
const ObjCMethodDecl * SelectorsForTypoCorrection(Selector Sel, QualType ObjectType=QualType())
void ProcessPropertyDecl(ObjCPropertyDecl *property)
Process the specified property declaration and create decls for the setters and getters as needed.
TypeResult actOnObjCTypeArgsAndProtocolQualifiers(Scope *S, SourceLocation Loc, ParsedType BaseType, SourceLocation TypeArgsLAngleLoc, ArrayRef< ParsedType > TypeArgs, SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, ArrayRef< Decl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc)
Build a specialized and/or protocol-qualified Objective-C type.
void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method)
Add the given method to the list of globally-known methods.
ObjCInterfaceDecl * ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, IdentifierInfo *SuperName, SourceLocation SuperLoc, ArrayRef< ParsedType > SuperTypeArgs, SourceRange SuperTypeArgsRange, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody)
void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)
Diagnose any null-resettable synthesized setters.
void updateOutOfDateSelector(Selector Sel)
void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList)
ObjCImplementationDecl * ActOnStartClassImplementation(SourceLocation AtClassImplLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, const IdentifierInfo *SuperClassname, SourceLocation SuperClassLoc, const ParsedAttributesView &AttrList)
bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl< ObjCMethodDecl * > &Methods)
Decl * ActOnObjCExceptionDecl(Scope *S, Declarator &D)
bool CheckObjCDeclScope(Decl *D)
Checks that the Objective-C declaration is declared in the global scope.
DeclResult actOnObjCTypeParam(Scope *S, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, IdentifierInfo *paramName, SourceLocation paramLoc, SourceLocation colonLoc, ParsedType typeBound)
ObjCIvarDecl * GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, const ObjCPropertyDecl *&PDecl) const
GetIvarBackingPropertyAccessor - If method is a property setter/getter and it property has a backing ...
bool CheckARCMethodDecl(ObjCMethodDecl *method)
Check a method declaration for compatibility with the Objective-C ARC conventions.
ObjCContainerKind getObjCContainerKind() const
ObjCInterfaceDecl * getObjCInterfaceDecl(const IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection=false)
Look for an Objective-C class in the translation unit.
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
ParmVarDecl * ActOnMethodParmDeclaration(Scope *S, ObjCArgInfo &ArgInfo, int ParamIndex, bool MethodDefinition)
DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef< Decl * > Decls)
ObjCContainerDecl * getObjCDeclContext() const
void WarnConflictingTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl)
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod, MethodMatchStrategy strategy=MMS_strict)
MatchTwoMethodDeclarations - Checks if two methods' type match and returns true, or false,...
void MatchAllMethodDeclarations(const SelectorSet &InsMap, const SelectorSet &ClsMap, SelectorSet &InsMapSeen, SelectorSet &ClsMapSeen, ObjCImplDecl *IMPDecl, ObjCContainerDecl *IDecl, bool &IncompleteImpl, bool ImmediateClass, bool WarnCategoryMethodImpl=false)
MatchAllMethodDeclarations - Check methods declaraed in interface or or protocol against those declar...
llvm::MapVector< Selector, SourceLocation > ReferencedSelectors
Method selectors used in a @selector expression.
void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D)
void ActOnObjCContainerFinishDefinition()
Decl * ActOnCompatibilityAlias(SourceLocation AtCompatibilityAliasLoc, IdentifierInfo *AliasName, SourceLocation AliasLocation, IdentifierInfo *ClassName, SourceLocation ClassLocation)
ActOnCompatibilityAlias - this action is called after complete parsing of a @compatibility_alias decl...
void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID)
DiagnoseDuplicateIvars - Check for duplicate ivars in the entire class at the start of @implementatio...
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall)
Check whether the given method, which must be in the 'init' family, is a valid member of that family.
void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, ObjCMethodDecl *Overridden, bool IsProtocolMethodDecl)
ObjCTypeParamList * actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, ArrayRef< Decl * > typeParams, SourceLocation rAngleLoc)
ObjCCategoryDecl * ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, ObjCTypeParamList *typeParamList, const IdentifierInfo *CategoryName, SourceLocation CategoryLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList)
void actOnObjCTypeArgsOrProtocolQualifiers(Scope *S, ParsedType baseType, SourceLocation lAngleLoc, ArrayRef< IdentifierInfo * > identifiers, ArrayRef< SourceLocation > identifierLocs, SourceLocation rAngleLoc, SourceLocation &typeArgsLAngleLoc, SmallVectorImpl< ParsedType > &typeArgs, SourceLocation &typeArgsRAngleLoc, SourceLocation &protocolLAngleLoc, SmallVectorImpl< Decl * > &protocols, SourceLocation &protocolRAngleLoc, bool warnOnIncompleteProtocols)
Given a list of identifiers (and their locations), resolve the names to either Objective-C protocol q...
bool CheckForwardProtocolDeclarationForCircularDependency(IdentifierInfo *PName, SourceLocation &PLoc, SourceLocation PrevLoc, const ObjCList< ObjCProtocolDecl > &PList)
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...
void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, ObjCInterfaceDecl *ID)
DiagnoseClassExtensionDupMethods - Check for duplicate declaration of a class method in its extension...
ObjCCategoryImplDecl * ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, const IdentifierInfo *CatName, SourceLocation CatLoc, const ParsedAttributesView &AttrList)
ActOnStartCategoryImplementation - Perform semantic checks on the category implementation declaration...
bool inferObjCARCLifetime(ValueDecl *decl)
void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, const ObjCMethodDecl *Overridden)
Check whether the given new method is a valid override of the given overridden method,...
Decl * ActOnMethodDeclaration(Scope *S, SourceLocation BeginLoc, SourceLocation EndLoc, tok::TokenKind MethodType, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, ArrayRef< SourceLocation > SelectorLocs, Selector Sel, ParmVarDecl **ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, const ParsedAttributesView &AttrList, tok::ObjCKeywordKind MethodImplKind, bool isVariadic, bool MethodDefinition)
void ActOnTypedefedProtocols(SmallVectorImpl< Decl * > &ProtocolRefs, SmallVectorImpl< SourceLocation > &ProtocolLocs, IdentifierInfo *SuperName, SourceLocation SuperLoc)
ActOnTypedefedProtocols - this action finds protocol list as part of the typedef'ed use for a qualifi...
void DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD)
void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, SmallVectorImpl< ObjCIvarDecl * > &Ivars)
CollectIvarsToConstructOrDestruct - Collect those ivars which require initialization.
DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, ArrayRef< IdentifierLocPair > IdentList, const ParsedAttributesView &attrList)
ActOnForwardProtocolDeclaration - Handle @protocol foo;.
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
QualType AdjustParameterTypeForObjCAutoRefCount(QualType T, SourceLocation NameLoc, TypeSourceInfo *TSInfo)
GlobalMethodPool MethodPool
Method Pool - allows efficient lookup when typechecking messages to "id".
ObjCProtocolDecl * ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, Decl *const *ProtoRefNames, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody)
ResultTypeCompatibilityKind
Describes the compatibility of a result type with its method.
void DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl< ObjCMethodDecl * > &Methods, Selector Sel, SourceRange R, bool receiverIdOrClass)
DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, ArrayRef< ObjCTypeParamList * > TypeParamLists, unsigned NumElts)
void ReadMethodPool(Selector Sel)
Read the contents of the method pool for a given selector from external storage.
void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, const IdentifierInfo *ClassName, SmallVectorImpl< Decl * > &Decls)
Called whenever @defs(ClassName) is encountered in the source.
void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, SourceLocation ProtocolLoc, IdentifierInfo *TypeArgId, SourceLocation TypeArgLoc, bool SelectProtocolFirst=false)
bool CollectMultipleMethodsInGlobalPool(Selector Sel, SmallVectorImpl< ObjCMethodDecl * > &Methods, bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound=nullptr)
We first select the type of the method: Instance or Factory, then collect all methods with that type.
void CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, ObjCMethodDecl *overridden)
void DiagnoseUseOfUnimplementedSelectors()
Decl * ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef< Decl * > allMethods={}, ArrayRef< DeclGroupPtrTy > allTUVars={})
void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP)
CheckCategoryVsClassMethodMatches - Checks that methods implemented in category matches with those im...
void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl *IMPDecl, ObjCContainerDecl *IDecl, bool IncompleteImpl=false)
ImplMethodsVsClassMethods - This is main routine to warn if any method remains unimplemented in the c...
void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ObjCInterfaceDecl *CurrentClass, ResultTypeCompatibilityKind RTC)
void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, ObjCIvarDecl **Fields, unsigned nIvars, SourceLocation Loc)
CheckImplementationIvars - This routine checks if the instance variables listed in the implelementati...
ObjCMethodDecl * LookupImplementedMethodInGlobalPool(Selector Sel)
LookupImplementedMethodInGlobalPool - Returns the method which has an implementation.
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false)
AddInstanceMethodToGlobalPool - All instance methods in a translation unit are added to a global pool...
void AddAnyMethodToGlobalPool(Decl *D)
AddAnyMethodToGlobalPool - Add any method, instance or factory to global pool.
@ OCK_CategoryImplementation
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
void ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl)
void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, ArrayRef< IdentifierLocPair > ProtocolId, SmallVectorImpl< Decl * > &Protocols)
FindProtocolDeclaration - This routine looks up protocols and issues an error if they are not declare...
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
Sema - This implements semantic analysis and AST building for C.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false) const
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S',...
LookupNameKind
Describes the kind of name lookup to perform.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupObjCProtocolName
Look up the name of an Objective-C protocol.
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
void DiagnoseFunctionSpecifiers(const DeclSpec &DS)
Diagnose function specifiers on a declaration of an identifier that does not identify a function.
void AddPragmaAttributes(Scope *S, Decl *D)
Adds the attributes that have been specified using the '#pragma clang attribute push' directives to t...
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
class clang::Sema::DelayedDiagnostics DelayedDiagnostics
ExprResult VerifyBitField(SourceLocation FieldLoc, const IdentifierInfo *FieldName, QualType FieldTy, bool IsMsStruct, Expr *BitWidth)
VerifyBitField - verifies that a bit field expression is an ICE and has the correct width,...
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
void PushFunctionScope()
Enter a new function scope.
bool CheckFunctionReturnType(QualType T, SourceLocation Loc)
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() const
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
bool tryToFixVariablyModifiedVarType(TypeSourceInfo *&TInfo, QualType &T, SourceLocation Loc, unsigned FailedFoldDiagID)
Attempt to fold a variable-sized type to a constant-sized type, returning true if we were successful.
void CheckExtraCXXDefaultArguments(Declarator &D)
CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...
DeclContext * getCurLexicalContext() const
sema::FunctionScopeInfo * getCurFunction() const
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
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.
ParmVarDecl * CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, const IdentifierInfo *Name, QualType T, TypeSourceInfo *TSInfo, StorageClass SC)
void applyFunctionAttributesBeforeParsingBody(Decl *FD)
bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, bool OnlyNeedComplete=false)
Determine if D has a visible definition.
SourceManager & getSourceManager() const
TypeResult ActOnTypeName(Declarator &D)
ExternalSemaSource * getExternalSource() const
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
RedeclarationKind forRedeclarationInCurContext() const
void mergeDeclAttributes(NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK=AMK_Redeclaration)
mergeDeclAttributes - Copy attributes from the Old decl to the New one.
IntrusiveRefCntPtr< ExternalSemaSource > ExternalSource
Source of additional semantic information.
TypeSourceInfo * GetTypeForDeclarator(Declarator &D)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
DiagnosticsEngine & Diags
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD)
ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in it, apply them to D.
llvm::BumpPtrAllocator BumpAlloc
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old)
void ProcessAPINotes(Decl *D)
Map any API notes provided for this declaration to attributes on the declaration.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
IdentifierResolver IdResolver
llvm::SmallVector< std::pair< SourceLocation, const BlockDecl * >, 1 > ImplicitlyRetainedSelfLocs
List of SourceLocations where 'self' is implicitly retained inside a block.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
SourceLocation getBeginLoc() const LLVM_READONLY
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
Represents a declaration of a type.
SourceLocation getBeginLoc() const LLVM_READONLY
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
void pushFullCopy(TypeLoc L)
Pushes a copy of the given TypeLoc onto this builder.
TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)
Creates a TypeSourceInfo for the given type.
Base wrapper for a particular "section" of type source info.
TypeLoc findExplicitQualifierLoc() const
Find a type with the location of an explicit type qualifier.
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
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.
The base class of the type hierarchy.
bool isIncompleteArrayType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs.
bool isReferenceType() const
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isScalarType() const
bool isObjCQualifiedIdType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
ScalarTypeKind getScalarTypeKind() const
Given that this is a scalar type, classify it.
bool containsErrors() const
Whether this type is an error type.
bool isObjCIdType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjCObjectType() const
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const
Return the implicit lifetime for this type, which must not be dependent.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
bool isVectorType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
const T * getAs() const
Member-template getAs'.
bool isRecordType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isObjCIndependentClassType() const
Base class for declarations which introduce a typedef-name.
TypeSourceInfo * getTypeSourceInfo() const
QualType getUnderlyingType() const
Simple class containing the result of Sema::CorrectTypo.
DeclClass * getCorrectionDeclAs() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
void setType(QualType newType)
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
void setExceptionVariable(bool EV)
static DelayedDiagnostic makeForbiddenType(SourceLocation loc, unsigned diagnostic, QualType type, unsigned argument)
bool ObjCIsDesignatedInit
True when this is a method marked as a designated initializer.
bool ObjCShouldCallSuper
A flag that is set when parsing a method that must call super's implementation, such as -dealloc,...
bool ObjCWarnForNoInitDelegation
This starts true for a secondary initializer method and will be set to false if there is an invocatio...
bool ObjCIsSecondaryInit
True when this is an initializer method not marked as a designated initializer within a class that ha...
bool ObjCWarnForNoDesignatedInitChain
This starts true for a method marked as designated initializer and will be set to false if there is a...
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
ThreadStorageClassSpecifier
Thread storage-class-specifier.
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_None
No particular method family.
@ Property
The type of a property.
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
@ Class
The "class" keyword.
AvailabilityResult
Captures the result of checking the availability of a declaration.
std::pair< NullabilityKind, bool > DiagNullabilityKind
A nullability kind paired with a bit indicating whether it used a context-sensitive keyword.
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
ObjCTypeParamVariance
Describes the variance of a given generic parameter.
@ Invariant
The parameter is invariant: must match exactly.
@ Contravariant
The parameter is contravariant, e.g., X is a subtype of X when the type parameter is covariant and...
@ Covariant
The parameter is covariant, e.g., X is a subtype of X when the type parameter is covariant and T i...
std::pair< IdentifierInfo *, SourceLocation > IdentifierLocPair
A simple pair of identifier info and location.
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Visibility
Describes the different kinds of visibility that a declaration may have.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc)
Return a DeclaratorChunk for a pointer.
a linked list of methods with the same selector name but different signatures.
ObjCMethodDecl * getMethod() const
void setMethod(ObjCMethodDecl *M)
void setNext(ObjCMethodList *L)
bool hasMoreThanOneDecl() const
ObjCMethodList * getNext() const
ParsedAttributesView ArgAttrs
ArgAttrs - Attribute list for this argument.