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
58 if (result->isObjCId()) {
59 return false;
60 } else if (result->isObjCClass()) {
61
62 } else {
64 assert(resultClass && "unexpected object type!");
65
66
67
69 if (receiverTypeIfCall.isNull() &&
71 return false;
72
73
74 } else {
75
76
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() &&
104 SemaRef.getSourceManager().isInSystemHeader(loc)) {
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)
169 << Context.getObjCInterfaceType(CurrentClass)
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
246 if (!Context.hasSameType(method->getReturnType(), Context.VoidTy)) {
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);
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)
322 ? 0
324 : 1);
328 else
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
354 T = PT->getPointeeType();
356 T = RT->getPointeeType();
357 } else {
358 return true;
359 }
360
361
362
363 return .getLocalQualifiers().hasObjCLifetime();
364}
365
366
367
370 SemaRef.ImplicitlyRetainedSelfLocs.clear();
371 assert((SemaRef.getCurMethodDecl() == nullptr) && "Methodparsing confused");
372 ObjCMethodDecl *MDecl = dyn_cast_or_null(D);
373
374 SemaRef.PushExpressionEvaluationContext(
375 SemaRef.ExprEvalContexts.back().Context);
376
377
378 if (!MDecl)
379 return;
380
385 diag::err_func_def_incomplete_result))
387
388
389 SemaRef.PushDeclContext(FnBodyScope, MDecl);
390 SemaRef.PushFunctionScope();
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())
413 SemaRef.PushOnScopeChains(Param, FnBodyScope);
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
471 SemaRef.getCurFunction()->ObjCIsDesignatedInit = true;
472 SemaRef.getCurFunction()->ObjCWarnForNoDesignatedInitChain =
473 IC->getSuperClass() != nullptr;
474 } else if (IC->hasDesignatedInitializers()) {
475 SemaRef.getCurFunction()->ObjCIsSecondaryInit = true;
476 SemaRef.getCurFunction()->ObjCWarnForNoInitDelegation = true;
477 }
478 }
479
480
481
482
483
489 SemaRef.getCurFunction()->ObjCShouldCallSuper = true;
490
493 SemaRef.getCurFunction()->ObjCShouldCallSuper = true;
494
495 } else {
497 SuperClass->lookupMethod(MDecl->getSelector(),
499 SemaRef.getCurFunction()->ObjCShouldCallSuper =
500 (SuperMethod && SuperMethod->hasAttr());
501 }
502 }
503 }
504
505
506
507 SemaRef.applyFunctionAttributesBeforeParsingBody(D);
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:
531 ObjCInterfaceDecl *CurrentIDecl;
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);
569 SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)
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) {
586 (void)SemaRef.DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
587 SuperClassType = Context.getObjCInterfaceType(SuperClassDecl);
588 }
589
590 if (PrevDecl && !SuperClassDecl) {
591
592
594 dyn_cast_or_null(PrevDecl)) {
595 QualType T = TDecl->getUnderlyingType();
596 if (T->isObjCObjectType()) {
598 SuperClassDecl = dyn_cast(IDecl);
599 SuperClassType = Context.getTypeDeclType(
601
602
603
604
605
606 (void)SemaRef.DiagnoseUseOfDecl(
608 }
609 }
610 }
611
612
613
614
615
616
617 if (!SuperClassDecl) {
618 Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
619 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
620 }
621 }
622
623 if (!isa_and_nonnull(PrevDecl)) {
624 if (!SuperClassDecl)
625 Diag(SuperLoc, diag::err_undef_superclass)
626 << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
627 else if (SemaRef.RequireCompleteType(
628 SuperLoc, SuperClassType, diag::err_forward_superclass,
629 SuperClassDecl->getDeclName(), ClassName,
630 SourceRange(AtInterfaceLoc, ClassLoc))) {
631 SuperClassDecl = nullptr;
633 }
634 }
635
636 if (SuperClassType.isNull()) {
637 assert(!SuperClassDecl && "Failed to set SuperClassType?");
638 return;
639 }
640
641
643 if (!SuperTypeArgs.empty()) {
645 S, SuperLoc, SemaRef.CreateParsedType(SuperClassType, nullptr),
646 SuperTypeArgsRange.getBegin(), SuperTypeArgs,
649 if (!fullSuperClassType.isUsable())
650 return;
651
652 SuperClassType =
653 SemaRef.GetTypeFromParser(fullSuperClassType.get(), &SuperClassTInfo);
654 }
655
656 if (!SuperClassTInfo) {
657 SuperClassTInfo = Context.getTrivialTypeSourceInfo(SuperClassType,
658 SuperLoc);
659 }
660
664 }
665}
666
672
674 if (parsedTypeBound) {
675
677 SemaRef.GetTypeFromParser(parsedTypeBound, &typeBoundInfo);
679
681
682
686 diag::err_objc_type_param_bound_missing_pointer)
687 << typeBound << paramName
689
690
691
694
695
696 typeBound = Context.getObjCObjectPointerType(typeBound);
700
701
703 } else {
704
706 diag::err_objc_type_param_bound_nonobject)
707 << typeBound << paramName;
708
709
710 typeBoundInfo = nullptr;
711 }
712
713
714
715 if (typeBoundInfo) {
719 bool diagnosed = false;
721 if (qual) {
723 rangeToRemove = attr.getLocalSourceRange();
724 if (attr.getTypePtr()->getImmediateNullability()) {
726 diag::err_objc_type_param_bound_explicit_nullability)
727 << paramName << typeBound
729 diagnosed = true;
730 }
731 }
732 }
733
734 if (!diagnosed) {
737 diag::err_objc_type_param_bound_qualified)
738 << paramName << typeBound
741 }
742
743
744
745
748 if (!quals.empty()) {
749 typeBoundInfo =
751 }
752 }
753 }
754 }
755
756
757
758 if (!typeBoundInfo) {
760 typeBoundInfo = Context.getTrivialTypeSourceInfo(Context.getObjCIdType());
761 }
762
763
765 varianceLoc, index, paramLoc, paramName,
766 colonLoc, typeBoundInfo);
767}
768
774
776 typeParams(
777 reinterpret_cast<ObjCTypeParamDecl * const *>(typeParamsIn.data()),
778 typeParamsIn.size());
779
780
781
782
783
784 llvm::SmallDenseMap<IdentifierInfo *, ObjCTypeParamDecl *> knownParams;
785 for (auto *typeParam : typeParams) {
786 auto known = knownParams.find(typeParam->getIdentifier());
787 if (known != knownParams.end()) {
788 Diag(typeParam->getLocation(), diag::err_objc_type_param_redecl)
789 << typeParam->getIdentifier()
790 << SourceRange(known->second->getLocation());
791
792 typeParam->setInvalidDecl();
793 } else {
794 knownParams.insert(std::make_pair(typeParam->getIdentifier(), typeParam));
795
796
797 SemaRef.PushOnScopeChains(typeParam, S, false);
798 }
799 }
800
801
803}
804
807 for (auto *typeParam : *typeParamList) {
808 if (!typeParam->isInvalidDecl()) {
810 SemaRef.IdResolver.RemoveDecl(typeParam);
811 }
812 }
813}
814
815namespace {
816
817
818 enum class TypeParamListContext {
819 ForwardDeclaration,
821 Category,
822 Extension
823 };
824}
825
826
827
828
832 TypeParamListContext newContext) {
833
834 if (prevTypeParams->size() != newTypeParams->size()) {
836 if (newTypeParams->size() > prevTypeParams->size()) {
837 diagLoc = newTypeParams->begin()[prevTypeParams->size()]->getLocation();
838 } else {
840 }
841
842 S.Diag(diagLoc, diag::err_objc_type_param_arity_mismatch)
843 << static_cast<unsigned>(newContext)
844 << (newTypeParams->size() > prevTypeParams->size())
845 << prevTypeParams->size()
846 << newTypeParams->size();
847
848 return true;
849 }
850
851
852 for (unsigned i = 0, n = prevTypeParams->size(); i != n; ++i) {
855
856
859 newContext != TypeParamListContext::Definition) {
860
861
867 ->getDefinition() == prevTypeParam->getDeclContext())) {
868
869
870
871 } else {
872 {
873
877
879 diag::err_objc_type_param_variance_conflict)
880 << static_cast<unsigned>(newTypeParam->getVariance())
882 << static_cast<unsigned>(prevTypeParam->getVariance())
887 break;
888
891 StringRef newVarianceStr
893 ? "__covariant"
894 : "__contravariant";
898 (newVarianceStr + " ").str());
899 } else {
901 newVarianceStr);
902 }
903 }
904 }
905 }
906
907 S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)
909
910
912 }
913 }
914
915
918 continue;
919
920
921
925 S.Diag(newBoundRange.getBegin(), diag::err_objc_type_param_bound_conflict)
933 newBoundRange,
936
937 S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)
939
940
941
943 continue;
944 }
945
946
947
948
949 if (newContext == TypeParamListContext::ForwardDeclaration ||
950 newContext == TypeParamListContext::Definition) {
951
954 std::string newCode
958 diag::err_objc_type_param_bound_missing)
961 << (newContext == TypeParamListContext::ForwardDeclaration)
963
964 S.Diag(prevTypeParam->getLocation(), diag::note_objc_type_param_here)
966 }
967
968
970 }
971
972 return false;
973}
974
980 Decl *const *ProtoRefs, unsigned NumProtoRefs,
983 assert(ClassName && "Missing class identifier");
984
986
989 SemaRef.forRedeclarationInCurContext());
990
992 Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
993 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
994 }
995
996
997 ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null(PrevDecl);
998
999 if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1013 }
1014
1015
1016
1017 if (PrevIDecl) {
1019 if (typeParamList) {
1020
1022 typeParamList,
1023 TypeParamListContext::Definition)) {
1024 typeParamList = nullptr;
1025 }
1026 } else {
1027 Diag(ClassLoc, diag::err_objc_parameterized_forward_class_first)
1028 << ClassName;
1029 Diag(prevTypeParamList->getLAngleLoc(), diag::note_previous_decl)
1030 << ClassName;
1031
1032
1034 for (auto *typeParam : *prevTypeParamList) {
1036 Context, SemaRef.CurContext, typeParam->getVariance(),
1039 Context.getTrivialTypeSourceInfo(
1040 typeParam->getUnderlyingType())));
1041 }
1042
1045 clonedTypeParams,
1047 }
1048 }
1049 }
1050
1053 ClassName, typeParamList, PrevIDecl, ClassLoc);
1054 if (PrevIDecl) {
1055
1057 if (SkipBody && .hasVisibleDefinition(Def)) {
1059 SkipBody->New = IDecl;
1061 } else {
1062 Diag(AtInterfaceLoc, diag::err_duplicate_class_def)
1064 Diag(Def->getLocation(), diag::note_previous_definition);
1066 }
1067 }
1068 }
1069
1070 SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, IDecl, AttrList);
1071 SemaRef.AddPragmaAttributes(SemaRef.TUScope, IDecl);
1072 SemaRef.ProcessAPINotes(IDecl);
1073
1074
1075 if (PrevIDecl)
1076 SemaRef.mergeDeclAttributes(IDecl, PrevIDecl);
1077
1079
1080
1081
1086
1087 if (SuperName) {
1088
1090
1092 ClassName, ClassLoc,
1093 SuperName, SuperLoc, SuperTypeArgs,
1094 SuperTypeArgsRange);
1095 } else {
1097 }
1098
1099
1100 if (NumProtoRefs) {
1102 NumProtoRefs, ProtoLocs);
1104 ProtoLocs, Context);
1106 }
1107
1110 return IDecl;
1111}
1112
1113
1114
1115
1120 if (!SuperName)
1121 return;
1124 if (!IDecl)
1125 return;
1126
1127 if (const TypedefNameDecl *TDecl = dyn_cast_or_null(IDecl)) {
1128 QualType T = TDecl->getUnderlyingType();
1129 if (T->isObjCObjectType())
1131 ProtocolRefs.append(OPT->qual_begin(), OPT->qual_end());
1132
1133
1134
1135
1136 ProtocolLocs.append(OPT->getNumProtocols(), SuperLoc);
1137 }
1138 }
1139}
1140
1141
1142
1149
1152 SemaRef.forRedeclarationInCurContext());
1153 if (ADecl) {
1154 Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
1155 Diag(ADecl->getLocation(), diag::note_previous_declaration);
1156 return nullptr;
1157 }
1158
1161 SemaRef.forRedeclarationInCurContext());
1163 dyn_cast_or_null(CDeclU)) {
1164 QualType T = TDecl->getUnderlyingType();
1165 if (T->isObjCObjectType()) {
1167 ClassName = IDecl->getIdentifier();
1168 CDeclU = SemaRef.LookupSingleName(
1170 SemaRef.forRedeclarationInCurContext());
1171 }
1172 }
1173 }
1174 ObjCInterfaceDecl *CDecl = dyn_cast_or_null(CDeclU);
1175 if (!CDecl) {
1176 Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
1177 if (CDeclU)
1178 Diag(CDeclU->getLocation(), diag::note_previous_declaration);
1179 return nullptr;
1180 }
1181
1182
1184 Context, SemaRef.CurContext, AtLoc, AliasName, CDecl);
1185
1188
1190}
1191
1195
1196 bool res = false;
1198 E = PList.end(); I != E; ++I) {
1200 if (PDecl->getIdentifier() == PName) {
1201 Diag(Ploc, diag::err_protocol_has_circular_dependency);
1202 Diag(PrevLoc, diag::note_previous_definition);
1203 res = true;
1204 }
1205
1206 if (!PDecl->hasDefinition())
1207 continue;
1208
1210 PDecl->getLocation(), PDecl->getReferencedProtocols()))
1211 res = true;
1212 }
1213 }
1214 return res;
1215}
1216
1219 SourceLocation ProtocolLoc, Decl *const *ProtoRefs, unsigned NumProtoRefs,
1223 bool err = false;
1224
1225 assert(ProtocolName && "Missing protocol identifier");
1227 ProtocolName, ProtocolLoc, SemaRef.forRedeclarationInCurContext());
1230
1231
1232
1233
1235 ProtocolLoc, AtProtoInterfaceLoc,
1236 Def);
1237
1238 if (SkipBody && .hasVisibleDefinition(Def)) {
1240 SkipBody->New = PDecl;
1242 } else {
1243
1244 Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
1245 Diag(Def->getLocation(), diag::note_previous_definition);
1246 }
1247
1248
1249
1253 } else {
1254 if (PrevDecl) {
1255
1256
1260 ProtocolName, ProtocolLoc, PrevDecl->getLocation(), PList);
1261 }
1262
1263
1265 ProtocolLoc, AtProtoInterfaceLoc,
1266 PrevDecl);
1267
1270 }
1271
1272 SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, PDecl, AttrList);
1273 SemaRef.AddPragmaAttributes(SemaRef.TUScope, PDecl);
1274 SemaRef.ProcessAPINotes(PDecl);
1275
1276
1277 if (PrevDecl)
1278 SemaRef.mergeDeclAttributes(PDecl, PrevDecl);
1279
1280 if (!err && NumProtoRefs ) {
1281
1283 NumProtoRefs, ProtoLocs);
1285 ProtoLocs, Context);
1286 }
1287
1290 return PDecl;
1291}
1292
1297 UndefinedProtocol = PDecl;
1298 return true;
1299 }
1300
1301 for (auto *PI : PDecl->protocols())
1303 UndefinedProtocol = PI;
1304 return true;
1305 }
1306 return false;
1307}
1308
1309
1310
1311
1313 bool ForObjCContainer,
1318 LookupProtocol(Pair.getIdentifierInfo(), Pair.getLoc());
1319 if (!PDecl) {
1326 SemaRef.diagnoseTypo(Corrected,
1327 PDiag(diag::err_undeclared_protocol_suggest)
1328 << Pair.getIdentifierInfo());
1329 }
1330
1331 if (!PDecl) {
1332 Diag(Pair.getLoc(), diag::err_undeclared_protocol)
1333 << Pair.getIdentifierInfo();
1334 continue;
1335 }
1336
1339
1340
1341
1342 if (!ForObjCContainer) {
1343 (void)SemaRef.DiagnoseUseOfDecl(PDecl, Pair.getLoc());
1344 }
1345
1346
1347
1348
1350
1351 if (WarnOnDeclarations &&
1353 Diag(Pair.getLoc(), diag::warn_undef_protocolref)
1354 << Pair.getIdentifierInfo();
1355 Diag(UndefinedProtocol->getLocation(), diag::note_protocol_decl_undefined)
1356 << UndefinedProtocol;
1357 }
1358 Protocols.push_back(PDecl);
1359 }
1360}
1361
1362namespace {
1363
1364
1365class ObjCTypeArgOrProtocolValidatorCCC final
1369 public:
1370 ObjCTypeArgOrProtocolValidatorCCC(ASTContext &context,
1372 : Context(context), LookupKind(lookupKind) { }
1373
1374 bool ValidateCandidate(const TypoCorrection &candidate) override {
1375
1378 return true;
1379 }
1380
1381
1383
1385
1386
1387
1389 return false;
1390
1391
1392
1394 type->isDependentType() ||
1396 return true;
1397
1398 return false;
1399 }
1400
1401
1402
1404 return true;
1405
1406 return false;
1407 }
1408
1409 return false;
1410 }
1411
1412 std::unique_ptr clone() override {
1413 return std::make_unique(*this);
1414 }
1415};
1416}
1417
1422 bool SelectProtocolFirst) {
1423 Diag(TypeArgLoc, diag::err_objc_type_args_and_protocols)
1424 << SelectProtocolFirst << TypeArgId << ProtocolId
1426}
1427
1435 bool warnOnIncompleteProtocols) {
1437
1438
1439 unsigned numProtocolsResolved = 0;
1440 auto resolvedAsProtocols = [&] {
1441 assert(numProtocolsResolved == identifiers.size() && "Unresolved protocols");
1442
1443
1444
1445
1447 QualType base = SemaRef.GetTypeFromParser(baseType, nullptr);
1448 bool allAreTypeNames = false;
1450 if (!base.isNull()) {
1452 baseClass = objcObjectType->getInterface();
1453 if (baseClass) {
1455 if (typeParams->size() == numProtocolsResolved) {
1456
1457 allAreTypeNames = true;
1458 }
1459 }
1460 }
1461 }
1462 }
1463
1464 for (unsigned i = 0, n = protocols.size(); i != n; ++i) {
1467
1468
1469 if (!warnOnIncompleteProtocols) {
1470 (void)SemaRef.DiagnoseUseOfDecl(proto, identifierLocs[i]);
1471 }
1472
1473
1476
1477
1478
1479
1481 if (warnOnIncompleteProtocols &&
1483 Diag(identifierLocs[i], diag::warn_undef_protocolref)
1485 Diag(forwardDecl->getLocation(), diag::note_protocol_decl_undefined)
1486 << forwardDecl;
1487 }
1488
1489
1490
1491
1492 if (allAreTypeNames) {
1493 if (auto *decl =
1494 SemaRef.LookupSingleName(S, identifiers[i], identifierLocs[i],
1497 if (firstClassNameLoc.isInvalid())
1498 firstClassNameLoc = identifierLocs[i];
1500
1501 allAreTypeNames = false;
1502 }
1503 } else {
1504 allAreTypeNames = false;
1505 }
1506 }
1507 }
1508
1509
1510
1511
1512
1513 if (allAreTypeNames && firstClassNameLoc.isValid()) {
1515 Context.CollectInheritedProtocols(baseClass, knownProtocols);
1516 bool allProtocolsDeclared = true;
1517 for (auto *proto : protocols) {
1518 if (knownProtocols.count(static_cast<ObjCProtocolDecl *>(proto)) == 0) {
1519 allProtocolsDeclared = false;
1520 break;
1521 }
1522 }
1523
1524 if (allProtocolsDeclared) {
1525 Diag(firstClassNameLoc, diag::warn_objc_redundant_qualified_class_type)
1528 SemaRef.getLocForEndOfToken(firstClassNameLoc), " *");
1529 }
1530 }
1531
1532 protocolLAngleLoc = lAngleLoc;
1533 protocolRAngleLoc = rAngleLoc;
1534 assert(protocols.size() == identifierLocs.size());
1535 };
1536
1537
1538 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1540 protocols.push_back(proto);
1541 if (proto)
1542 ++numProtocolsResolved;
1543 }
1544
1545
1546 if (numProtocolsResolved == identifiers.size())
1547 return resolvedAsProtocols();
1548
1549
1550
1551
1552
1553 typedef llvm::PointerUnion<TypeDecl *, ObjCInterfaceDecl *> TypeOrClassDecl;
1555 unsigned numTypeDeclsResolved = 0;
1556 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1559 if () {
1560 typeDecls.push_back(TypeOrClassDecl());
1561 continue;
1562 }
1563
1564 if (auto typeDecl = dyn_cast(decl)) {
1565 typeDecls.push_back(typeDecl);
1566 ++numTypeDeclsResolved;
1567 continue;
1568 }
1569
1570 if (auto objcClass = dyn_cast(decl)) {
1571 typeDecls.push_back(objcClass);
1572 ++numTypeDeclsResolved;
1573 continue;
1574 }
1575
1576 typeDecls.push_back(TypeOrClassDecl());
1577 }
1578
1580
1581
1582
1583 auto resolveTypeReference = [&](TypeOrClassDecl typeDecl, SourceLocation loc)
1585
1587 const char* prevSpec;
1588 unsigned diagID;
1590 if (auto *actualTypeDecl = dyn_cast<TypeDecl *>(typeDecl))
1593 std::nullopt, actualTypeDecl);
1594 else
1596 TypeSourceInfo *parsedTSInfo = Context.getTrivialTypeSourceInfo(type, loc);
1599 parsedType, Context.getPrintingPolicy());
1600
1603
1604
1606
1607
1608
1617 starLoc);
1618
1619
1620 Diag(loc, diag::err_objc_type_arg_missing_star)
1623 }
1624
1625
1626 return SemaRef.ActOnTypeName(D);
1627 };
1628
1629
1630
1631 auto resolvedAsTypeDecls = [&] {
1632
1633 protocols.clear();
1634
1635 assert(numTypeDeclsResolved == identifiers.size() && "Unresolved type decl");
1636
1637 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1638
1639 TypeResult type = resolveTypeReference(typeDecls[i], identifierLocs[i]);
1640 if (.isUsable()) {
1641 typeArgs.clear();
1642 return;
1643 }
1644
1645 typeArgs.push_back(type.get());
1646 }
1647
1648 typeArgsLAngleLoc = lAngleLoc;
1649 typeArgsRAngleLoc = rAngleLoc;
1650 };
1651
1652
1653
1654 if (numTypeDeclsResolved == identifiers.size())
1655 return resolvedAsTypeDecls();
1656
1657
1658
1659
1661 for (unsigned i = 0, n = identifiers.size(); i != n; ++i) {
1662
1663
1664 if (protocols[i] || typeDecls[i]) {
1665
1666
1668
1669
1670 if (protocols[i] && typeDecls[i])
1671 continue;
1672
1673
1674
1677 continue;
1678 }
1679
1680
1681
1683 continue;
1684
1685
1686
1688 continue;
1689
1690
1691
1693 identifiers[i], identifierLocs[i],
1694 protocols[i] != nullptr);
1695
1696 protocols.clear();
1697 typeArgs.clear();
1698 return;
1699 }
1700
1701
1702 ObjCTypeArgOrProtocolValidatorCCC CCC(Context, lookupKind);
1706 if (corrected) {
1707
1709 SemaRef.diagnoseTypo(corrected,
1710 PDiag(diag::err_undeclared_protocol_suggest)
1711 << identifiers[i]);
1713 protocols[i] = proto;
1714 ++numProtocolsResolved;
1715 continue;
1716 }
1717
1718
1720 SemaRef.diagnoseTypo(corrected,
1721 PDiag(diag::err_unknown_typename_suggest)
1722 << identifiers[i]);
1724 typeDecls[i] = typeDecl;
1725 ++numTypeDeclsResolved;
1726 continue;
1727 }
1728
1729
1731 SemaRef.diagnoseTypo(corrected,
1732 PDiag(diag::err_unknown_type_or_class_name_suggest)
1733 << identifiers[i] << true);
1735 typeDecls[i] = objcClass;
1736 ++numTypeDeclsResolved;
1737 continue;
1738 }
1739 }
1740
1741
1742 Diag(identifierLocs[i],
1745 ? diag::err_undeclared_protocol
1746 : diag::err_unknown_typename))
1747 << identifiers[i];
1748 protocols.clear();
1749 typeArgs.clear();
1750 return;
1751 }
1752
1753
1754
1755 if (numProtocolsResolved == identifiers.size())
1756 return resolvedAsProtocols();
1757
1758
1759 assert(numTypeDeclsResolved == identifiers.size() && "Not all types?");
1760 return resolvedAsTypeDecls();
1761}
1762
1763
1764
1765
1768 if (!ID)
1769 return;
1770
1771 llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
1772 for (auto *MD : ID->methods())
1773 MethodMap[MD->getSelector()] = MD;
1774
1775 if (MethodMap.empty())
1776 return;
1779 if (PrevMethod &&
1782 Diag(Method->getLocation(), diag::err_duplicate_method_decl)
1783 << Method->getDeclName();
1784 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
1785 }
1786 }
1787}
1788
1789
1795 for (const IdentifierLoc &IdentPair : IdentList) {
1796 IdentifierInfo *Ident = IdentPair.getIdentifierInfo();
1798 Ident, IdentPair.getLoc(), SemaRef.forRedeclarationInCurContext());
1801 IdentPair.getLoc(), AtProtocolLoc, PrevDecl);
1802
1805
1806 SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, PDecl, attrList);
1807 SemaRef.AddPragmaAttributes(SemaRef.TUScope, PDecl);
1808
1809 if (PrevDecl)
1810 SemaRef.mergeDeclAttributes(PDecl, PrevDecl);
1811
1812 DeclsInGroup.push_back(PDecl);
1813 }
1814
1815 return SemaRef.BuildDeclaratorGroup(DeclsInGroup);
1816}
1817
1822 Decl *const *ProtoRefs, unsigned NumProtoRefs,
1828
1829
1830
1831 if (!IDecl ||
1832 SemaRef.RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
1833 diag::err_category_forward_interface,
1834 CategoryName == nullptr)) {
1835
1836
1837
1839 AtInterfaceLoc, ClassLoc, CategoryLoc,
1840 CategoryName, IDecl, typeParamList);
1842 SemaRef.CurContext->addDecl(CDecl);
1843
1844 if (!IDecl)
1845 Diag(ClassLoc, diag::err_undef_interface) << ClassName;
1847 return CDecl;
1848 }
1849
1851 Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;
1853 diag::note_implementation_declared);
1854 }
1855
1856 if (CategoryName) {
1857
1860
1861 Diag(CategoryLoc, diag::warn_dup_category_def)
1862 << ClassName << CategoryName;
1863 Diag(Previous->getLocation(), diag::note_previous_definition);
1864 }
1865 }
1866
1867
1868 if (typeParamList) {
1871 SemaRef, prevTypeParamList, typeParamList,
1872 CategoryName ? TypeParamListContext::Category
1873 : TypeParamListContext::Extension))
1874 typeParamList = nullptr;
1875 } else {
1877 diag::err_objc_parameterized_category_nonclass)
1878 << (CategoryName != nullptr)
1879 << ClassName
1881
1882 typeParamList = nullptr;
1883 }
1884 }
1885
1887 ClassLoc, CategoryLoc, CategoryName, IDecl,
1888 typeParamList);
1889
1890 SemaRef.CurContext->addDecl(CDecl);
1891
1892
1893
1894
1895 SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, CDecl, AttrList);
1896 SemaRef.AddPragmaAttributes(SemaRef.TUScope, CDecl);
1897
1898 if (NumProtoRefs) {
1900 NumProtoRefs, ProtoLocs);
1902 ProtoLocs, Context);
1903
1906 NumProtoRefs, Context);
1907 }
1908
1911 return CDecl;
1912}
1913
1914
1915
1916
1926 if (!CatIDecl) {
1927
1928
1929 CatIDecl =
1931 ClassLoc, CatLoc, CatName, IDecl,
1932 nullptr);
1934 }
1935 }
1936
1939 ClassLoc, AtCatImplLoc, CatLoc);
1940
1941 if (!IDecl) {
1942 Diag(ClassLoc, diag::err_undef_interface) << ClassName;
1944 } else if (SemaRef.RequireCompleteType(ClassLoc,
1945 Context.getObjCInterfaceType(IDecl),
1946 diag::err_undef_interface)) {
1948 }
1949
1950 SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, CDecl, Attrs);
1951 SemaRef.AddPragmaAttributes(SemaRef.TUScope, CDecl);
1952
1953
1954 SemaRef.CurContext->addDecl(CDecl);
1955
1956
1957
1958 if (IDecl && IDecl->hasAttr()) {
1959 Diag(ClassLoc, diag::err_objc_runtime_visible_category)
1961 }
1962
1963
1964 if (CatIDecl) {
1966 Diag(ClassLoc, diag::err_dup_implementation_category) << ClassName
1967 << CatName;
1969 diag::note_previous_definition);
1971 } else {
1973
1974
1977 }
1978 }
1979
1982 return CDecl;
1983}
1984
1991
1994 SemaRef.forRedeclarationInCurContext());
1996 Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
1997 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
1998 } else if ((IDecl = dyn_cast_or_null(PrevDecl))) {
1999
2000
2001 SemaRef.RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
2002 diag::warn_undef_interface);
2003 } else {
2004
2005
2006 ObjCInterfaceValidatorCCC CCC{};
2011
2012
2013
2015 Corrected, PDiag(diag::warn_undef_interface_suggest) << ClassName,
2016 false);
2017 } else {
2018 Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
2019 }
2020 }
2021
2022
2024 if (SuperClassname) {
2025
2026 PrevDecl =
2027 SemaRef.LookupSingleName(SemaRef.TUScope, SuperClassname, SuperClassLoc,
2030 Diag(SuperClassLoc, diag::err_redefinition_different_kind)
2031 << SuperClassname;
2032 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
2033 } else {
2034 SDecl = dyn_cast_or_null(PrevDecl);
2036 SDecl = nullptr;
2037 if (!SDecl)
2038 Diag(SuperClassLoc, diag::err_undef_superclass)
2039 << SuperClassname << ClassName;
2041
2042
2043 Diag(SuperClassLoc, diag::err_conflicting_super_class)
2045 Diag(SDecl->getLocation(), diag::note_previous_definition);
2046 }
2047 }
2048 }
2049
2050 if (!IDecl) {
2051
2052
2053
2054
2055
2056 IDecl =
2058 ClassName, nullptr,
2059 nullptr, ClassLoc, true);
2060 SemaRef.AddPragmaAttributes(SemaRef.TUScope, IDecl);
2062 if (SDecl) {
2063 IDecl->setSuperClass(Context.getTrivialTypeSourceInfo(
2064 Context.getObjCInterfaceType(SDecl),
2065 SuperClassLoc));
2067 } else {
2069 }
2070
2072 } else {
2073
2074
2075
2078 }
2079
2082 ClassLoc, AtClassImplLoc, SuperClassLoc);
2083
2084 SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, IMPDecl, Attrs);
2085 SemaRef.AddPragmaAttributes(SemaRef.TUScope, IMPDecl);
2086
2089 return IMPDecl;
2090 }
2091
2092
2094
2095 Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
2097 diag::note_previous_definition);
2099 } else {
2101 SemaRef.PushOnScopeChains(IMPDecl, SemaRef.TUScope);
2102
2103
2105 }
2106
2107
2108
2111 Diag(ClassLoc, diag::err_objc_runtime_visible_subclass)
2114 }
2115
2117 return IMPDecl;
2118}
2119
2124 DeclsInGroup.reserve(Decls.size() + 1);
2125
2126 for (unsigned i = 0, e = Decls.size(); i != e; ++i) {
2127 Decl *Dcl = Decls[i];
2128 if (!Dcl)
2129 continue;
2132 DeclsInGroup.push_back(Dcl);
2133 }
2134
2135 DeclsInGroup.push_back(ObjCImpDecl);
2136
2137
2138
2139 if (auto *ImplD = dyn_cast(ObjCImpDecl))
2140 if (!ImplD->ivar_empty())
2142
2143 return SemaRef.BuildDeclaratorGroup(DeclsInGroup);
2144}
2145
2149 assert(ImpDecl && "missing implementation decl");
2152 if (!IDecl)
2153 return;
2154
2155
2156
2159
2160 for (unsigned i = 0, e = numIvars; i != e; ++i) {
2162
2163
2164
2165
2168 ImpDecl->addDecl(ivars[i]);
2169 }
2170
2171 return;
2172 }
2173
2174 if (numIvars == 0)
2175 return;
2176
2177 assert(ivars && "missing @implementation ivars");
2180 Diag(ImpDecl->getLocation(), diag::warn_on_superclass_use);
2181 for (unsigned i = 0; i < numIvars; i++) {
2185 Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
2186 Diag(ClsIvar->getLocation(), diag::note_previous_definition);
2187 continue;
2188 }
2189
2192 CDecl->getIvarDecl(ImplIvar->getIdentifier())) {
2193 Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration);
2194 Diag(ClsExtIvar->getLocation(), diag::note_previous_definition);
2195 continue;
2196 }
2197 }
2198
2201 ImpDecl->addDecl(ImplIvar);
2202 }
2203 return;
2204 }
2205
2206
2207
2208 unsigned j = 0;
2211 for (; numIvars > 0 && IVI != IVE; ++IVI) {
2214 assert (ImplIvar && "missing implementation ivar");
2215 assert (ClsIvar && "missing class ivar");
2216
2217
2218 if (!Context.hasSameType(ImplIvar->getType(), ClsIvar->getType())) {
2219 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
2222 Diag(ClsIvar->getLocation(), diag::note_previous_definition);
2226 diag::err_conflicting_ivar_bitwidth)
2229 diag::note_previous_definition);
2230 }
2231
2233 Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
2235 Diag(ClsIvar->getLocation(), diag::note_previous_definition);
2236 }
2237 --numIvars;
2238 }
2239
2240 if (numIvars > 0)
2241 Diag(ivars[j]->getLocation(), diag::err_inconsistent_ivar_count);
2242 else if (IVI != IVE)
2243 Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count);
2244}
2245
2250
2253 unsigned DiagID,
2254 NamedDecl *NeededFor = nullptr) {
2256 return;
2257
2258
2259
2260
2261
2262
2263 {
2265 S.Diag(Impl->getLocation(), DiagID);
2266 B << method;
2267 if (NeededFor)
2268 B << NeededFor;
2269
2270
2271 std::string FixItStr;
2272 llvm::raw_string_ostream Out(FixItStr);
2273 method->print(Out, Impl->getASTContext().getPrintingPolicy());
2274 Out << " {\n}\n\n";
2275
2276 SourceLocation Loc = Impl->getAtEndRange().getBegin();
2278 }
2279
2280
2282 if (MethodLoc.isValid())
2283 S.Diag(MethodLoc, diag::note_method_declared_at) << method;
2284}
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2322 bool rejectId) {
2323
2324 if (rejectId && B->isObjCIdType()) return false;
2325
2326
2327
2328
2329
2332 Context.ObjCQualifiedIdTypesAreCompatible(A, B, false);
2333 }
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348 return Context.canAssignObjCInterfaces(A, B);
2349}
2350
2354
2355
2359 (y & ~Decl::OBJC_TQ_CSNullability);
2360}
2361
2365 bool IsProtocolMethodDecl,
2366 bool IsOverridingMode,
2367 bool Warn) {
2368 if (IsProtocolMethodDecl &&
2371 if (Warn) {
2373 (IsOverridingMode
2374 ? diag::warn_conflicting_overriding_ret_type_modifiers
2375 : diag::warn_conflicting_ret_type_modifiers))
2378 S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
2380 }
2381 else
2382 return false;
2383 }
2384 if (Warn && IsOverridingMode &&
2388 false)) {
2392 diag::warn_conflicting_nullability_attr_overriding_ret_types)
2399 S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
2400 }
2401
2404 return true;
2405 if (!Warn)
2406 return false;
2407
2408 unsigned DiagID =
2409 IsOverridingMode ? diag::warn_conflicting_overriding_ret_types
2410 : diag::warn_conflicting_ret_types;
2411
2412
2413
2418
2419
2420
2421
2423 return false;
2424
2425 DiagID =
2426 IsOverridingMode ? diag::warn_non_covariant_overriding_ret_types
2427 : diag::warn_non_covariant_ret_types;
2428 }
2429 }
2430
2436 ? diag::note_previous_declaration
2437 : diag::note_previous_definition)
2439 return false;
2440}
2441
2447 bool IsProtocolMethodDecl,
2448 bool IsOverridingMode,
2449 bool Warn) {
2450 if (IsProtocolMethodDecl &&
2453 if (Warn) {
2454 if (IsOverridingMode)
2456 diag::warn_conflicting_overriding_param_modifiers)
2460 diag::warn_conflicting_param_modifiers)
2463 S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration)
2465 }
2466 else
2467 return false;
2468 }
2469
2472 if (Warn && IsOverridingMode &&
2476 diag::warn_conflicting_nullability_attr_overriding_param_types)
2483 S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration);
2484 }
2486 return true;
2487
2488 if (!Warn)
2489 return false;
2490 unsigned DiagID =
2491 IsOverridingMode ? diag::warn_conflicting_overriding_param_types
2492 : diag::warn_conflicting_param_types;
2493
2494
2495
2500
2501
2502
2503
2505 return false;
2506
2507 DiagID =
2508 IsOverridingMode ? diag::warn_non_contravariant_overriding_param_types
2509 : diag::warn_non_contravariant_param_types;
2510 }
2511 }
2512
2515 << MethodImpl->getDeclName() << IfaceTy << ImplTy;
2517 (IsOverridingMode ? diag::note_previous_declaration
2518 : diag::note_previous_definition))
2520 return false;
2521}
2522
2523
2524
2529 if (implFamily == declFamily) return false;
2530
2531
2532
2533
2535
2536
2537 if (impl->isInvalidDecl() || decl->isInvalidDecl()) return true;
2538
2541 unsigned errorID = diag::err_arc_lost_method_convention;
2542 unsigned noteID = diag::note_arc_lost_method_convention;
2543 if (declFamily == OMF_None) {
2544 unmatched = decl;
2545 family = implFamily;
2546 errorID = diag::err_arc_gained_method_convention;
2547 noteID = diag::note_arc_gained_method_convention;
2548 }
2549
2550
2551 enum FamilySelector {
2552 F_alloc, F_copy, F_mutableCopy = F_copy, F_init, F_new
2553 };
2554 FamilySelector familySelector = FamilySelector();
2555
2556 switch (family) {
2557 case OMF_None: llvm_unreachable("logic error, no method convention");
2567
2568
2569 return false;
2570
2571 case OMF_init: familySelector = F_init; break;
2572 case OMF_alloc: familySelector = F_alloc; break;
2573 case OMF_copy: familySelector = F_copy; break;
2574 case OMF_mutableCopy: familySelector = F_mutableCopy; break;
2575 case OMF_new: familySelector = F_new; break;
2576 }
2577
2578 enum ReasonSelector { R_NonObjectReturn, R_UnrelatedReturn };
2579 ReasonSelector reasonSelector;
2580
2581
2582
2584 reasonSelector = R_UnrelatedReturn;
2585 } else {
2586 reasonSelector = R_NonObjectReturn;
2587 }
2588
2589 S.Diag(impl->getLocation(), errorID) << int(familySelector) << int(reasonSelector);
2590 S.Diag(decl->getLocation(), noteID) << int(familySelector) << int(reasonSelector);
2591
2592 return true;
2593}
2594
2597 bool IsProtocolMethodDecl) {
2600 return;
2601
2603 IsProtocolMethodDecl, false, true);
2604
2608 IM != EM && IF != EF; ++IM, ++IF) {
2610 IsProtocolMethodDecl, false, true);
2611 }
2612
2615 diag::warn_conflicting_variadic);
2616 Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
2617 }
2618}
2619
2622 bool IsProtocolMethodDecl) {
2623
2625 true, true);
2626
2630 IM != EM && IF != EF; ++IM, ++IF) {
2632 IsProtocolMethodDecl, true, true);
2633 }
2634
2637 diag::warn_conflicting_overriding_variadic);
2638 Diag(Overridden->getLocation(), diag::note_previous_declaration);
2639 }
2640}
2641
2642
2643
2646 bool IsProtocolMethodDecl) {
2648
2649
2650
2653 return;
2654
2655
2656 if (MethodDecl->hasAttr() ||
2657 MethodDecl->hasAttr())
2658 return;
2659
2661 IsProtocolMethodDecl, false, false);
2666 IM != EM && IF != EF; ++IM, ++IF) {
2668 *IF, IsProtocolMethodDecl, false, false);
2670 break;
2671 }
2677
2680 diag::warn_category_method_impl_match);
2681 Diag(MethodDecl->getLocation(), diag::note_method_declared_at)
2683 }
2684}
2685
2686
2687
2688
2689
2690
2691
2694
2697 if (PDecl->hasAttr())
2699 for (const auto *PI : PDecl->protocols())
2701}
2702
2703
2704
2705
2708 if (!Super)
2709 return;
2710
2713
2715}
2716
2717
2718
2725 : dyn_cast(CDecl);
2726 assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");
2727
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742 if (PDecl->hasAttr()) {
2743 if (!ProtocolsExplictImpl) {
2746 }
2747 if (ProtocolsExplictImpl->contains(PDecl->getIdentifier()))
2748 return;
2749
2750
2751
2752 Super = nullptr;
2753 }
2754
2756
2757
2758
2759
2760
2761
2762
2765 if (InsMap.count(fISelector))
2766
2767
2769 }
2770
2771
2775
2776
2777
2778
2779
2780
2781
2782 if (!NSIDecl)
2784 if (method->getImplementationControl() !=
2786 !method->isPropertyAccessor() &&
2787 !InsMap.count(method->getSelector()) &&
2789 method->getSelector(), true ,
2790 false , true ,
2791 nullptr ))) {
2792
2793
2794
2795
2796
2797
2798
2799
2800
2802 method->getSelector(), true ,
2803 true , false ))
2804 if (C || MethodInClass->isPropertyAccessor())
2805 continue;
2806 unsigned DIAG = diag::warn_unimplemented_protocol_method;
2809 }
2810 }
2811 }
2812
2814 if (method->getImplementationControl() !=
2816 !ClsMap.count(method->getSelector()) &&
2818 method->getSelector(), false ,
2819 false ,
2820 true , nullptr ))) {
2821
2822 if (C && IDecl->lookupMethod(method->getSelector(),
2823 false ,
2824 true ,
2825 false ))
2826 continue;
2827
2828 unsigned DIAG = diag::warn_unimplemented_protocol_method;
2831 }
2832 }
2833 }
2834
2835 for (auto *PI : PDecl->protocols())
2837 ProtocolsExplictImpl);
2838}
2839
2840
2841
2842
2846 ObjCContainerDecl *CDecl, bool &IncompleteImpl, bool ImmediateClass,
2847 bool WarnCategoryMethodImpl) {
2848
2849
2851 if (!InsMapSeen.insert(I->getSelector()).second)
2852 continue;
2853 if (!I->isPropertyAccessor() &&
2854 !InsMap.count(I->getSelector())) {
2855 if (ImmediateClass)
2857 diag::warn_undef_method_impl);
2858 continue;
2859 } else {
2862 assert(CDecl->getInstanceMethod(I->getSelector(), true) &&
2863 "Expected to find the method through lookup as well");
2864
2865 if (ImpMethodDecl) {
2866
2868 continue;
2869 if (!WarnCategoryMethodImpl)
2872 else if (!I->isPropertyAccessor())
2874 }
2875 }
2876 }
2877
2878
2879
2881 if (!ClsMapSeen.insert(I->getSelector()).second)
2882 continue;
2883 if (!I->isPropertyAccessor() &&
2884 !ClsMap.count(I->getSelector())) {
2885 if (ImmediateClass)
2887 diag::warn_undef_method_impl);
2888 } else {
2891 assert(CDecl->getClassMethod(I->getSelector(), true) &&
2892 "Expected to find the method through lookup as well");
2893
2894 if (ImpMethodDecl) {
2895
2897 continue;
2898 if (!WarnCategoryMethodImpl)
2901 else if (!I->isPropertyAccessor())
2903 }
2904 }
2905 }
2906
2907 if (ObjCProtocolDecl *PD = dyn_cast (CDecl)) {
2908
2909
2910 for (auto *PI : PD->protocols())
2912 IMPDecl, PI, IncompleteImpl, false,
2913 WarnCategoryMethodImpl);
2914 }
2915
2916 if (ObjCInterfaceDecl *I = dyn_cast (CDecl)) {
2917
2918
2919
2920 if (!WarnCategoryMethodImpl) {
2921 for (auto *Cat : I->visible_categories())
2923 IMPDecl, Cat, IncompleteImpl,
2924 ImmediateClass && Cat->IsClassExtension(),
2925 WarnCategoryMethodImpl);
2926 } else {
2927
2928 for (auto *Ext : I->visible_extensions())
2930 IMPDecl, Ext, IncompleteImpl, false,
2931 WarnCategoryMethodImpl);
2932 }
2933
2934
2935 for (auto *PI : I->all_referenced_protocols())
2937 IMPDecl, PI, IncompleteImpl, false,
2938 WarnCategoryMethodImpl);
2939
2940
2941
2942 if (!WarnCategoryMethodImpl && I->getSuperClass())
2944 IMPDecl,
2945 I->getSuperClass(), IncompleteImpl, false);
2946 }
2947}
2948
2949
2950
2951
2954
2956 if (!CatDecl)
2957 return;
2959 if (!IDecl)
2960 return;
2963
2965 Selector Sel = I->getSelector();
2966
2967
2968
2969 if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true))
2970 continue;
2971 InsMap.insert(Sel);
2972 }
2973
2974 for (const auto *I : CatIMPDecl->class_methods()) {
2975 Selector Sel = I->getSelector();
2976 if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false))
2977 continue;
2978 ClsMap.insert(Sel);
2979 }
2980 if (InsMap.empty() && ClsMap.empty())
2981 return;
2982
2984 bool IncompleteImpl = false;
2986 CatIMPDecl, IDecl,
2987 IncompleteImpl, false,
2988 true );
2989}
2990
2993 bool IncompleteImpl) {
2995
2996
2998 InsMap.insert(I->getSelector());
2999
3000
3001 for (const auto *PImpl : IMPDecl->property_impls()) {
3002
3004 continue;
3005
3006 const auto *P = PImpl->getPropertyDecl();
3007 if (!P) continue;
3008
3009 InsMap.insert(P->getGetterName());
3010 if (!P->getSetterName().isNull())
3011 InsMap.insert(P->getSetterName());
3012 }
3013
3014
3015
3016
3017 if (const ObjCInterfaceDecl *IDecl = dyn_cast(CDecl)) {
3018 bool SynthesizeProperties = getLangOpts().ObjCDefaultSynthProperties &&
3020 !IDecl->isObjCRequiresPropertyDefs();
3022 }
3023
3024
3026
3029 ClsMap.insert(I->getSelector());
3030
3031
3032
3035 IMPDecl, CDecl,
3036 IncompleteImpl, true);
3037
3038
3039
3041 dyn_cast(IMPDecl))
3043
3044
3045
3046
3047
3048
3050
3051 if (ObjCInterfaceDecl *I = dyn_cast (CDecl)) {
3052 for (auto *PI : I->all_referenced_protocols())
3054 ClsMap, I, ExplicitImplProtocols);
3055 } else if (ObjCCategoryDecl *C = dyn_cast(CDecl)) {
3056
3057
3058 if (->IsClassExtension()) {
3059 for (auto *P : C->protocols())
3061 ClsMap, CDecl, ExplicitImplProtocols);
3063 false);
3064 }
3065 } else
3066 llvm_unreachable("invalid ObjCContainerDecl type.");
3067}
3068
3072 unsigned NumElts) {
3075 for (unsigned i = 0; i != NumElts; ++i) {
3076
3079 SemaRef.forRedeclarationInCurContext());
3081
3082
3083
3084
3085
3086
3087
3088 TypedefNameDecl *TDD = dyn_cast(PrevDecl);
3090 Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
3091 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
3092 } else {
3093
3094
3095
3096
3098 Diag(AtClassLoc, diag::warn_forward_class_redefinition)
3099 << IdentList[i];
3100 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
3101 continue;
3102 }
3103 }
3104 }
3105
3106
3108 = dyn_cast_or_null(PrevDecl);
3109
3111 if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3125 }
3126
3127
3128
3130 if (PrevIDecl && TypeParams) {
3132
3134 SemaRef, PrevTypeParams, TypeParams,
3135 TypeParamListContext::ForwardDeclaration)) {
3136 TypeParams = nullptr;
3137 }
3139
3140 Diag(IdentLocs[i], diag::err_objc_parameterized_forward_class)
3141 << ClassName
3143 Diag(Def->getLocation(), diag::note_defined_here)
3144 << ClassName;
3145
3146 TypeParams = nullptr;
3147 }
3148 }
3149
3151 Context, SemaRef.CurContext, AtClassLoc, ClassName, TypeParams,
3152 PrevIDecl, IdentLocs[i]);
3154
3155 if (PrevIDecl)
3156 SemaRef.mergeDeclAttributes(IDecl, PrevIDecl);
3157
3160 DeclsInGroup.push_back(IDecl);
3161 }
3162
3163 return SemaRef.BuildDeclaratorGroup(DeclsInGroup);
3164}
3165
3168 const Type *left, const Type *right);
3169
3173 const Type *left =
3174 Context.getCanonicalType(leftQT).getUnqualifiedType().getTypePtr();
3175 const Type *right =
3176 Context.getCanonicalType(rightQT).getUnqualifiedType().getTypePtr();
3177
3178 if (left == right) return true;
3179
3180
3182 return false;
3183
3185
3186
3187
3188
3189
3190 TypeInfo LeftTI = Context.getTypeInfo(left);
3191 TypeInfo RightTI = Context.getTypeInfo(right);
3193 return false;
3194
3196 return false;
3197
3198
3199
3200
3201
3204
3205
3206
3207
3208
3211
3212
3213
3222
3223
3224
3225
3226 return (leftSK == rightSK);
3227}
3228
3231 const Type *lt, const Type *rt) {
3232 assert(lt && rt && lt != rt);
3233
3237
3238
3239 if (left->isUnion() != right->isUnion()) return false;
3240
3241
3244 return false;
3245
3246
3247 TypeInfo LeftTI = Context.getTypeInfo(lt);
3248 TypeInfo RightTI = Context.getTypeInfo(rt);
3250 return false;
3251
3253 return false;
3254
3255
3258 for (; li != le && ri != re; ++li, ++ri) {
3259 if ((Context, strategy, li->getType(), ri->getType()))
3260 return false;
3261 }
3262 return (li == le && ri == re);
3263}
3264
3265
3266
3267
3274 return false;
3275
3276
3278 return false;
3279
3281 return false;
3282
3284 (left->hasAttr()
3285 != right->hasAttr() ||
3286 left->hasAttr()
3287 != right->hasAttr()))
3288 return false;
3289
3293
3294 for (; li != le && ri != re; ++li, ++ri) {
3295 assert(ri != right->param_end() && "Param mismatch");
3296 const ParmVarDecl *lparm = *li, *rparm = *ri;
3297
3298 if ((Context, strategy, lparm->getType(), rparm->getType()))
3299 return false;
3300
3302 lparm->hasAttr() != rparm->hasAttr())
3303 return false;
3304 }
3305 return true;
3306}
3307
3310 auto *MethodProtocol = dyn_cast(Method->getDeclContext());
3311 auto *MethodInListProtocol =
3312 dyn_cast(MethodInList->getDeclContext());
3313
3314
3315 if ((MethodProtocol && !MethodInListProtocol) ||
3316 (!MethodProtocol && MethodInListProtocol))
3317 return false;
3318
3319 if (MethodProtocol && MethodInListProtocol)
3320 return true;
3321
3322 ObjCInterfaceDecl *MethodInterface = Method->getClassInterface();
3325 return MethodInterface == MethodInListInterface;
3326}
3327
3330
3331
3333 dyn_cast(Method->getDeclContext()))
3334 if (!CD->IsClassExtension() && List->getBits() < 2)
3336
3337
3338 if (List->getMethod() == nullptr) {
3341 return;
3342 }
3343
3344
3345
3349
3351 continue;
3352
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365 if (!SameDeclaration ||
3367
3368
3369
3370 if (->isDefined())
3372
3373
3374
3375 if (Method->isDeprecated() && SameDeclaration &&
3377 ListWithSameDeclaration = List;
3378
3379 if (Method->isUnavailable() && SameDeclaration &&
3380 !ListWithSameDeclaration &&
3382 ListWithSameDeclaration = List;
3383 continue;
3384 }
3385
3387
3388
3389 if (Method->isDefined())
3391 else {
3392
3393
3394
3395
3397 }
3398
3399
3400
3401 if (Method->isDeprecated()) {
3404 }
3405
3406
3407 if (Method->isUnavailable()) {
3410 }
3411
3412 return;
3413 }
3414
3415
3416
3418
3419
3420 if (ListWithSameDeclaration) {
3421 auto *List = new (Mem) ObjCMethodList(*ListWithSameDeclaration);
3422
3424 ListWithSameDeclaration->setNext(List);
3425 return;
3426 }
3427
3429}
3430
3431
3432
3434 assert(SemaRef.ExternalSource && "We need an external AST source");
3435 SemaRef.ExternalSource->ReadMethodPool(Sel);
3436}
3437
3439 if (.ExternalSource)
3440 return;
3441 SemaRef.ExternalSource->updateOutOfDateSelector(Sel);
3442}
3443
3445 bool instance) {
3446
3448 return;
3449
3452
3454
3455 Method->setDefined(impl);
3456
3457 ObjCMethodList &Entry = instance ? Lists.first : Lists.second;
3459}
3460
3461
3462
3463
3464
3465
3469 return false;
3470
3472 return false;
3473
3476 return false;
3477
3478
3479
3481}
3482
3483
3486 if (!TypeBound)
3487 return true;
3488
3489 if (TypeBound->isObjCId())
3490
3491 return true;
3492
3493 auto *BoundInterface = TypeBound->getInterface();
3494 assert(BoundInterface && "unexpected object type!");
3495
3496
3497
3498 auto *MethodProtocol = dyn_cast(Method->getDeclContext());
3499 if (MethodProtocol) {
3500 return true;
3501 }
3502
3503
3504
3505 if (ObjCInterfaceDecl *MethodInterface = Method->getClassInterface()) {
3506
3507
3508
3509 return MethodInterface == BoundInterface ||
3510 MethodInterface->isSuperClassOf(BoundInterface) ||
3511 BoundInterface->isSuperClassOf(MethodInterface);
3512 }
3513 llvm_unreachable("unknown method context");
3514}
3515
3516
3517
3520 bool InstanceFirst, bool CheckTheOther, const ObjCObjectType *TypeBound) {
3521 if (SemaRef.ExternalSource)
3523
3524 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3526 return false;
3527
3528
3529 ObjCMethodList &MethList = InstanceFirst ? Pos->second.first :
3530 Pos->second.second;
3532 if (M->getMethod() && M->getMethod()->isUnconditionallyVisible()) {
3534 Methods.push_back(M->getMethod());
3535 }
3536
3537
3538 if (!Methods.empty())
3539 return Methods.size() > 1;
3540
3541 if (!CheckTheOther)
3542 return false;
3543
3544
3545 ObjCMethodList &MethList2 = InstanceFirst ? Pos->second.second :
3546 Pos->second.first;
3548 if (M->getMethod() && M->getMethod()->isUnconditionallyVisible()) {
3550 Methods.push_back(M->getMethod());
3551 }
3552
3553 return Methods.size() > 1;
3554}
3555
3559
3561 FilteredMethods.push_back(BestMethod);
3562
3563 for (auto *M : Methods)
3564 if (M != BestMethod && !M->hasAttr())
3565 FilteredMethods.push_back(M);
3566
3567 if (FilteredMethods.size() > 1)
3569 receiverIdOrClass);
3570
3571 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3572
3573
3575 return true;
3577 BestMethod->isInstanceMethod() ? Pos->second.first : Pos->second.second;
3579}
3580
3582 bool receiverIdOrClass,
3583 bool instance) {
3586
3587 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3589 return nullptr;
3590
3591
3592 ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
3594 if (M->getMethod() && M->getMethod()->isUnconditionallyVisible())
3595 return M->getMethod();
3596 }
3597 return nullptr;
3598}
3599
3602 bool receiverIdOrClass) {
3603
3604 bool issueDiagnostic = false, issueError = false;
3605
3606
3607
3608 bool strictSelectorMatch =
3609 receiverIdOrClass &&
3612 if (strictSelectorMatch) {
3613 for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
3615 issueDiagnostic = true;
3616 break;
3617 }
3618 }
3619 }
3620
3621
3622
3623
3624 if (!strictSelectorMatch ||
3625 (issueDiagnostic && getLangOpts().ObjCAutoRefCount))
3626 for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
3627
3630 issueDiagnostic = true;
3632 issueError = true;
3633 break;
3634 }
3635 }
3636
3637 if (issueDiagnostic) {
3638 if (issueError)
3639 Diag(R.getBegin(), diag::err_arc_multiple_method_decl) << Sel << R;
3640 else if (strictSelectorMatch)
3641 Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;
3642 else
3643 Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
3644
3645 Diag(Methods[0]->getBeginLoc(),
3646 issueError ? diag::note_possibility : diag::note_using)
3647 << Methods[0]->getSourceRange();
3648 for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
3649 Diag(Methods[I]->getBeginLoc(), diag::note_also_found)
3650 << Methods[I]->getSourceRange();
3651 }
3652 }
3653}
3654
3656 GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
3658 return nullptr;
3659
3660 auto &Methods = Pos->second;
3663 if (Method->getMethod() &&
3664 (Method->getMethod()->isDefined() ||
3665 Method->getMethod()->isPropertyAccessor()))
3666 return Method->getMethod();
3667
3670 if (Method->getMethod() &&
3671 (Method->getMethod()->isDefined() ||
3672 Method->getMethod()->isPropertyAccessor()))
3673 return Method->getMethod();
3674 return nullptr;
3675}
3676
3677static void
3681 const unsigned MaxEditDistance = 1;
3682 unsigned BestEditDistance = MaxEditDistance + 1;
3683 std::string MethodName = Method->getSelector().getAsString();
3684
3685 unsigned MinPossibleEditDistance = abs((int)MethodName.size() - (int)Typo.size());
3686 if (MinPossibleEditDistance > 0 &&
3687 Typo.size() / MinPossibleEditDistance < 1)
3688 return;
3689 unsigned EditDistance = Typo.edit_distance(MethodName, true, MaxEditDistance);
3690 if (EditDistance > MaxEditDistance)
3691 return;
3692 if (EditDistance == BestEditDistance)
3693 BestMethod.push_back(Method);
3694 else if (EditDistance < BestEditDistance) {
3695 BestMethod.clear();
3696 BestMethod.push_back(Method);
3697 }
3698}
3699
3702 if (ObjectType.isNull())
3703 return true;
3705 true ))
3706 return true;
3708 false ) != nullptr;
3709}
3710
3713 unsigned NumArgs = Sel.getNumArgs();
3715 bool ObjectIsId = true, ObjectIsClass = true;
3716 if (ObjectType.isNull())
3717 ObjectIsId = ObjectIsClass = false;
3719 return nullptr;
3722 ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
3723 ObjectIsId = ObjectIsClass = false;
3724 }
3726 ObjectIsClass = false;
3728 ObjectIsId = false;
3729 else
3730 return nullptr;
3731
3732 for (GlobalMethodPool::iterator b = MethodPool.begin(),
3734
3735 for (ObjCMethodList *M = &b->second.first; M; M=M->getNext())
3736 if (M->getMethod() &&
3737 (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&
3738 (M->getMethod()->getSelector() != Sel)) {
3739 if (ObjectIsId)
3740 Methods.push_back(M->getMethod());
3741 else if (!ObjectIsClass &&
3743 SemaRef, M->getMethod()->getSelector(), ObjectType))
3744 Methods.push_back(M->getMethod());
3745 }
3746
3747 for (ObjCMethodList *M = &b->second.second; M; M=M->getNext())
3748 if (M->getMethod() &&
3749 (M->getMethod()->getSelector().getNumArgs() == NumArgs) &&
3750 (M->getMethod()->getSelector() != Sel)) {
3751 if (ObjectIsClass)
3752 Methods.push_back(M->getMethod());
3753 else if (!ObjectIsId &&
3755 SemaRef, M->getMethod()->getSelector(), ObjectType))
3756 Methods.push_back(M->getMethod());
3757 }
3758 }
3759
3761 for (unsigned i = 0, e = Methods.size(); i < e; i++) {
3764 }
3765 return (SelectedMethods.size() == 1) ? SelectedMethods[0] : nullptr;
3766}
3767
3768
3769
3770
3771
3772
3775 for (auto *Ivar : ID->ivars()) {
3776 if (Ivar->isInvalidDecl())
3777 continue;
3780 if (prevIvar) {
3781 Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
3782 Diag(prevIvar->getLocation(), diag::note_previous_declaration);
3783 Ivar->setInvalidDecl();
3784 }
3785 }
3786 }
3787}
3788
3789
3792
3793 for (auto ivar = ID->getClassInterface()->all_declared_ivar_begin();
3794 ivar; ivar = ivar->getNextIvar()) {
3795 if (ivar->isInvalidDecl()) continue;
3798 S.Diag(ivar->getLocation(), diag::err_arc_weak_disabled);
3799 } else {
3800 S.Diag(ivar->getLocation(), diag::err_arc_weak_no_runtime);
3801 }
3802 }
3803 }
3804}
3805
3806
3810 return;
3811
3812 for (auto ivar = ID->all_declared_ivar_begin(); ivar;
3813 ivar = ivar->getNextIvar()) {
3814 if (ivar->isInvalidDecl())
3815 continue;
3816 QualType IvarTy = ivar->getType();
3820 S.Diag(ivar->getLocation(), diag::err_flexible_array_arc_retainable);
3821 ivar->setInvalidDecl();
3822 }
3823 }
3824}
3825
3827 switch (SemaRef.CurContext->getDeclKind()) {
3828 case Decl::ObjCInterface:
3830 case Decl::ObjCProtocol:
3832 case Decl::ObjCCategory:
3836 case Decl::ObjCImplementation:
3838 case Decl::ObjCCategoryImpl:
3840
3841 default:
3843 }
3844}
3845
3847 if (T->isIncompleteArrayType())
3848 return true;
3849 const auto *RD = T->getAsRecordDecl();
3850 return RD && RD->hasFlexibleArrayMember();
3851}
3852
3857 if ((IntfDecl = dyn_cast(OCD))) {
3858 Ivars = IntfDecl->ivars();
3859 } else if (auto *ImplDecl = dyn_cast(OCD)) {
3860 IntfDecl = ImplDecl->getClassInterface();
3861 Ivars = ImplDecl->ivars();
3862 } else if (auto *CategoryDecl = dyn_cast(OCD)) {
3863 if (CategoryDecl->IsClassExtension()) {
3864 IntfDecl = CategoryDecl->getClassInterface();
3865 Ivars = CategoryDecl->ivars();
3866 }
3867 }
3868
3869
3871 for (auto *ivar : Ivars) {
3873 S.Diag(ivar->getLocation(), diag::warn_variable_sized_ivar_visibility)
3874 << ivar->getDeclName() << ivar->getType();
3875 }
3876 }
3877 }
3878
3879
3880 if (!IntfDecl)
3881 return;
3882
3883
3886 if (ivar->isInvalidDecl() || !ivar->getNextIvar())
3887 continue;
3888 QualType IvarTy = ivar->getType();
3889 bool IsInvalidIvar = false;
3891 S.Diag(ivar->getLocation(), diag::err_flexible_array_not_at_end)
3892 << ivar->getDeclName() << IvarTy
3894 IsInvalidIvar = true;
3897 S.Diag(ivar->getLocation(), diag::err_objc_variable_sized_type_not_at_end)
3898 << ivar->getDeclName() << IvarTy;
3899 IsInvalidIvar = true;
3900 }
3901 if (IsInvalidIvar) {
3902 S.Diag(ivar->getNextIvar()->getLocation(),
3903 diag::note_next_ivar_declaration)
3904 << ivar->getNextIvar()->getSynthesize();
3905 ivar->setInvalidDecl();
3906 }
3907 }
3908
3909
3910
3911
3913 (Ivars.begin() == Ivars.end()) ? nullptr : *Ivars.begin();
3916 while (SuperClass && SuperClass->ivar_empty())
3918 if (SuperClass) {
3919 auto IvarIter = SuperClass->ivar_begin();
3920 std::advance(IvarIter, SuperClass->ivar_size() - 1);
3924 diag::warn_superclass_variable_sized_type_not_at_end)
3927 S.Diag(LastIvar->getLocation(), diag::note_entity_declared_at)
3929 }
3930 }
3931 }
3932}
3933
3936
3939 const llvm::iterator_rangeObjCProtocolList::iterator &Protocols) {
3940 for (auto *PI : Protocols)
3942}
3943
3948
3951 for (auto *MD : PDecl->methods()) {
3952 if (!MD->isPropertyAccessor()) {
3953 if (const auto *CMD =
3954 IDecl->getMethod(MD->getSelector(), MD->isInstanceMethod())) {
3955 if (CMD->isDirectMethod())
3956 DirectMembers.push_back(CMD);
3957 }
3958 }
3959 }
3960 for (auto *PD : PDecl->properties()) {
3961 if (const auto *CPD = IDecl->FindPropertyVisibleInPrimaryClass(
3962 PD->getIdentifier(),
3963 PD->isClassProperty()
3966 if (CPD->isDirectProperty())
3967 DirectMembers.push_back(CPD);
3968 }
3969 }
3970 if (!DirectMembers.empty()) {
3971 S.Diag(CDecl->getLocation(), diag::err_objc_direct_protocol_conformance)
3973 for (const auto *MD : DirectMembers)
3974 S.Diag(MD->getLocation(), diag::note_direct_member_here);
3975 return;
3976 }
3977
3978
3981}
3982
3983
3989 return nullptr;
3990
3991 assert(AtEnd.isValid() && "Invalid location for '@end'");
3992
3994 Decl *ClassDecl = OCD;
3995
3996 bool isInterfaceDeclKind =
4000
4001
4002
4003
4004
4005 if (auto *OID = dyn_cast(SemaRef.CurContext)) {
4006 for (auto *PropImpl : OID->property_impls()) {
4007 if (auto *Getter = PropImpl->getGetterMethodDecl())
4008 if (Getter->isSynthesizedAccessorStub())
4009 OID->addDecl(Getter);
4010 if (auto *Setter = PropImpl->getSetterMethodDecl())
4011 if (Setter->isSynthesizedAccessorStub())
4012 OID->addDecl(Setter);
4013 }
4014 }
4015
4016
4017 llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap;
4018 llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap;
4019
4020 for (unsigned i = 0, e = allMethods.size(); i != e; i++ ) {
4022 cast_or_null(allMethods[i]);
4023
4024 if () continue;
4025 if (Method->isInstanceMethod()) {
4026
4029 : false;
4030 if ((isInterfaceDeclKind && PrevMethod && )
4031 || (checkIdenticalMethods && match)) {
4032 Diag(Method->getLocation(), diag::err_duplicate_method_decl)
4033 << Method->getDeclName();
4034 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
4035 Method->setInvalidDecl();
4036 } else {
4037 if (PrevMethod) {
4038 Method->setAsRedeclaration(PrevMethod);
4039 if (!Context.getSourceManager().isInSystemHeader(
4040 Method->getLocation()))
4041 Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
4042 << Method->getDeclName();
4043 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
4044 }
4046
4048 }
4049 } else {
4050
4053 : false;
4054 if ((isInterfaceDeclKind && PrevMethod && )
4055 || (checkIdenticalMethods && match)) {
4056 Diag(Method->getLocation(), diag::err_duplicate_method_decl)
4057 << Method->getDeclName();
4058 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
4059 Method->setInvalidDecl();
4060 } else {
4061 if (PrevMethod) {
4062 Method->setAsRedeclaration(PrevMethod);
4063 if (!Context.getSourceManager().isInSystemHeader(
4064 Method->getLocation()))
4065 Diag(Method->getLocation(), diag::warn_duplicate_method_decl)
4066 << Method->getDeclName();
4067 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
4068 }
4071 }
4072 }
4073 }
4075
4076 } else if (ObjCCategoryDecl *C = dyn_cast(ClassDecl)) {
4077
4078
4079
4080
4081 if (C->IsClassExtension()) {
4084 }
4085
4087 C->protocols());
4088 }
4089 if (ObjCContainerDecl *CDecl = dyn_cast(ClassDecl)) {
4090 if (CDecl->getIdentifier())
4091
4092
4093
4094 for (auto *I : CDecl->properties())
4096 CDecl->setAtEndRange(AtEnd);
4097 }
4099 IC->setAtEndRange(AtEnd);
4101
4102
4103
4104
4105
4106 for (const auto *Ext : IDecl->visible_extensions()) {
4107 for (const auto *Property : Ext->instance_properties()) {
4108
4110 = IC->FindPropertyImplDecl(Property->getIdentifier(),
4112 if (PIDecl->getPropertyImplementation()
4114 continue;
4115
4116 for (const auto *Ext : IDecl->visible_extensions()) {
4118 Ext->getInstanceMethod(Property->getGetterName()))
4119 GetterMethod->setPropertyAccessor(true);
4120 if (->isReadOnly())
4122 = Ext->getInstanceMethod(Property->getSetterName()))
4123 SetterMethod->setPropertyAccessor(true);
4124 }
4125 }
4126 }
4131 if (IDecl->hasDesignatedInitializers())
4135
4136 bool HasRootClassAttr = IDecl->hasAttr();
4137 if (IDecl->getSuperClass() == nullptr) {
4138
4139
4140 if (!HasRootClassAttr) {
4143 Diag(DeclLoc, diag::warn_objc_root_class_missing)
4144 << IDecl->getIdentifier();
4145
4146
4150 ObjCInterfaceDecl *NSObjectDecl = dyn_cast_or_null(IF);
4151 if (NSObjectDecl && NSObjectDecl->getDefinition()) {
4152 Diag(SuperClassLoc, diag::note_objc_needs_superclass)
4154 } else {
4155 Diag(SuperClassLoc, diag::note_objc_needs_superclass);
4156 }
4157 }
4158 } else if (HasRootClassAttr) {
4159
4160 Diag(IDecl->getLocation(), diag::err_objc_root_class_subclass);
4161 }
4162
4164
4165
4166
4167
4168 if (IDecl->hasAttr() &&
4169 Super->hasAttr()) {
4170 Diag(IC->getLocation(), diag::err_restricted_superclass_mismatch);
4171 Diag(Super->getLocation(), diag::note_class_declared);
4172 }
4173 }
4174
4175 if (IDecl->hasAttr())
4176 Diag(IC->getLocation(), diag::err_implementation_of_class_stub);
4177
4179 while (IDecl->getSuperClass()) {
4181 IDecl = IDecl->getSuperClass();
4182 }
4183 }
4184 }
4187 dyn_cast(ClassDecl)) {
4188 CatImplClass->setAtEndRange(AtEnd);
4189
4190
4191
4192 if (ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface()) {
4194 = IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier())) {
4196 }
4197 }
4198 } else if (const auto *IntfDecl = dyn_cast(ClassDecl)) {
4200 if (!IntfDecl->hasAttr() &&
4201 Super->hasAttr()) {
4202 Diag(IntfDecl->getLocation(), diag::err_restricted_superclass_mismatch);
4203 Diag(Super->getLocation(), diag::note_class_declared);
4204 }
4205 }
4206
4207 if (IntfDecl->hasAttr() &&
4208 !IntfDecl->hasAttr())
4209 Diag(IntfDecl->getLocation(), diag::err_class_stub_subclassing_mismatch);
4210 }
4212 if (isInterfaceDeclKind) {
4213
4214 for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
4217 if (VarDecl *VDecl = dyn_cast(*I)) {
4218 if (!VDecl->hasExternalStorage())
4219 Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass);
4220 }
4221 }
4222 }
4224
4225 for (unsigned i = 0, e = allTUVars.size(); i != e; i++) {
4228 (*I)->setTopLevelDeclInObjCContainer();
4229 SemaRef.Consumer.HandleTopLevelDeclInObjCContainer(DG);
4230 }
4231
4232 SemaRef.ActOnDocumentableDecl(ClassDecl);
4233 return ClassDecl;
4234}
4235
4236
4237
4242
4243
4244
4245
4249 QualType ResultType = Method->getReturnType();
4250
4251
4252
4253
4256
4257 if (ResultObjectType->isObjCIdType() ||
4258 ResultObjectType->isObjCQualifiedIdType())
4260
4261 if (CurrentClass) {
4263 = ResultObjectType->getInterfaceDecl()) {
4264
4267
4268
4269 if (ResultClass->isSuperClassOf(CurrentClass))
4271 }
4272 } else {
4273
4274
4276 }
4277 }
4278
4280}
4281
4282namespace {
4283
4284
4285class OverrideSearch {
4286public:
4287 const ObjCMethodDecl *Method;
4288 llvm::SmallSetVector<ObjCMethodDecl*, 4> Overridden;
4289 bool Recursive;
4290
4291public:
4292 OverrideSearch(Sema &S, const ObjCMethodDecl *method) : Method(method) {
4293 Selector selector = method->getSelector();
4294
4295
4296
4297 SemaObjC::GlobalMethodPool::iterator it =
4298 S.ObjC().MethodPool.find(selector);
4300 if (!S.getExternalSource()) return;
4301 S.ObjC().ReadMethodPool(selector);
4302
4303 it = S.ObjC().MethodPool.find(selector);
4304 if (it == S.ObjC().MethodPool.end())
4305 return;
4306 }
4307 const ObjCMethodList &list =
4308 method->isInstanceMethod() ? it->second.first : it->second.second;
4309 if (!list.getMethod()) return;
4310
4311 const ObjCContainerDecl *container
4313
4314
4315
4316
4317 if (const ObjCCategoryDecl *Category =
4318 dyn_cast(container)) {
4319 searchFromContainer(container);
4320 if (const ObjCInterfaceDecl *Interface = Category->getClassInterface())
4322 } else {
4323 searchFromContainer(container);
4324 }
4325 }
4326
4327 typedef decltype(Overridden)::iterator iterator;
4328 iterator begin() const { return Overridden.begin(); }
4329 iterator end() const { return Overridden.end(); }
4330
4331private:
4332 void searchFromContainer(const ObjCContainerDecl *container) {
4334
4336#define OBJCCONTAINER(type, base) \
4337 case Decl::type: \
4338 searchFrom(cast<type##Decl>(container)); \
4339 break;
4340#define ABSTRACT_DECL(expansion)
4341#define DECL(type, base) \
4342 case Decl::type:
4343#include "clang/AST/DeclNodes.inc"
4344 llvm_unreachable("not an ObjC container!");
4345 }
4346 }
4347
4348 void searchFrom(const ObjCProtocolDecl *protocol) {
4350 return;
4351
4352
4353
4355 }
4356
4357 void searchFrom(const ObjCCategoryDecl *category) {
4358
4359
4360
4362 }
4363
4364 void searchFrom(const ObjCCategoryImplDecl *impl) {
4365
4366
4367
4368 if (ObjCCategoryDecl *category = impl->getCategoryDecl()) {
4369 search(category);
4370 if (ObjCInterfaceDecl *Interface = category->getClassInterface())
4372
4373
4376 }
4377 }
4378
4379 void searchFrom(const ObjCInterfaceDecl *iface) {
4380
4382 return;
4383
4384
4386 search(Cat);
4387
4388
4389 if (ObjCInterfaceDecl *super = iface->getSuperClass())
4390 search(super);
4391
4392
4394 }
4395
4396 void searchFrom(const ObjCImplementationDecl *impl) {
4397
4398
4401 }
4402
4403 void search(const ObjCProtocolList &protocols) {
4404 for (const auto *Proto : protocols)
4405 search(Proto);
4406 }
4407
4408 void search(const ObjCContainerDecl *container) {
4409
4410 ObjCMethodDecl *meth = container->getMethod(Method->getSelector(),
4411 Method->isInstanceMethod(),
4412 true);
4413
4414
4415 if (meth) {
4416 Overridden.insert(meth);
4417 return;
4418 }
4419
4420
4421
4422
4423
4424 Recursive = true;
4425
4426 searchFromContainer(container);
4427 }
4428};
4429}
4430
4434 const auto *attr = overridden->getAttr();
4435 Diag(method->getLocation(), diag::err_objc_override_direct_method);
4436 Diag(attr->getLocation(), diag::note_previous_declaration);
4438 const auto *attr = method->getAttr();
4439 Diag(attr->getLocation(), diag::err_objc_direct_on_override)
4441 Diag(overridden->getLocation(), diag::note_previous_declaration);
4442 }
4443}
4444
4449 if (!ObjCMethod)
4450 return;
4451 auto IsMethodInCurrentClass = [CurrentClass](const ObjCMethodDecl *M) {
4452
4453 return M->getClassInterface()->getCanonicalDecl() ==
4455 };
4456
4457 OverrideSearch overrides(SemaRef, ObjCMethod);
4458
4459
4460
4461
4462
4463 bool hasOverriddenMethodsInBaseOrProtocol = false;
4465 if (!hasOverriddenMethodsInBaseOrProtocol) {
4467 !IsMethodInCurrentClass(overridden) || overridden->isOverriding()) {
4469 hasOverriddenMethodsInBaseOrProtocol = true;
4471
4472
4473
4474
4475
4476
4477
4478 GlobalMethodPool::iterator It =
4482 ObjCMethod->isInstanceMethod()? It->second.first: It->second.second;
4483 unsigned CategCount = List.getBits();
4484 if (CategCount > 0) {
4485
4486
4487 if (CategCount > 1 ||
4489 OverrideSearch overrides(SemaRef, overridden);
4492 !IsMethodInCurrentClass(SuperOverridden)) {
4494 hasOverriddenMethodsInBaseOrProtocol = true;
4495 overridden->setOverriding(true);
4496 break;
4497 }
4498 }
4499 }
4500 }
4501 }
4502 }
4503 }
4504
4505
4508
4509
4510 SemaRef.mergeObjCMethodDecls(ObjCMethod, overridden);
4511
4512 if (ObjCMethod->isImplicit() && overridden->isImplicit())
4513 continue;
4514
4515
4520
4521 if (CurrentClass && overridden->getDeclContext() != CurrentClass &&
4523 !overridden->isImplicit() ) {
4527 PrevE = overridden->param_end();
4528 for (; ParamI != E && PrevI != PrevE; ++ParamI, ++PrevI) {
4529 assert(PrevI != overridden->param_end() && "Param mismatch");
4532
4533
4534 if (!Context.typesAreCompatible(T1, T2)) {
4535 Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super)
4536 << T1 << T2;
4537 Diag(overridden->getLocation(), diag::note_previous_declaration);
4538 break;
4539 }
4540 }
4541 }
4542 }
4543
4544 ObjCMethod->setOverriding(hasOverriddenMethodsInBaseOrProtocol);
4545}
4546
4547
4548
4551 bool usesCSKeyword,
4554 bool prevUsesCSKeyword) {
4555
4556 auto nullability = type->getNullability();
4558
4559
4560 if (nullability.has_value() == prevNullability.has_value()) {
4561
4562 if (!nullability)
4563 return type;
4564
4565
4566 if (*nullability == *prevNullability)
4567 return type;
4568
4569
4570 S.Diag(loc, diag::err_nullability_conflicting)
4573 return type;
4574 }
4575
4576
4577 if (nullability)
4578 return type;
4579
4580
4582}
4583
4584
4585
4586
4590
4591 if (prevMethod->hasAttr() &&
4592 !method->hasAttr()) {
4593
4595 ObjCRequiresSuperAttr::CreateImplicit(S.Context,
4597 }
4598
4599
4609
4610
4611 unsigned numParams = method->param_size();
4612 unsigned numPrevParams = prevMethod->param_size();
4613 for (unsigned i = 0, n = std::min(numParams, numPrevParams); i != n; ++i) {
4616
4617
4624 param->setType(newParamType);
4625 }
4626}
4627
4628
4629
4633 llvm::Triple::x86 &&
4634 "x86-specific check invoked for a different target");
4637 for (const ParmVarDecl *P : Method->parameters()) {
4638 if (P->getType()->isVectorType()) {
4639 Loc = P->getBeginLoc();
4640 T = P->getType();
4641 break;
4642 }
4643 }
4645 if (Method->getReturnType()->isVectorType()) {
4646 Loc = Method->getReturnTypeSourceRange().getBegin();
4647 T = Method->getReturnType();
4648 } else
4649 return;
4650 }
4651
4652
4653
4655 VersionTuple AcceptedInVersion;
4656 if (Triple.getOS() == llvm::Triple::IOS)
4657 AcceptedInVersion = VersionTuple(9);
4658 else if (Triple.isMacOSX())
4659 AcceptedInVersion = VersionTuple(10, 11);
4660 else
4661 return;
4663 AcceptedInVersion)
4664 return;
4665 SemaRef.Diag(Loc, diag::err_objc_method_unsupported_param_ret_type)
4666 << T << (Method->getReturnType()->isVectorType() ? 1
4667 : 0)
4668 << (Triple.isMacOSX() ? "macOS 10.11" : "iOS 9");
4669}
4670
4672 if (!Method->isDirectMethod() && !Method->hasAttr() &&
4673 CD->hasAttr()) {
4674 Method->addAttr(
4675 ObjCDirectAttr::CreateImplicit(S.Context, Method->getLocation()));
4676 }
4677}
4678
4682 auto Sel = Method->getSelector();
4683 bool isInstance = Method->isInstanceMethod();
4684 bool diagnosed = false;
4685
4687 if (diagnosed || IMD->isImplicit())
4688 return;
4689 if (Method->isDirectMethod() || IMD->isDirectMethod()) {
4690 S.Diag(Method->getLocation(), diag::err_objc_direct_duplicate_decl)
4691 << Method->isDirectMethod() << 0 << IMD->isDirectMethod()
4692 << Method->getDeclName();
4693 S.Diag(IMD->getLocation(), diag::note_previous_declaration);
4694 diagnosed = true;
4695 }
4696 };
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711 if (auto *IMD = IDecl->getMethod(Sel, isInstance))
4712 diagClash(IMD);
4714 if (Impl != ImpDecl)
4716 diagClash(IMD);
4717
4719 if (auto *IMD = Cat->getMethod(Sel, isInstance))
4720 diagClash(IMD);
4721 else if (auto CatImpl = Cat->getImplementation())
4722 if (CatImpl != ImpDecl)
4723 if (auto *IMD = Cat->getMethod(Sel, isInstance))
4724 diagClash(IMD);
4725}
4726
4729 int ParamIndex,
4730 bool MethodDefinition) {
4734
4735 if (!ArgInfo.Type) {
4736 ArgType = Context.getObjCIdType();
4737 TSI = nullptr;
4738 } else {
4740 }
4743 SemaRef.forRedeclarationInCurContext());
4744 SemaRef.LookupName(R, S);
4749 (MethodDefinition ? diag::warn_method_param_redefinition
4750 : diag::warn_method_param_declaration))
4751 << ArgInfo.Name;
4752 Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
4753 }
4754 }
4757
4758
4759
4760
4762 Context.getTranslationUnitDecl(), StartLoc, ArgInfo.NameLoc, ArgInfo.Name,
4764 Param->setObjCMethodScopeInfo(ParamIndex);
4765 Param->setObjCDeclQualifier(
4767
4768
4770 SemaRef.AddPragmaAttributes(SemaRef.TUScope, Param);
4771 if (Param->hasAttr()) {
4772 Diag(Param->getLocation(), diag::err_block_on_nonlocal);
4773 Param->setInvalidDecl();
4774 }
4775
4777 SemaRef.IdResolver.AddDecl(Param);
4778 return Param;
4779}
4780
4785
4786
4788 unsigned CNumArgs,
4790 bool isVariadic, bool MethodDefinition) {
4792
4793 if (.CurContext->isObjCContainer()) {
4794 Diag(MethodLoc, diag::err_missing_method_context);
4795 return nullptr;
4796 }
4797
4800
4801 bool HasRelatedResultType = false;
4803 if (ReturnType) {
4804 resultDeclType = SemaRef.GetTypeFromParser(ReturnType, &ReturnTInfo);
4805
4806 if (SemaRef.CheckFunctionReturnType(resultDeclType, MethodLoc))
4807 return nullptr;
4808
4809 QualType bareResultType = resultDeclType;
4810 (void)AttributedType::stripOuterNullability(bareResultType);
4811 HasRelatedResultType = (bareResultType == Context.getObjCInstanceType());
4812 } else {
4813 resultDeclType = Context.getObjCIdType();
4814 Diag(MethodLoc, diag::warn_missing_method_return_type)
4816 }
4817
4819 Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo,
4820 SemaRef.CurContext, MethodType == tok::minus, isVariadic,
4821 false, false,
4822 false, false,
4823 MethodDeclKind == tok::objc_optional
4826 HasRelatedResultType);
4827
4829 for (unsigned I = 0; I < Sel.getNumArgs(); ++I) {
4832 SemaRef.ProcessAPINotes(Param);
4833 Params.push_back(Param);
4834 }
4835
4836 for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
4840 ArgType = Context.getObjCIdType();
4841 else
4842
4843 ArgType = Context.getAdjustedParameterType(ArgType);
4844
4845 Param->setDeclContext(ObjCMethod);
4846 Params.push_back(Param);
4847 }
4848
4849 ObjCMethod->setMethodParams(Context, Params, SelectorLocs);
4852
4853 SemaRef.ProcessDeclAttributeList(SemaRef.TUScope, ObjCMethod, AttrList);
4854 SemaRef.AddPragmaAttributes(SemaRef.TUScope, ObjCMethod);
4855 SemaRef.ProcessAPINotes(ObjCMethod);
4856
4857
4859 if (ObjCImplDecl *ImpDecl = dyn_cast(ClassDecl)) {
4860 if (MethodType == tok::minus) {
4861 PrevMethod = ImpDecl->getInstanceMethod(Sel);
4862 ImpDecl->addInstanceMethod(ObjCMethod);
4863 } else {
4864 PrevMethod = ImpDecl->getClassMethod(Sel);
4865 ImpDecl->addClassMethod(ObjCMethod);
4866 }
4867
4868
4869
4870
4871
4872
4874 if (auto *Setter = PropertyImpl->getSetterMethodDecl())
4875 if (Setter->getSelector() == Sel &&
4876 Setter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) {
4877 assert(Setter->isSynthesizedAccessorStub() && "autosynth stub expected");
4878 PropertyImpl->setSetterMethodDecl(ObjCMethod);
4879 }
4880 if (auto *Getter = PropertyImpl->getGetterMethodDecl())
4881 if (Getter->getSelector() == Sel &&
4882 Getter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) {
4883 assert(Getter->isSynthesizedAccessorStub() && "autosynth stub expected");
4884 PropertyImpl->setGetterMethodDecl(ObjCMethod);
4885 break;
4886 }
4887 }
4888
4889
4890
4891
4892
4893
4894
4898 const auto *attr = CanonicalMD->getAttr();
4900 ObjCDirectAttr::CreateImplicit(Context, attr->getLocation()));
4901 }
4902 }
4903
4904
4905
4907 if (auto *IMD = IDecl->lookupMethod(ObjCMethod->getSelector(),
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927 if (IDecl == IMD->getClassInterface()) {
4928 auto diagContainerMismatch = [&] {
4929 int decl = 0, impl = 0;
4930
4931 if (auto *Cat = dyn_cast(IMD->getDeclContext()))
4932 decl = Cat->IsClassExtension() ? 1 : 2;
4933
4935 impl = 1 + (decl != 0);
4936
4938 diag::err_objc_direct_impl_decl_mismatch)
4939 << decl << impl;
4940 Diag(IMD->getLocation(), diag::note_previous_declaration);
4941 };
4942
4944 const auto *attr = ObjCMethod->getAttr();
4946 diagContainerMismatch();
4947 } else if (!IMD->isDirectMethod()) {
4948 Diag(attr->getLocation(), diag::err_objc_direct_missing_on_decl);
4949 Diag(IMD->getLocation(), diag::note_previous_declaration);
4950 }
4951 } else if (IMD->isDirectMethod()) {
4952 const auto *attr = IMD->getAttr();
4954 diagContainerMismatch();
4955 } else {
4957 ObjCDirectAttr::CreateImplicit(Context, attr->getLocation()));
4958 }
4959 }
4960 }
4961
4962
4965 Diag(ObjCMethod->getLocation(), diag::warn_dealloc_in_category)
4967 }
4968 } else {
4971 }
4972
4973
4974
4975
4976 for (auto *C : IDecl->visible_categories())
4977 for (auto &P : C->protocols())
4978 if (auto *IMD = P->lookupMethod(ObjCMethod->getSelector(),
4980 assert(ObjCMethod->parameters().size() ==
4981 IMD->parameters().size() &&
4982 "Methods have different number of parameters");
4983 auto OI = IMD->param_begin(), OE = IMD->param_end();
4985 for (; OI != OE; ++OI, ++NI)
4987 }
4988 }
4989 } else {
4992
4993 ObjCInterfaceDecl *IDecl = dyn_cast(ClassDecl);
4994 if (!IDecl)
4996
4997
4998
4999 if (IDecl)
5001 }
5002
5004 }
5005
5006 if (PrevMethod) {
5007
5008 Diag(ObjCMethod->getLocation(), diag::err_duplicate_method_decl)
5010 Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
5012 return ObjCMethod;
5013 }
5014
5015
5016
5017
5018 ObjCInterfaceDecl *CurrentClass = dyn_cast(ClassDecl);
5019 if (!CurrentClass) {
5020 if (ObjCCategoryDecl *Cat = dyn_cast(ClassDecl))
5021 CurrentClass = Cat->getClassInterface();
5022 else if (ObjCImplDecl *Impl = dyn_cast(ClassDecl))
5023 CurrentClass = Impl->getClassInterface();
5025 = dyn_cast(ClassDecl))
5026 CurrentClass = CatImpl->getClassInterface();
5027 }
5028
5031
5033
5034 bool ARCError = false;
5037
5038
5041 getLangOpts().ObjCInferRelatedResultType) {
5042 bool InferRelatedResultType = false;
5053 break;
5054
5057 InferRelatedResultType = ObjCMethod->isClassMethod();
5058 break;
5059
5065 break;
5066 }
5067
5068 if (InferRelatedResultType &&
5071 }
5072
5073 if (MethodDefinition &&
5074 Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
5076
5077
5078
5079 if (const auto *attr = ObjCMethod->getAttr()) {
5082 Diag(attr->getLocation(), diag::warn_availability_on_static_initializer)
5083 << 0;
5084 ObjCMethod->dropAttr();
5085 }
5086 }
5087
5088
5090
5091 SemaRef.ActOnDocumentableDecl(ObjCMethod);
5092
5093 return ObjCMethod;
5094}
5095
5097
5098
5100 return false;
5101
5102
5103
5105 SemaRef.getCurLexicalContext()->getRedeclContext()))
5106 return false;
5107
5108 Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
5110
5111 return true;
5112}
5113
5114
5115
5120
5123 Diag(DeclStart, diag::err_undef_interface) << ClassName;
5124 return;
5125 }
5127 Diag(DeclStart, diag::err_atdef_nonfragile_interface);
5128 return;
5129 }
5130
5131
5133 Context.DeepCollectObjCIvars(Class, true, Ivars);
5134
5135 for (unsigned i = 0; i < Ivars.size(); i++) {
5139 ID->getLocation(),
5140 ID->getLocation(),
5141 ID->getIdentifier(), ID->getType(),
5142 ID->getBitWidth());
5143 Decls.push_back(FD);
5144 }
5145
5146
5148 D != Decls.end(); ++D) {
5151 SemaRef.PushOnScopeChains(FD, S);
5153 Record->addDecl(FD);
5154 }
5155}
5156
5157
5164
5165
5166
5167
5169 Diag(IdLoc, diag::err_arg_with_address_space);
5171 }
5172
5173
5174
5176
5177 } else if (T->isDependentType()) {
5178
5179 } else if (T->isObjCQualifiedIdType()) {
5181 Diag(IdLoc, diag::err_illegal_qualifiers_on_catch_parm);
5182 } else if (T->isObjCIdType()) {
5183
5184 } else if (->isObjCObjectPointerType()) {
5186 Diag(IdLoc, diag::err_catch_param_not_objc_type);
5189 Diag(IdLoc, diag::err_catch_param_not_objc_type);
5190 }
5191
5194 New->setExceptionVariable(true);
5195
5196
5199
5201 New->setInvalidDecl();
5202 return New;
5203}
5204
5207
5208
5209
5216 }
5222 diag::err_invalid_thread)
5225
5227
5228
5229
5231 SemaRef.CheckExtraCXXDefaultArguments(D);
5232
5235
5241
5242
5246 New->setInvalidDecl();
5247 }
5248
5249
5253
5254 SemaRef.ProcessDeclAttributes(S, New, D);
5255
5256 if (New->hasAttr())
5257 Diag(New->getLocation(), diag::err_block_on_nonlocal);
5258 return New;
5259}
5260
5261
5262
5268 QualType QT = Context.getBaseElementType(Iv->getType());
5270 Ivars.push_back(Iv);
5271 }
5272}
5273
5276
5277 if (SemaRef.ExternalSource) {
5279 SemaRef.ExternalSource->ReadReferencedSelectors(Sels);
5280 for (unsigned I = 0, N = Sels.size(); I != N; ++I)
5282 }
5283
5284
5285
5286
5288 !Context.AnyObjCImplementation())
5289 return;
5291 Selector Sel = SelectorAndLocation.first;
5294 Diag(Loc, diag::warn_unimplemented_selector) << Sel;
5295 }
5296}
5297
5301 if (Method->isClassMethod())
5302 return nullptr;
5304 if (!IDecl)
5305 return nullptr;
5307 false,
5308 false);
5309 if ( ||
->isPropertyAccessor())
5310 return nullptr;
5311 if ((PDecl = Method->findPropertyDecl()))
5313
5314
5315
5316 IV = const_cast<ObjCInterfaceDecl *>(IDecl)->lookupInstanceVariable(
5317 IV->getIdentifier());
5318 return IV;
5319 }
5320 return nullptr;
5321}
5322
5323namespace {
5324
5325
5327public:
5331 bool AccessedIvar;
5332 bool InvokedSelfMethod;
5333
5337 InvokedSelfMethod(false) {
5338 assert(IvarD);
5339 }
5340
5341 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) override {
5342 if (E->getDecl() == IvarD) {
5343 AccessedIvar = true;
5344 return false;
5345 }
5346 return true;
5347 }
5348
5349 bool VisitObjCMessageExpr(ObjCMessageExpr *E) override {
5352 InvokedSelfMethod = true;
5353 }
5354 return true;
5355 }
5356};
5357}
5358
5362 return;
5363
5365 unsigned DIAG = diag::warn_unused_property_backing_ivar;
5368 continue;
5369
5372 if (!IV)
5373 continue;
5374
5375 if (CurMethod->isSynthesizedAccessorStub())
5376 continue;
5377
5378 UnusedBackingIvarChecker Checker(SemaRef, CurMethod, IV);
5379 Checker.TraverseStmt(CurMethod->getBody());
5380 if (Checker.AccessedIvar)
5381 continue;
5382
5383
5384
5385
5386
5387 if (!IV->isReferenced() || !Checker.InvokedSelfMethod) {
5389 Diag(PDecl->getLocation(), diag::note_property_declare);
5390 }
5391 }
5392}
5393
5397
5400 return T;
5401
5403
5404
5405
5406
5407 if (T->isArrayType()) {
5408 if (.isConstQualified()) {
5409 if (SemaRef.DelayedDiagnostics.shouldDelayDiagnostics())
5410 SemaRef.DelayedDiagnostics.add(
5412 NameLoc, diag::err_arc_array_param_no_ownership, T, false));
5413 else
5414 Diag(NameLoc, diag::err_arc_array_param_no_ownership)
5416 }
5418 } else {
5419 Lifetime = T->getObjCARCImplicitLifetime();
5420 }
5421 T = Context.getLifetimeQualifiedType(T, Lifetime);
5422
5423 return T;
5424}
5425
5428 bool DoTypoCorrection) {
5429
5430
5433
5434 if (!IDecl && DoTypoCorrection) {
5435
5436
5441 SemaRef.diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id);
5444 }
5445 }
5446 ObjCInterfaceDecl *Def = dyn_cast_or_null(IDecl);
5447
5450 return Def;
5451}
5452
5458
5459 unsigned kind = -1U;
5460 if (VarDecl *var = dyn_cast(decl)) {
5461 if (var->hasAttr())
5462 kind = 0;
5463 else if (!var->hasLocalStorage())
5464 kind = 1;
5466 kind = 3;
5468 kind = 2;
5469 }
5470
5471 if (kind != -1U) {
5472 Diag(decl->getLocation(), diag::err_arc_autoreleasing_var) << kind;
5473 }
5475
5476 if (->isObjCLifetimeType())
5477 return false;
5478
5479 lifetime = type->getObjCARCImplicitLifetime();
5480 type = Context.getLifetimeQualifiedType(type, lifetime);
5482 }
5483
5484 if (VarDecl *var = dyn_cast(decl)) {
5485
5487 var->getTLSKind()) {
5488 Diag(var->getLocation(), diag::err_arc_thread_ownership)
5489 << var->getType();
5490 return true;
5491 }
5492 }
5493
5494 return false;
5495}
5496
5498 return (dyn_cast_or_null(SemaRef.CurContext));
5499}
5500
5503 return;
5508 if (ivars.empty())
5509 return;
5511 for (unsigned i = 0; i < ivars.size(); i++) {
5513 if (Field->isInvalidDecl())
5514 continue;
5515
5520
5523 InitSeq.Perform(SemaRef, InitEntity, InitKind, {});
5524 MemberInit = SemaRef.MaybeCreateExprWithCleanups(MemberInit);
5525
5526
5527 if (!MemberInit.get() || MemberInit.isInvalid())
5528 continue;
5529
5530 Member = new (Context)
5533 AllToInit.push_back(Member);
5534
5535
5536 if (auto *RD = Context.getBaseElementType(Field->getType())
5537 ->getAsCXXRecordDecl()) {
5539 SemaRef.MarkFunctionReferenced(Field->getLocation(), Destructor);
5540 SemaRef.CheckDestructorAccess(
5542 PDiag(diag::err_access_dtor_ivar)
5543 << Context.getBaseElementType(Field->getType()));
5544 }
5545 }
5546 }
5548 AllToInit.size());
5549 }
5550}
5551
5552
5553
5556 switch (ivarVisibility) {
5557 default:
5558 llvm_unreachable("Unknown visitibility kind");
5559 case tok::objc_private:
5561 case tok::objc_public:
5563 case tok::objc_protected:
5565 case tok::objc_package:
5567 }
5568}
5569
5570
5571
5574
5577 if (II)
5579
5580
5581
5582
5586 if (Context.getLangOpts().PointerAuthObjcInterfaceSel &&
5587 .getPointerAuth()) {
5588 if (Context.isObjCSelType(T.getUnqualifiedType())) {
5589 if (auto PAQ = Context.getObjCMemberSelTypePtrAuth())
5590 T = Context.getPointerAuthType(T, PAQ);
5591 }
5592 }
5593
5594 if (BitWidth) {
5595
5596 BitWidth =
5597 SemaRef.VerifyBitField(Loc, II, T, false, BitWidth)
5598 .get();
5599 if (!BitWidth)
5601 } else {
5602
5603
5604
5605 }
5606 if (T->isReferenceType()) {
5607 Diag(Loc, diag::err_ivar_reference_type);
5609 }
5610
5611
5612 else if (T->isVariablyModifiedType()) {
5613 if (.tryToFixVariablyModifiedVarType(
5614 TInfo, T, Loc, diag::err_typecheck_ivar_variable_size))
5616 }
5617
5618
5622
5625 if (!EnclosingDecl || EnclosingDecl->isInvalidDecl())
5626 return nullptr;
5629 dyn_cast(EnclosingDecl)) {
5631
5632
5633 EnclosingContext = IMPDecl->getClassInterface();
5634 assert(EnclosingContext && "Implementation has no class interface!");
5635 } else
5636 EnclosingContext = EnclosingDecl;
5637 } else {
5638 if (ObjCCategoryDecl *CDecl = dyn_cast(EnclosingDecl)) {
5640 Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension();
5641 return nullptr;
5642 }
5643 }
5644 EnclosingContext = EnclosingDecl;
5645 }
5646
5647
5650 II, T, TInfo, ac, BitWidth);
5651
5652 if (T->containsErrors())
5654
5655 if (II) {
5659 if (PrevDecl && SemaRef.isDeclInScope(PrevDecl, EnclosingContext, S) &&
5661 Diag(Loc, diag::err_duplicate_member) << II;
5662 Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
5664 }
5665 }
5666
5667
5668 SemaRef.ProcessDeclAttributes(S, NewID, D);
5669
5672
5673
5676
5679
5680 if (II) {
5681
5682
5684 SemaRef.IdResolver.AddDecl(NewID);
5685 }
5686
5689 Diag(Loc, diag::warn_ivars_in_interface);
5690
5691 return NewID;
5692}
Defines the clang::ASTContext interface.
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, 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.
FormatToken * Previous
The previous token in the unwrapped line.
llvm::MachO::Record Record
@ ForVisibleRedeclaration
The lookup results will be used for redeclaration of a name, if an entity by that name already exists...
static bool IsVariableSizedType(QualType T)
Definition SemaDeclObjC.cpp:3846
static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD)
Definition SemaDeclObjC.cpp:3853
static bool HasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param)
HasExplicitOwnershipAttr - returns true when pointer to ObjC pointer has explicit ownership attribute...
Definition SemaDeclObjC.cpp:350
static void checkObjCDirectMethodClashes(Sema &S, ObjCInterfaceDecl *IDecl, ObjCMethodDecl *Method, ObjCImplDecl *ImpDecl=nullptr)
Definition SemaDeclObjC.cpp:4679
static bool CheckMethodOverrideParam(Sema &S, ObjCMethodDecl *MethodImpl, ObjCMethodDecl *MethodDecl, ParmVarDecl *ImplVar, ParmVarDecl *IfaceVar, bool IsProtocolMethodDecl, bool IsOverridingMode, bool Warn)
Definition SemaDeclObjC.cpp:2442
static SourceRange getTypeRange(TypeSourceInfo *TSI)
Definition SemaDeclObjC.cpp:2351
std::unique_ptr< ProtocolNameSet > LazyProtocolNameSet
Definition SemaDeclObjC.cpp:2693
static bool CheckMethodOverrideReturn(Sema &S, ObjCMethodDecl *MethodImpl, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl, bool IsOverridingMode, bool Warn)
Definition SemaDeclObjC.cpp:2362
static void DiagnoseCategoryDirectMembersProtocolConformance(Sema &S, ObjCProtocolDecl *PDecl, ObjCCategoryDecl *CDecl)
Definition SemaDeclObjC.cpp:3944
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...
Definition SemaDeclObjC.cpp:829
static void HelperSelectorsForTypoCorrection(SmallVectorImpl< const ObjCMethodDecl * > &BestMethod, StringRef Typo, const ObjCMethodDecl *Method)
Definition SemaDeclObjC.cpp:3678
static bool objcModifiersConflict(Decl::ObjCDeclQualifier x, Decl::ObjCDeclQualifier y)
Determine whether two set of Objective-C declaration qualifiers conflict.
Definition SemaDeclObjC.cpp:2356
static bool shouldWarnUndefinedMethod(const ObjCMethodDecl *M)
Definition SemaDeclObjC.cpp:2246
static bool FilterMethodsByTypeBound(ObjCMethodDecl *Method, const ObjCObjectType *TypeBound)
Return true if the given method is wthin the type bound.
Definition SemaDeclObjC.cpp:3484
static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, SourceLocation ImplLoc)
Definition SemaDeclObjC.cpp:288
static void findProtocolsWithExplicitImpls(const ObjCProtocolDecl *PDecl, ProtocolNameSet &PNS)
Definition SemaDeclObjC.cpp:2695
static bool matchTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strategy, QualType leftQT, QualType rightQT)
Definition SemaDeclObjC.cpp:3170
static void DiagnoseRetainableFlexibleArrayMember(Sema &S, ObjCInterfaceDecl *ID)
Diagnose attempts to use flexible array member with retainable object type.
Definition SemaDeclObjC.cpp:3807
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...
Definition SemaDeclObjC.cpp:4587
static bool HelperIsMethodInObjCType(Sema &S, Selector Sel, QualType ObjectType)
Definition SemaDeclObjC.cpp:3700
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...
Definition SemaDeclObjC.cpp:4247
static ObjCIvarDecl::AccessControl TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility)
TranslateIvarVisibility - Translate visibility from a token ID to an AST enum value.
Definition SemaDeclObjC.cpp:5555
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,...
Definition SemaDeclObjC.cpp:2719
static void WarnUndefinedMethod(Sema &S, ObjCImplDecl *Impl, ObjCMethodDecl *method, bool &IncompleteImpl, unsigned DiagID, NamedDecl *NeededFor=nullptr)
Definition SemaDeclObjC.cpp:2251
static bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl, ObjCProtocolDecl *&UndefinedProtocol)
Definition SemaDeclObjC.cpp:1293
static bool isObjCTypeSubstitutable(ASTContext &Context, const ObjCObjectPointerType *A, const ObjCObjectPointerType *B, bool rejectId)
Determines if type B can be substituted for type A.
Definition SemaDeclObjC.cpp:2319
llvm::DenseSet< IdentifierInfo * > ProtocolNameSet
FIXME: Type hierarchies in Objective-C can be deep.
Definition SemaDeclObjC.cpp:2692
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...
Definition SemaDeclObjC.cpp:4549
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...
Definition SemaDeclObjC.cpp:118
static bool isAcceptableMethodMismatch(ObjCMethodDecl *chosen, ObjCMethodDecl *other)
Determines if this is an "acceptable" loose mismatch in the global method pool.
Definition SemaDeclObjC.cpp:3466
static void mergeObjCDirectMembers(Sema &S, Decl *CD, ObjCMethodDecl *Method)
Definition SemaDeclObjC.cpp:4671
static void DiagnoseWeakIvars(Sema &S, ObjCImplementationDecl *ID)
Diagnose attempts to define ARC-__weak ivars when __weak is disabled.
Definition SemaDeclObjC.cpp:3790
static void checkObjCMethodX86VectorTypes(Sema &SemaRef, const ObjCMethodDecl *Method)
Verify that the method parameters/return value have types that are supported by the x86 target.
Definition SemaDeclObjC.cpp:4630
static bool checkMethodFamilyMismatch(Sema &S, ObjCMethodDecl *impl, ObjCMethodDecl *decl)
In ARC, check whether the conventional meanings of the two methods match.
Definition SemaDeclObjC.cpp:2525
static bool isMethodContextSameForKindofLookup(ObjCMethodDecl *Method, ObjCMethodDecl *MethodInList)
Definition SemaDeclObjC.cpp:3308
static bool tryMatchRecordTypes(ASTContext &Context, SemaObjC::MethodMatchStrategy strategy, const Type *left, const Type *right)
Definition SemaDeclObjC.cpp:3229
static Decl::ObjCDeclQualifier CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal)
CvtQTToAstBitMask - utility routine to produce an AST bitmask for objective-c's type qualifier from t...
Definition SemaDeclObjC.cpp:4239
static void diagnoseUseOfProtocols(Sema &TheSema, ObjCContainerDecl *CD, ObjCProtocolDecl *const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs)
Definition SemaDeclObjC.cpp:536
This file declares semantic analysis for Objective-C.
Defines the SourceManager interface.
__DEVICE__ long long abs(long long __n)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig, ObjCTypeParamDecl *New) const
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType, const Attr *attr=nullptr) const
const LangOptions & getLangOpts() const
SelectorTable & Selectors
const clang::PrintingPolicy & getPrintingPolicy() const
void ResetObjCLayout(const ObjCInterfaceDecl *D)
CanQualType getCanonicalTypeDeclType(const TypeDecl *TD) const
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
const TargetInfo & getTargetInfo() const
bool hasSameNullabilityTypeQualifier(QualType SubT, QualType SuperT, bool IsParam) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
void addObjCSubClass(const ObjCInterfaceDecl *D, const ObjCInterfaceDecl *SubClass)
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
Type source information for an attributed type.
Represents a C++ base or member initializer.
Represents a C++ destructor within a class.
SourceRange getRange() const
bool isSet() const
Deprecated.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
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.
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".
bool isModulePrivateSpecified() const
static const TST TST_typename
ThreadStorageClassSpecifier TSCS
void ClearStorageClassSpecs()
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
TSCS getThreadStorageClassSpec() const
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 getThreadStorageClassSpecLoc() const
SourceLocation getInlineSpecLoc() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
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)
TypeSourceInfo * getTypeSourceInfo() const
Information about one declarator, including the parsed type information and the identifier.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
void setInvalidType(bool Val=true)
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
DeclSpec & getMutableDeclSpec()
getMutableDeclSpec - Return a non-const version of the DeclSpec.
const IdentifierInfo * getIdentifier() const
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
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.
A simple pair of identifier info and location.
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
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
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
llvm::iterator_range< specific_decl_iterator< ObjCIvarDecl > > ivar_range
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...
specific_decl_iterator< ObjCIvarDecl > ivar_iterator
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
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)
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
@ Instance
The receiver is an object instance.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
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
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
param_const_iterator param_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 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 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
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.
ObjCDeclQualifier getObjCDeclQualifier() const
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 getCanonicalType() const
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.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isDeclScope(const Decl *D) const
isDeclScope - Return true if this is the scope that the specified decl is declared in.
bool hasUnrecoverableErrorOccurred() const
Determine whether any unrecoverable errors have occurred within this scope.
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.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
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...
Definition SemaDeclObjC.cpp:5572
void ActOnStartOfObjCMethodDef(Scope *S, Decl *D)
ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible and user declared,...
Definition SemaDeclObjC.cpp:368
void ActOnSuperClassOfClassInterface(Scope *S, SourceLocation AtInterfaceLoc, ObjCInterfaceDecl *IDecl, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, ArrayRef< ParsedType > SuperTypeArgs, SourceRange SuperTypeArgsRange)
Definition SemaDeclObjC.cpp:552
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.
Definition SemaDeclObjC.cpp:5158
void DiagnoseUnusedBackingIvarInAccessor(Scope *S, const ObjCImplementationDecl *ImplD)
DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which backs the property is n...
Definition SemaDeclObjC.cpp:5359
void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation)
SetIvarInitializers - This routine builds initialization ASTs for the Objective-C implementation whos...
Definition SemaDeclObjC.cpp:5501
void WarnExactTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl)
WarnExactTypedMethods - This routine issues a warning if method implementation declaration matches ex...
Definition SemaDeclObjC.cpp:2644
const ObjCMethodDecl * SelectorsForTypoCorrection(Selector Sel, QualType ObjectType=QualType())
Definition SemaDeclObjC.cpp:3712
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.
Definition SemaDeclObjC.cpp:3328
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)
Definition SemaDeclObjC.cpp:975
void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl)
Diagnose any null-resettable synthesized setters.
void updateOutOfDateSelector(Selector Sel)
Definition SemaDeclObjC.cpp:3438
llvm::SmallPtrSet< Selector, 8 > SelectorSet
void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList)
Definition SemaDeclObjC.cpp:805
ObjCImplementationDecl * ActOnStartClassImplementation(SourceLocation AtClassImplLoc, const IdentifierInfo *ClassName, SourceLocation ClassLoc, const IdentifierInfo *SuperClassname, SourceLocation SuperClassLoc, const ParsedAttributesView &AttrList)
Definition SemaDeclObjC.cpp:1985
bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl< ObjCMethodDecl * > &Methods)
Definition SemaDeclObjC.cpp:3556
Decl * ActOnObjCExceptionDecl(Scope *S, Declarator &D)
Definition SemaDeclObjC.cpp:5205
bool CheckObjCDeclScope(Decl *D)
Checks that the Objective-C declaration is declared in the global scope.
Definition SemaDeclObjC.cpp:5096
DeclResult actOnObjCTypeParam(Scope *S, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, IdentifierInfo *paramName, SourceLocation paramLoc, SourceLocation colonLoc, ParsedType typeBound)
Definition SemaDeclObjC.cpp:667
ObjCIvarDecl * GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, const ObjCPropertyDecl *&PDecl) const
GetIvarBackingPropertyAccessor - If method is a property setter/getter and it property has a backing ...
Definition SemaDeclObjC.cpp:5299
bool CheckARCMethodDecl(ObjCMethodDecl *method)
Check a method declaration for compatibility with the Objective-C ARC conventions.
Definition SemaDeclObjC.cpp:230
ObjCContainerKind getObjCContainerKind() const
Definition SemaDeclObjC.cpp:3826
ObjCInterfaceDecl * getObjCInterfaceDecl(const IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection=false)
Look for an Objective-C class in the translation unit.
Definition SemaDeclObjC.cpp:5426
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)
Definition SemaDeclObjC.cpp:4727
DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, ArrayRef< Decl * > Decls)
Definition SemaDeclObjC.cpp:2121
ObjCContainerDecl * getObjCDeclContext() const
Definition SemaDeclObjC.cpp:5497
void WarnConflictingTypedMethods(ObjCMethodDecl *Method, ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl)
Definition SemaDeclObjC.cpp:2595
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod, MethodMatchStrategy strategy=MMS_strict)
MatchTwoMethodDeclarations - Checks if two methods' type match and returns true, or false,...
Definition SemaDeclObjC.cpp:3268
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...
Definition SemaDeclObjC.cpp:2843
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...
Definition SemaDeclObjC.cpp:1143
void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID)
DiagnoseDuplicateIvars - Check for duplicate ivars in the entire class at the start of @implementatio...
Definition SemaDeclObjC.cpp:3773
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.
Definition SemaDeclObjC.cpp:44
void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, ObjCMethodDecl *Overridden, bool IsProtocolMethodDecl)
Definition SemaDeclObjC.cpp:2620
ObjCTypeParamList * actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, ArrayRef< Decl * > typeParams, SourceLocation rAngleLoc)
Definition SemaDeclObjC.cpp:770
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)
Definition SemaDeclObjC.cpp:1818
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...
Definition SemaDeclObjC.cpp:1428
bool CheckForwardProtocolDeclarationForCircularDependency(IdentifierInfo *PName, SourceLocation &PLoc, SourceLocation PrevLoc, const ObjCList< ObjCProtocolDecl > &PList)
Definition SemaDeclObjC.cpp:1192
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 FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, ArrayRef< IdentifierLoc > ProtocolId, SmallVectorImpl< Decl * > &Protocols)
FindProtocolDeclaration - This routine looks up protocols and issues an error if they are not declare...
Definition SemaDeclObjC.cpp:1312
void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, ObjCInterfaceDecl *ID)
DiagnoseClassExtensionDupMethods - Check for duplicate declaration of a class method in its extension...
Definition SemaDeclObjC.cpp:1766
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...
Definition SemaDeclObjC.cpp:1917
bool inferObjCARCLifetime(ValueDecl *decl)
Definition SemaDeclObjC.cpp:5453
void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, const ObjCMethodDecl *Overridden)
Check whether the given new method is a valid override of the given overridden method,...
Definition SemaDeclObjC.cpp:140
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)
Definition SemaDeclObjC.cpp:4781
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...
Definition SemaDeclObjC.cpp:1116
void DiagnoseMissingDesignatedInitOverrides(const ObjCImplementationDecl *ImplD, const ObjCInterfaceDecl *IFD)
void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, SmallVectorImpl< ObjCIvarDecl * > &Ivars)
CollectIvarsToConstructOrDestruct - Collect those ivars which require initialization.
Definition SemaDeclObjC.cpp:5263
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)
Definition SemaDeclObjC.cpp:5394
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)
Definition SemaDeclObjC.cpp:1217
ResultTypeCompatibilityKind
Describes the compatibility of a result type with its method.
void DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl< ObjCMethodDecl * > &Methods, Selector Sel, SourceRange R, bool receiverIdOrClass)
Definition SemaDeclObjC.cpp:3600
DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, IdentifierInfo **IdentList, SourceLocation *IdentLocs, ArrayRef< ObjCTypeParamList * > TypeParamLists, unsigned NumElts)
Definition SemaDeclObjC.cpp:3069
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, ArrayRef< IdentifierLoc > IdentList, const ParsedAttributesView &attrList)
ActOnForwardProtocolDeclaration - Handle @protocol foo;.
Definition SemaDeclObjC.cpp:1790
void ReadMethodPool(Selector Sel)
Read the contents of the method pool for a given selector from external storage.
Definition SemaDeclObjC.cpp:3433
void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, const IdentifierInfo *ClassName, SmallVectorImpl< Decl * > &Decls)
Called whenever @defs(ClassName) is encountered in the source.
Definition SemaDeclObjC.cpp:5116
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)
Definition SemaDeclObjC.cpp:1418
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.
Definition SemaDeclObjC.cpp:3518
void CheckObjCMethodDirectOverrides(ObjCMethodDecl *method, ObjCMethodDecl *overridden)
Definition SemaDeclObjC.cpp:4431
void DiagnoseUseOfUnimplementedSelectors()
Definition SemaDeclObjC.cpp:5274
Decl * ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef< Decl * > allMethods={}, ArrayRef< DeclGroupPtrTy > allTUVars={})
Definition SemaDeclObjC.cpp:3984
void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP)
CheckCategoryVsClassMethodMatches - Checks that methods implemented in category matches with those im...
Definition SemaDeclObjC.cpp:2952
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...
Definition SemaDeclObjC.cpp:2991
void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, ObjCInterfaceDecl *CurrentClass, ResultTypeCompatibilityKind RTC)
Definition SemaDeclObjC.cpp:4445
void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, ObjCIvarDecl **Fields, unsigned nIvars, SourceLocation Loc)
CheckImplementationIvars - This routine checks if the instance variables listed in the implelementati...
Definition SemaDeclObjC.cpp:2146
ObjCMethodDecl * LookupImplementedMethodInGlobalPool(Selector Sel)
LookupImplementedMethodInGlobalPool - Returns the method which has an implementation.
Definition SemaDeclObjC.cpp:3655
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.
Definition SemaDeclObjC.cpp:335
@ 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)
Sema - This implements semantic analysis and AST building for C.
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.
ASTContext & getASTContext() const
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() 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.
IntrusiveRefCntPtr< ExternalSemaSource > ExternalSource
Source of additional semantic information.
DiagnosticsEngine & Diags
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
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
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isScalarType() const
bool isObjCQualifiedIdType() const
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 isObjCIdType() const
bool isObjCObjectType() const
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
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 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)
static DelayedDiagnostic makeForbiddenType(SourceLocation loc, unsigned diagnostic, QualType type, unsigned argument)
Defines the clang::TargetInfo interface.
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.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_None
No particular method family.
std::pair< NullabilityKind, bool > DiagNullabilityKind
A nullability kind paired with a bit indicating whether it used a context-sensitive keyword.
@ Property
The type of a property.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
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.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
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...
U cast(CodeGen::Address addr)
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ None
No keyword precedes the qualified type name.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
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)
void setHasMoreThanOneDecl(bool B)
bool hasMoreThanOneDecl() const
ObjCMethodList * getNext() const
ParsedAttributesView ArgAttrs
ArgAttrs - Attribute list for this argument.