clang: lib/Sema/SemaExprObjC.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
30#include "llvm/Support/ConvertUTF.h"
31#include
32
33using namespace clang;
34using namespace sema;
36
40
41
42
43
45
46
47 if (Strings.size() != 1) {
48
51
52 for (Expr *E : Strings) {
54
55
57 Diag(S->getBeginLoc(), diag::err_cfstring_literal_not_string_constant)
59 return true;
60 }
61
62
64
65
67 }
68
69
70
72 assert(CAT && "String literal not of constant array type!");
73 QualType StrTy = Context.getConstantArrayType(
74 CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), nullptr,
77 false, StrTy, StrLocs);
78 }
79
81}
82
86
88 return true;
89
90
91
92
93
94 QualType Ty = Context.getObjCConstantStringInterface();
96 Ty = Context.getObjCObjectPointerType(Ty);
97 } else if (getLangOpts().NoConstantCFStrings) {
99 std::string StringClass(getLangOpts().ObjCConstantStringClass);
100
101 if (StringClass.empty())
102 NSIdent = &Context.Idents.get("NSConstantString");
103 else
104 NSIdent = &Context.Idents.get(StringClass);
105
108 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null(IF)) {
109 Context.setObjCConstantStringInterface(StrIF);
110 Ty = Context.getObjCConstantStringInterface();
111 Ty = Context.getObjCObjectPointerType(Ty);
112 } else {
113
114
115 Diag(S->getBeginLoc(), diag::err_no_nsconstant_string_class)
117 Ty = Context.getObjCIdType();
118 }
119 } else {
123 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null(IF)) {
124 Context.setObjCConstantStringInterface(StrIF);
125 Ty = Context.getObjCConstantStringInterface();
126 Ty = Context.getObjCObjectPointerType(Ty);
127 } else {
128
129
130
131
132 Ty = Context.getObjCNSStringType();
136 Context.getTranslationUnitDecl(),
139 Ty = Context.getObjCInterfaceType(NSStringIDecl);
140 Context.setObjCNSStringType(Ty);
141 }
142 Ty = Context.getObjCObjectPointerType(Ty);
143 }
144 }
145
147}
148
149
150
154 if (!Method) {
155
156 S.Diag(Loc, diag::err_undeclared_boxing_method) << Sel << Class->getName();
157 return false;
158 }
159
160
161 QualType ReturnType = Method->getReturnType();
163 S.Diag(Loc, diag::err_objc_literal_method_sig)
164 << Sel;
165 S.Diag(Method->getLocation(), diag::note_objc_literal_method_return)
166 << ReturnType;
167 return false;
168 }
169
170 return true;
171}
172
173
176 switch (LiteralKind) {
187
188
189
192 break;
193 }
194 llvm_unreachable("LiteralKind can't be converted into a ClassKind");
195}
196
197
198
199
200static bool
207 S.Diag(Loc, diag::err_undeclared_objc_literal_class)
208 << II->getName() << LiteralKind;
209 return false;
210 } else if (->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {
211 S.Diag(Loc, diag::err_undeclared_objc_literal_class)
212 << Decl->getName() << LiteralKind;
214 return false;
215 }
216
217 return true;
218}
219
220
221
222
231 if (!ID && S.getLangOpts().DebuggerObjCLiteral) {
236 }
237
239 ID = nullptr;
240 }
241
242 return ID;
243}
244
245
246
249 bool isLiteral = false,
251 std::optionalNSAPI::NSNumberLiteralMethodKind Kind =
252 S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
253
254 if (!Kind) {
255 if (isLiteral) {
256 S.Diag(Loc, diag::err_invalid_nsnumber_type)
257 << NumberType << R;
258 }
259 return nullptr;
260 }
261
262
265
267 false);
268
270
271
272
277 return nullptr;
278 }
279 }
280
282
285 }
286
287
289 if (!Method && S.getLangOpts().DebuggerObjCLiteral) {
290
295 false, false,
296 false,
297 false,
298 true,
300 false);
304 NumberType, nullptr, SC_None, nullptr);
305 Method->setMethodParams(S.SemaRef.Context, value, {});
306 }
307
309 return nullptr;
310
311
312
313
315 return Method;
316}
317
318
319
321 Expr *Number) {
323
325 if (CharacterLiteral *Char = dyn_cast(Number)) {
326
327
328 switch (Char->getKind()) {
331 NumberType = Context.CharTy;
332 break;
333
335 NumberType = Context.getWideCharType();
336 break;
337
339 NumberType = Context.Char16Ty;
340 break;
341
343 NumberType = Context.Char32Ty;
344 break;
345 }
346 }
347
348
349
352 true, NR);
355
356
359 ParamDecl);
364 Number = ConvertedNumber.get();
365
366
369}
370
376 Inner = SemaRef.ActOnCXXBoolLiteral(ValueLoc,
377 Value ? tok::kw_true : tok::kw_false);
378 } else {
379
380
381 Inner = SemaRef.ActOnIntegerConstant(ValueLoc, Value ? 1 : 0);
382 Inner = SemaRef.ImpCastExprToType(Inner.get(), Context.BoolTy,
383 CK_IntegralToBoolean);
384 }
385
387}
388
389
390
393 bool ArrayLiteral = false) {
394
396 return Element;
397
399 if (Result.isInvalid())
401 Element = Result.get();
402
403
404
408 false);
412 if (.Failed())
413 return Seq.Perform(S, Entity, Kind, Element);
414 }
415
416 Expr *OrigElement = Element;
417
418
420 if (Result.isInvalid())
422 Element = Result.get();
423
424
427 bool Recovered = false;
428
429
435 if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind(
436 OrigElement->getType())) {
440 : 3;
441
442 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
445
447 OrigElement);
448 if (Result.isInvalid())
450
451 Element = Result.get();
452 Recovered = true;
453 }
454 }
455
456 else if (StringLiteral *String = dyn_cast(OrigElement)) {
457 if (String->isOrdinary()) {
458 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
461
462 Result =
464 if (Result.isInvalid())
466
467 Element = Result.get();
468 Recovered = true;
469 }
470 }
471
472 if (!Recovered) {
473 S.Diag(Element->getBeginLoc(), diag::err_invalid_collection_element)
476 }
477 }
478 if (ArrayLiteral)
480 dyn_cast(OrigElement)) {
482 unsigned numConcat = SL->getNumConcatenated();
483 if (numConcat > 1) {
484
485 bool hasMacro = false;
486 for (unsigned i = 0; i < numConcat ; ++i)
487 if (SL->getStrTokenLoc(i).isMacroID()) {
488 hasMacro = true;
489 break;
490 }
491 if (!hasMacro)
493 diag::warn_concatenated_nsarray_literal)
495 }
496 }
497 }
498
499
500
503 false),
505}
506
511 new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr, SR);
512 return BoxedExpr;
513 }
516
517 ExprResult RValue = SemaRef.DefaultFunctionArrayLvalueConversion(ValueExpr);
520 }
522 ValueExpr = RValue.get();
526 if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {
527
533 }
535 NSStringPointer = Context.getObjCObjectPointerType(NSStringObject);
536 }
537
538
539
540 if (auto *CE = dyn_cast(ValueExpr))
541 if (CE->getCastKind() == CK_ArrayToPointerDecay)
542 if (auto *SL =
543 dyn_cast(CE->getSubExpr()->IgnoreParens())) {
544 assert((SL->isOrdinary() || SL->isUTF8()) &&
545 "unexpected character encoding");
546 StringRef Str = SL->getString();
547 const llvm::UTF8 *StrBegin = Str.bytes_begin();
548 const llvm::UTF8 *StrEnd = Str.bytes_end();
549
550 if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {
553 return new (Context) ObjCBoxedExpr(CE, BoxedType, nullptr, SR);
554 }
555
556 Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)
558 }
559
561 IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");
562 Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);
563
564
565 BoxingMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String);
566 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
567
572 false, false,
573 false,
574 false,
575 true,
577 false);
582 &Context.Idents.get("value"),
583 Context.getPointerType(ConstCharType),
584 nullptr,
587 BoxingMethod = M;
588 }
589
591 stringWithUTF8String, BoxingMethod))
593
595 }
596
599
600 std::optional Nullability =
602 if (Nullability)
603 BoxedType =
604 Context.getAttributedType(*Nullability, BoxedType, BoxedType);
605 }
606 } else if (ValueType->isBuiltinType()) {
607
608
609
610
611
612
614 dyn_cast(ValueExpr->IgnoreParens())) {
615
616
617 switch (Char->getKind()) {
620 ValueType = Context.CharTy;
621 break;
622
624 ValueType = Context.getWideCharType();
625 break;
626
628 ValueType = Context.Char16Ty;
629 break;
630
632 ValueType = Context.Char32Ty;
633 break;
634 }
635 }
636
637
638
641 } else if (const auto *ED = ValueType->getAsEnumDecl()) {
642 if (!ED->isComplete()) {
643 Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)
646 }
647
650 } else if (ValueType->isObjCBoxableRecordType()) {
651
652
653
654
655
660 }
661
662
664 NSValuePointer = Context.getObjCObjectPointerType(NSValueObject);
665 }
666
668 const IdentifierInfo *II[] = {&Context.Idents.get("valueWithBytes"),
669 &Context.Idents.get("objCType")};
670 Selector ValueWithBytesObjCType = Context.Selectors.getSelector(2, II);
671
672
673 BoxingMethod = NSValueDecl->lookupClassMethod(ValueWithBytesObjCType);
674 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
675
680 false,
681 false,
682 false,
683 false,
684 true,
686 false);
687
689
693 &Context.Idents.get("bytes"),
694 Context.VoidPtrTy.withConst(),
695 nullptr,
697 Params.push_back(bytes);
698
703 &Context.Idents.get("type"),
704 Context.getPointerType(ConstCharType),
705 nullptr,
707 Params.push_back(type);
708
710 BoxingMethod = M;
711 }
712
714 ValueWithBytesObjCType, BoxingMethod))
716
718 }
719
720 if (!ValueType.isTriviallyCopyableType(Context)) {
721 Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)
724 }
725
728 }
729
730 if (!BoxingMethod) {
731 Diag(Loc, diag::err_objc_illegal_boxed_expression_type)
734 }
735
736 SemaRef.DiagnoseUseOfDecl(BoxingMethod, Loc);
737
739 if (ValueType->isObjCBoxableRecordType()) {
741 ConvertedValueExpr = SemaRef.PerformCopyInitialization(
742 IE, ValueExpr->getExprLoc(), ValueExpr);
743 } else {
744
747 ParamDecl);
748 ConvertedValueExpr =
750 }
751
752 if (ConvertedValueExpr.isInvalid())
754 ValueExpr = ConvertedValueExpr.get();
755
757 new (Context) ObjCBoxedExpr(ValueExpr, BoxedType,
758 BoxingMethod, SR);
759 return SemaRef.MaybeBindToTemporary(BoxedExpr);
760}
761
762
763
767 assert(().isSubscriptPointerArithmetic());
769
770
771
773 "base or index cannot have dependent type here");
774
775
776
778 if (Result.isInvalid())
780 IndexExpr = Result.get();
781
782
783 Result = SemaRef.DefaultLvalueConversion(BaseExpr);
784 if (Result.isInvalid())
786 BaseExpr = Result.get();
787
788
791 getterMethod, setterMethod, RB);
792}
793
798
804 }
805 }
806
807
808 QualType IdT = Context.getObjCIdType();
817 Context.getTranslationUnitDecl(), false ,
818 false ,
819 false, false,
820 true, false,
826 &Context.Idents.get("objects"),
827 Context.getPointerType(IdT),
828 nullptr,
830 Params.push_back(objects);
834 &Context.Idents.get("cnt"),
835 Context.UnsignedLongTy,
836 nullptr, SC_None,
837 nullptr);
838 Params.push_back(cnt);
839 Method->setMethodParams(Context, Params, {});
840 }
841
844
845
848 if (!PtrT ||
849 !Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {
850 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
851 << Sel;
852 Diag(Method->parameters()[0]->getLocation(),
853 diag::note_objc_literal_method_param)
854 << 0 << T
855 << Context.getPointerType(IdT.withConst());
857 }
858
859
860 if (->parameters()[1]->getType()->isIntegerType()) {
861 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
862 << Sel;
863 Diag(Method->parameters()[1]->getLocation(),
864 diag::note_objc_literal_method_param)
865 << 1
866 << Method->parameters()[1]->getType()
867 << "integral";
869 }
870
871
873 }
874
877
878
879
880 Expr **ElementsBuffer = Elements.data();
881 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
883 SemaRef, ElementsBuffer[I], RequiredType, true);
886
887 ElementsBuffer[I] = Converted.get();
888 }
889
891 = Context.getObjCObjectPointerType(
892 Context.getObjCInterfaceType(NSArrayDecl));
893
896}
897
898
899
900static void
903 if (Literal->isValueDependent() || Literal->isTypeDependent())
904 return;
905
906
907
908
909 struct APSIntCompare {
910 bool operator()(const llvm::APSInt &LHS, const llvm::APSInt &RHS) const {
911 return llvm::APSInt::compareValues(LHS, RHS) < 0;
912 }
913 };
914
915 llvm::DenseMap<StringRef, SourceLocation> StringKeys;
916 std::map<llvm::APSInt, SourceLocation, APSIntCompare> IntegralKeys;
917
918 auto checkOneKey = [&](auto &Map, const auto &Key, SourceLocation Loc) {
919 auto Pair = Map.insert({Key, Loc});
920 if (!Pair.second) {
921 S.Diag(Loc, diag::warn_nsdictionary_duplicate_key);
922 S.Diag(Pair.first->second, diag::note_nsdictionary_duplicate_key_here);
923 }
924 };
925
926 for (unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {
927 Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();
928
929 if (auto *StrLit = dyn_cast(Key)) {
930 StringRef Bytes = StrLit->getString()->getBytes();
932 checkOneKey(StringKeys, Bytes, Loc);
933 }
934
935 if (auto *BE = dyn_cast(Key)) {
936 Expr *Boxed = BE->getSubExpr();
938
939
941 checkOneKey(StringKeys, Str->getBytes(), Loc);
942 continue;
943 }
944
948 checkOneKey(IntegralKeys, Result.Val.getInt(), Loc);
949 }
950 }
951 }
952}
953
958
964 }
965 }
966
967
968
969 QualType IdT = Context.getObjCIdType();
977 nullptr , Context.getTranslationUnitDecl(),
978 false , false ,
979 false,
980 false,
981 true, false,
987 &Context.Idents.get("objects"),
988 Context.getPointerType(IdT),
989 nullptr, SC_None,
990 nullptr);
991 Params.push_back(objects);
995 &Context.Idents.get("keys"),
996 Context.getPointerType(IdT),
997 nullptr, SC_None,
998 nullptr);
999 Params.push_back(keys);
1003 &Context.Idents.get("cnt"),
1004 Context.UnsignedLongTy,
1005 nullptr, SC_None,
1006 nullptr);
1007 Params.push_back(cnt);
1008 Method->setMethodParams(Context, Params, {});
1009 }
1010
1014
1015
1016 QualType ValueT = Method->parameters()[0]->getType();
1018 if (!PtrValue ||
1019 !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {
1020 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1021 << Sel;
1022 Diag(Method->parameters()[0]->getLocation(),
1023 diag::note_objc_literal_method_param)
1024 << 0 << ValueT
1025 << Context.getPointerType(IdT.withConst());
1027 }
1028
1029
1032 if (!PtrKey ||
1033 !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
1034 IdT)) {
1035 bool err = true;
1036 if (PtrKey) {
1038
1043 Context.ObjCBuiltinIdTy, {},
1046 }
1047 }
1049 err = !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
1051 }
1052
1053 if (err) {
1054 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1055 << Sel;
1056 Diag(Method->parameters()[1]->getLocation(),
1057 diag::note_objc_literal_method_param)
1058 << 1 << KeyT
1059 << Context.getPointerType(IdT.withConst());
1061 }
1062 }
1063
1064
1065 QualType CountType = Method->parameters()[2]->getType();
1067 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1068 << Sel;
1069 Diag(Method->parameters()[2]->getLocation(),
1070 diag::note_objc_literal_method_param)
1071 << 2 << CountType
1072 << "integral";
1074 }
1075
1076
1078 }
1079
1084
1085
1086
1087 bool HasPackExpansions = false;
1089
1094
1095
1098 if (Value.isInvalid())
1100
1101 Element.Key = Key.get();
1102 Element.Value = Value.get();
1103
1104 if (Element.EllipsisLoc.isInvalid())
1105 continue;
1106
1107 if (!Element.Key->containsUnexpandedParameterPack() &&
1108 !Element.Value->containsUnexpandedParameterPack()) {
1109 Diag(Element.EllipsisLoc,
1110 diag::err_pack_expansion_without_parameter_packs)
1111 << SourceRange(Element.Key->getBeginLoc(),
1112 Element.Value->getEndLoc());
1114 }
1115
1116 HasPackExpansions = true;
1117 }
1118
1119 QualType Ty = Context.getObjCObjectPointerType(
1121
1122 auto *Literal =
1126 return SemaRef.MaybeBindToTemporary(Literal);
1127}
1128
1136 StrTy = Context.DependentTy;
1137 else {
1138 if (!EncodedType->getAsArrayTypeUnsafe() &&
1139 !EncodedType->isVoidType())
1140 if (SemaRef.RequireCompleteType(AtLoc, EncodedType,
1141 diag::err_incomplete_type_objc_at_encode,
1144
1145 std::string Str;
1147 Context.getObjCEncodingForType(EncodedType, Str, nullptr, &NotEncodedT);
1148 if (!NotEncodedT.isNull())
1149 Diag(AtLoc, diag::warn_incomplete_encoded_type)
1150 << EncodedType << NotEncodedT;
1151
1152
1153
1154 StrTy = Context.getStringLiteralArrayType(Context.CharTy, Str.size());
1155 }
1156
1157 return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
1158}
1159
1166
1168 QualType EncodedType = SemaRef.GetTypeFromParser(ty, &TInfo);
1169 if (!TInfo)
1170 TInfo = Context.getTrivialTypeSourceInfo(
1171 EncodedType, SemaRef.getLocForEndOfToken(LParenLoc));
1172
1174}
1175
1183 bool Warned = false;
1186 if (MatchingMethodDecl == Method ||
1188 MatchingMethodDecl->getSelector() != Method->getSelector())
1189 continue;
1192 if (!Warned) {
1193 Warned = true;
1194 S.Diag(AtLoc, diag::warn_multiple_selectors)
1197 S.Diag(Method->getLocation(), diag::note_method_declared_at)
1198 << Method->getDeclName();
1199 }
1200 S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)
1202 }
1203 }
1204 return Warned;
1205}
1206
1211 bool WarnMultipleSelectors) {
1212 if (!WarnMultipleSelectors ||
1214 return;
1215 bool Warned = false;
1216 for (SemaObjC::GlobalMethodPool::iterator b = S.ObjC().MethodPool.begin(),
1219
1222 Method, InstMethList))
1223 Warned = true;
1224
1225
1228 Method, ClsMethList) || Warned)
1229 return;
1230 }
1231}
1232
1235 bool &onlyDirect,
1236 bool &anyDirect) {
1237 (void)Sel;
1240 for (; M; M = M->getNext()) {
1242 if (!Method)
1243 continue;
1244 assert(Method->getSelector() == Sel && "Method with wrong selector in method list");
1245 if (Method->isDirectMethod()) {
1246 anyDirect = true;
1247 DirectMethod = Method;
1248 } else
1249 onlyDirect = false;
1250 }
1251
1252 return DirectMethod;
1253}
1254
1255
1256
1257
1258
1260 bool &onlyDirect,
1261 bool &anyDirect) {
1264 return nullptr;
1265
1267 S, Sel, Iter->second.first, onlyDirect, anyDirect);
1269 S, Sel, Iter->second.second, onlyDirect, anyDirect);
1270
1271 return DirectInstance ? DirectInstance : DirectClass;
1272}
1273
1276 if (!CurMD)
1277 return nullptr;
1279
1280
1281
1282
1284 return MD;
1286 return MD;
1288 return MD;
1290 return MD;
1291
1292 return nullptr;
1293}
1294
1300 bool WarnMultipleSelectors) {
1309 Selector MatchedSel = OM->getSelector();
1312 Diag(SelLoc, diag::warn_undeclared_selector_with_typo)
1313 << Sel << MatchedSel
1315
1316 } else
1317 Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1318 } else {
1320 WarnMultipleSelectors);
1321
1322 bool onlyDirect = true;
1323 bool anyDirect = false;
1326
1327 if (onlyDirect) {
1328 Diag(AtLoc, diag::err_direct_selector_expression)
1329 << Method->getSelector();
1330 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
1331 << Method->getDeclName();
1332 } else if (anyDirect) {
1333
1334
1335
1338 if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) {
1339 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1341 diag::note_direct_method_declared_at)
1343 } else if (!LikelyTargetMethod) {
1344
1345
1346 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1347 << Sel;
1349 diag::note_direct_method_declared_at)
1351 }
1352 }
1353 }
1354
1356 Method->getImplementationControl() !=
1358 .getSourceManager().isInSystemHeader(Method->getLocation()))
1360
1361
1362
1370 Diag(AtLoc, diag::err_arc_illegal_selector) <<
1371 Sel << SourceRange(LParenLoc, RParenLoc);
1372 break;
1373
1384 break;
1385 }
1386 }
1387 QualType Ty = Context.getObjCSelType();
1388 return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
1389}
1390
1399 if (!PDecl) {
1400 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1401 return true;
1402 }
1404 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1405 << PDecl;
1407 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1408 Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
1409 } else {
1411 }
1412
1413 QualType Ty = Context.getObjCProtoType();
1415 return true;
1416 Ty = Context.getObjCObjectPointerType(Ty);
1417 return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1418}
1419
1420
1423
1424
1425
1426
1427 ObjCMethodDecl *method = dyn_cast(DC);
1428 if (!method)
1429 return nullptr;
1430
1432
1433 return method;
1434}
1435
1438 if (auto nullability = AttributedType::stripOuterNullability(T)) {
1439 if (T == Context.getObjCInstanceType()) {
1440 return Context.getAttributedType(*nullability, Context.getObjCIdType(),
1441 Context.getObjCIdType());
1442 }
1443
1444 return origType;
1445 }
1446
1447 if (T == Context.getObjCInstanceType())
1448 return Context.getObjCIdType();
1449
1450 return origType;
1451}
1452
1453
1454
1455
1456
1457
1461 bool isClassMessage,
1462 bool isSuperMessage) {
1463 assert(Method && "Must have a method");
1464 if (!Method->hasRelatedResultType())
1465 return Method->getSendResultType(ReceiverType);
1466
1468
1469
1470
1472
1473 if (auto nullability =
1474 Method->getSendResultType(ReceiverType)->getNullability()) {
1475
1476 (void)AttributedType::stripOuterNullability(type);
1477
1478
1479 return Context.getAttributedType(*nullability, type, type);
1480 }
1481
1482 return type;
1483 };
1484
1485
1486
1487
1488
1489 if (Method->isInstanceMethod() && isClassMessage)
1491 Method->getSendResultType(ReceiverType));
1492
1493
1494
1495 if (isSuperMessage) {
1497 if (ObjCInterfaceDecl *Class = CurMethod->getClassInterface()) {
1498 return transferNullability(
1499 Context.getObjCObjectPointerType(
1500 Context.getObjCInterfaceType(Class)));
1501 }
1502 }
1503
1504
1506 return transferNullability(Context.getObjCObjectPointerType(ReceiverType));
1507
1508
1512 Method->getSendResultType(ReceiverType));
1513
1514
1515
1516
1517 return transferNullability(ReceiverType);
1518}
1519
1523 bool isClassMessage,
1524 bool isSuperMessage) {
1526
1528 SemaRef, ReceiverType, Method, isClassMessage, isSuperMessage);
1529
1530
1531 if (isClassMessage) {
1532
1533
1534
1535
1536
1538 assert(ReceiverType->isObjCClassType() && "expected a Class self");
1540 AttributedType::stripOuterNullability(T);
1541 if (T == Context.getObjCInstanceType()) {
1545 ->getDeclContext());
1546 assert(MD->isClassMethod() && "expected a class method");
1547 QualType NewResultType = Context.getObjCObjectPointerType(
1549 if (auto Nullability = resultType->getNullability())
1550 NewResultType = Context.getAttributedType(*Nullability, NewResultType,
1551 NewResultType);
1552 return NewResultType;
1553 }
1554 }
1555 return resultType;
1556 }
1557
1558
1559
1561 return resultType;
1562
1563
1564 unsigned receiverNullabilityIdx = 0;
1565 if (std::optional nullability =
1569 receiverNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1570 }
1571
1572 unsigned resultNullabilityIdx = 0;
1573 if (std::optional nullability =
1577 resultNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1578 }
1579
1580
1581
1582 static const uint8_t None = 0;
1583 static const uint8_t NonNull = 1;
1584 static const uint8_t Nullable = 2;
1586 static const uint8_t nullabilityMap[4][4] = {
1587
1592 };
1593
1594 unsigned newResultNullabilityIdx
1595 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1596 if (newResultNullabilityIdx == resultNullabilityIdx)
1597 return resultType;
1598
1599
1600
1601 do {
1602 if (auto attributed = dyn_cast(resultType.getTypePtr())) {
1603 resultType = attributed->getModifiedType();
1604 } else {
1606 }
1608
1609
1610 if (newResultNullabilityIdx > 0) {
1611 auto newNullability
1612 = static_cast<NullabilityKind>(newResultNullabilityIdx-1);
1613 return Context.getAttributedType(newNullability, resultType, resultType);
1614 }
1615
1616 return resultType;
1617}
1618
1619
1624 return MD;
1625
1626
1627
1632 dyn_cast(impl)) {
1633 iface = catImpl->getCategoryDecl();
1634 } else {
1635 iface = impl->getClassInterface();
1636 }
1637
1641 }
1642
1645 for (unsigned i = 0, e = overrides.size(); i != e; ++i) {
1648 return result;
1649 }
1650
1651 return nullptr;
1652}
1653
1656
1657
1660 Context.hasSameUnqualifiedType(destType, MD->getReturnType()))
1661 return;
1662
1663
1664
1667 SourceRange range = overridden->getReturnTypeSourceRange();
1670 loc = overridden->getLocation();
1671 Diag(loc, diag::note_related_result_type_explicit)
1672 << 1 << range;
1673 return;
1674 }
1675
1676
1677
1679 Diag(MD->getLocation(), diag::note_related_result_type_family)
1680 << 1
1681 << family;
1682}
1683
1687 const ObjCMessageExpr *MsgSend = dyn_cast(E);
1688 if (!MsgSend)
1689 return;
1690
1693 return;
1694
1695 if (->hasRelatedResultType())
1696 return;
1697
1698 if (Context.hasSameUnqualifiedType(
1699 Method->getReturnType().getNonReferenceType(), MsgSend->getType()))
1700 return;
1701
1702 if (!Context.hasSameUnqualifiedType(Method->getReturnType(),
1703 Context.getObjCInstanceType()))
1704 return;
1705
1706 Diag(Method->getLocation(), diag::note_related_result_type_inferred)
1707 << Method->isInstanceMethod() << Method->getSelector()
1709}
1710
1714 bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,
1719 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1720 SelLoc = SelectorLocs.front();
1721 else
1722 SelLoc = lbrac;
1723
1725
1726 for (unsigned i = 0, e = Args.size(); i != e; i++) {
1727 if (Args[i]->isTypeDependent())
1728 continue;
1729
1732 QualType paramTy;
1733 result = SemaRef.checkUnknownAnyArg(SelLoc, Args[i], paramTy);
1734 } else {
1735 result = SemaRef.DefaultArgumentPromotion(Args[i]);
1736 }
1738 return true;
1739 Args[i] = result.get();
1740 }
1741
1742 unsigned DiagID;
1744 DiagID = diag::err_arc_method_not_found;
1745 else
1746 DiagID = isClassMessage ? diag::warn_class_method_not_found
1747 : diag::warn_inst_method_not_found;
1752 DiagID = diag::err_method_not_found_with_typo;
1753 else
1754 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1755 : diag::warn_instance_method_not_found_with_typo;
1757 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1759 Diag(SelLoc, DiagID)
1760 << Sel<< isClassMessage << MatchedSel
1762 else
1763 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1764 }
1765 else
1766 Diag(SelLoc, DiagID)
1767 << Sel << isClassMessage << SourceRange(SelectorLocs.front(),
1768 SelectorLocs.back());
1769
1772 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1774 if (ThisClass->lookupClassMethod(Sel))
1775 Diag(RecRange.getBegin(), diag::note_receiver_expr_here)
1777 ThisClass->getNameAsString());
1778 }
1779 }
1780 }
1781
1782
1783
1785 ReturnType = Context.UnknownAnyTy;
1786 } else {
1787 ReturnType = Context.getObjCIdType();
1788 }
1790 return false;
1791 }
1792
1794 isClassMessage, isSuperMessage);
1796
1797 unsigned NumNamedArgs = Sel.getNumArgs();
1798
1799
1801 NumNamedArgs = Method->param_size();
1802
1803 if (Args.size() < NumNamedArgs) {
1804 Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1805 << 2 << NumNamedArgs << static_cast(Args.size())
1806 << 0;
1807 return false;
1808 }
1809
1810
1811
1812 std::optional<ArrayRef> typeArgs =
1814 bool IsError = false;
1815 for (unsigned i = 0; i < NumNamedArgs; i++) {
1816
1817 if (Args[i]->isTypeDependent())
1818 continue;
1819
1820 Expr *argExpr = Args[i];
1821
1823 assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
1824
1825 if (param->hasAttr() &&
1827 if (auto *BE = dyn_cast(
1829 BE->getBlockDecl()->setDoesNotEscape();
1830
1831
1832
1834 !param->hasAttr())
1836
1837
1838
1839 if (param->getType() == Context.UnknownAnyTy) {
1841 ExprResult argE = SemaRef.checkUnknownAnyArg(SelLoc, argExpr, paramType);
1843 IsError = true;
1844 } else {
1845 Args[i] = argE.get();
1846
1847
1848 param->setType(paramType);
1849 }
1850 continue;
1851 }
1852
1855 if (typeArgs)
1857 Context,
1858 *typeArgs,
1860
1861 if (SemaRef.RequireCompleteType(
1863 diag::err_call_incomplete_argument, argExpr))
1864 return true;
1865
1871 IsError = true;
1872 else {
1874
1875
1876
1877
1878 if (typeArgs && Args[i]->isPRValue() && paramType->isBlockPointerType() &&
1879 Args[i]->getType()->isBlockPointerType() &&
1882 SemaRef.maybeExtendBlockObject(arg);
1883 Args[i] = arg.get();
1884 }
1885 }
1886 }
1887
1888
1889 if (Method->isVariadic()) {
1890 for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
1891 if (Args[i]->isTypeDependent())
1892 continue;
1893
1897 Args[i] = Arg.get();
1898 }
1899 } else {
1900
1901 if (Args.size() != NumNamedArgs) {
1902 Diag(Args[NumNamedArgs]->getBeginLoc(),
1903 diag::err_typecheck_call_too_many_args)
1904 << 2 << NumNamedArgs << static_cast(Args.size())
1905 << Method->getSourceRange() << 0
1906 << SourceRange(Args[NumNamedArgs]->getBeginLoc(),
1907 Args.back()->getEndLoc());
1908 }
1909 }
1910
1911 SemaRef.DiagnoseSentinelCalls(Method, SelLoc, Args);
1912
1913
1914 IsError |=
1916
1917 return IsError;
1918}
1919
1921
1923 SemaRef.CurContext->getNonClosureAncestor());
1925}
1926
1928 if (!method) return false;
1929
1931 if (DeclRefExpr *DRE = dyn_cast(receiver))
1932 if (DRE->getDecl() == method->getSelfDecl())
1933 return true;
1934 return false;
1935}
1936
1937
1939 bool isInstance) {
1942
1943 if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
1944 return method;
1945
1946
1947
1948 if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
1949 return method;
1950 }
1951
1952
1953 for (const auto *I : objType->quals())
1954 if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance))
1955 return method;
1956
1957 return nullptr;
1958}
1959
1960
1961
1965 for (const auto *PROTO : OPT->quals()) {
1966 if ((MD = PROTO->lookupMethod(Sel, Instance))) {
1967 return MD;
1968 }
1969 }
1970 return nullptr;
1971}
1972
1973
1974
1981 assert(IFaceT && "Expected an Interface");
1983
1985 Diag(MemberLoc, diag::err_invalid_property_name)
1986 << MemberName << QualType(OPT, 0);
1988 }
1989
1991
1995 diag::err_property_not_found_forward_class,
1996 MemberName, BaseRange))
1998
2001
2002 if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2004 if (Super)
2005 return new (Context)
2008 else
2009 return new (Context)
2012 }
2013
2014 for (const auto *I : OPT->quals())
2017
2018 if (SemaRef.DiagnoseUseOfDecl(PD, MemberLoc))
2020
2021 if (Super)
2024 SuperLoc, SuperType);
2025 else
2026 return new (Context)
2029 }
2030
2031
2032
2033
2034
2035
2038
2039
2040 if (!Getter)
2042
2043
2044 if (!Getter)
2046
2047 if (Getter) {
2048
2049 if (SemaRef.DiagnoseUseOfDecl(Getter, MemberLoc))
2051 }
2052
2053
2057
2058
2059 if (!Setter)
2061
2062 if (!Setter) {
2063
2064
2066 }
2067
2068 if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, MemberLoc))
2070
2071
2072
2073
2078
2079
2080 if (!(PDecl->getPropertyAttributes() &
2082 Diag(MemberLoc,
2083 diag::warn_property_access_suggest)
2084 << MemberName << QualType(OPT, 0) << PDecl->getName()
2086 }
2087 }
2088
2089 if (Getter || Setter) {
2090 if (Super)
2091 return new (Context)
2094 else
2095 return new (Context)
2098
2099 }
2100
2101
2106 OPT)) {
2110
2112 Corrected.isKeyword() ? nullptr : Corrected.getFoundDecl();
2115
2116
2117 Diag(MemberLoc, diag::err_class_property_found) << MemberName
2122 }
2123 } else {
2124 SemaRef.diagnoseTypo(Corrected,
2125 PDiag(diag::err_property_not_found_suggest)
2126 << MemberName << QualType(OPT, 0));
2128 TypoResult, MemberLoc,
2129 SuperLoc, SuperType, Super);
2130 }
2131 }
2137 T->getAsObjCInterfacePointerType()) {
2138 if (SemaRef.RequireCompleteType(MemberLoc, OBJPT->getPointeeType(),
2139 diag::err_property_not_as_forward_class,
2140 MemberName, BaseExpr))
2142 }
2143 Diag(MemberLoc,
2144 diag::err_ivar_access_using_property_syntax_suggest)
2145 << MemberName << QualType(OPT, 0) << Ivar->getDeclName()
2148 }
2149
2150 Diag(MemberLoc, diag::err_property_not_found)
2151 << MemberName << QualType(OPT, 0);
2152 if (Setter)
2153 Diag(Setter->getLocation(), diag::note_getter_unavailable)
2156}
2157
2162 const IdentifierInfo *receiverNamePtr = &receiverName;
2164 receiverNameLoc);
2165
2167 if (!IFace) {
2168
2169
2170 if (receiverNamePtr->isStr("super")) {
2172 if (auto classDecl = CurMethod->getClassInterface()) {
2173 SuperType = QualType(classDecl->getSuperClassType(), 0);
2174 if (CurMethod->isInstanceMethod()) {
2175 if (SuperType.isNull()) {
2176
2177 Diag(receiverNameLoc, diag::err_root_class_cannot_use_super)
2178 << CurMethod->getClassInterface()->getIdentifier();
2180 }
2181 QualType T = Context.getObjCObjectPointerType(SuperType);
2182
2184 nullptr,
2186 &propertyName,
2187 propertyNameLoc,
2188 receiverNameLoc, T, true);
2189 }
2190
2191
2192
2193 IFace = CurMethod->getClassInterface()->getSuperClass();
2194 }
2195 }
2196 }
2197
2198 if (!IFace) {
2199 Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
2200 << tok::l_paren;
2202 }
2203 }
2204
2209 GetterSel = PD->getGetterName();
2210 SetterSel = PD->getSetterName();
2211 } else {
2212 GetterSel = SemaRef.PP.getSelectorTable().getNullarySelector(&propertyName);
2214 SemaRef.PP.getIdentifierTable(), SemaRef.PP.getSelectorTable(),
2215 &propertyName);
2216 }
2217
2218
2220
2221
2222 if (!Getter)
2224
2225 if (Getter) {
2226
2227
2228 if (SemaRef.DiagnoseUseOfDecl(Getter, propertyNameLoc))
2230 }
2231
2232
2234 if (!Setter) {
2235
2236
2238 }
2239
2240 if (!Setter)
2242
2243 if (Setter && SemaRef.DiagnoseUseOfDecl(Setter, propertyNameLoc))
2245
2246 if (Getter || Setter) {
2247 if (!SuperType.isNull())
2248 return new (Context)
2251 SuperType);
2252
2255 propertyNameLoc, receiverNameLoc, IFace);
2256 }
2257 return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
2258 << &propertyName << Context.getObjCInterfaceType(IFace));
2259}
2260
2261namespace {
2262
2264 public:
2266
2268 WantObjCSuper = Method->getClassInterface()->getSuperClass();
2269 }
2270
2271 bool ValidateCandidate(const TypoCorrection &candidate) override {
2274 }
2275
2276 std::unique_ptr clone() override {
2277 return std::make_unique(*this);
2278 }
2279};
2280
2281}
2282
2286 bool HasTrailingDot, ParsedType &ReceiverType) {
2288 ReceiverType = nullptr;
2289
2290
2291
2292
2295
2298
2299 switch (Result.getResultKind()) {
2301
2302
2303
2304
2306 if (->getClassInterface()) {
2307
2309 }
2310
2312 if (Method->getClassInterface()->lookupInstanceVariable(Name,
2313 ClassDeclared))
2315 }
2316
2317
2318 break;
2319
2324 Result.suppressDiagnostics();
2326
2328
2329
2330 if (HasTrailingDot)
2332
2333
2337 T = Context.getObjCInterfaceType(Class);
2338 else if (TypeDecl *Type = dyn_cast(ND)) {
2339 SemaRef.DiagnoseUseOfDecl(Type, NameLoc);
2341 std::nullopt, Type);
2342 } else
2344
2345
2346
2347 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2348 ReceiverType = SemaRef.CreateParsedType(T, TSInfo);
2350 }
2351 }
2352
2353 ObjCInterfaceOrSuperCCC CCC(SemaRef.getCurMethodDecl());
2355 Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC,
2357 if (Corrected.isKeyword()) {
2358
2359
2360 SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)
2361 << Name);
2365
2366
2367 SemaRef.diagnoseTypo(Corrected, PDiag(diag::err_unknown_receiver_suggest)
2368 << Name);
2370 TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
2371 ReceiverType = SemaRef.CreateParsedType(T, TSInfo);
2373 }
2374 }
2375
2376
2378}
2379
2386
2389 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2391 }
2392
2395 Diag(SuperLoc, diag::err_no_super_class_message)
2396 << Method->getDeclName();
2398 }
2399
2400 QualType SuperTy(Class->getSuperClassType(), 0);
2401 if (SuperTy.isNull()) {
2402
2403 Diag(SuperLoc, diag::err_root_class_cannot_use_super)
2404 << Class->getIdentifier();
2406 }
2407
2408
2409
2410 if (Method->getSelector() == Sel)
2411 SemaRef.getCurFunction()->ObjCShouldCallSuper = false;
2412
2413 if (Method->isInstanceMethod()) {
2414
2415
2416 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2418 Sel, nullptr,
2419 LBracLoc, SelectorLocs, RBracLoc, Args);
2420 }
2421
2422
2423
2425 SuperTy,
2426 SuperLoc, Sel, nullptr,
2427 LBracLoc, SelectorLocs, RBracLoc, Args);
2428}
2429
2431 bool isSuperReceiver,
2437 if (!ReceiverType.isNull())
2438 receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
2439
2440 assert(((isSuperReceiver && Loc.isValid()) || receiverTypeInfo) &&
2441 "Either the super receiver location needs to be valid or the receiver "
2442 "needs valid type source information");
2444 isSuperReceiver ? Loc : SourceLocation(),
2445 Sel, Method, Loc, Loc, Loc, Args,
2446 true);
2447}
2448
2450 unsigned DiagID,
2455 return;
2456
2459 if (refactor(Msg, *S.ObjC().NSAPIObj, ECommit)) {
2460 auto Builder = S.Diag(MsgLoc, DiagID)
2462
2464 return;
2468 switch (Edit.Kind) {
2473 break;
2475 Builder.AddFixItHint(
2479 break;
2482 break;
2483 }
2484 }
2485 }
2486}
2487
2492
2496 bool IsClassObjectCall) {
2497
2498
2500 Args.empty())
2501 return;
2502 const auto *SE = dyn_cast(Args[0]->IgnoreParens());
2503 if (!SE)
2504 return;
2506 if (!IsClassObjectCall) {
2508 if (!OPT || !OPT->getInterfaceDecl())
2509 return;
2510 ImpliedMethod =
2511 OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
2512 if (!ImpliedMethod)
2513 ImpliedMethod =
2514 OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
2515 } else {
2517 if (!IT)
2518 return;
2519 ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
2520 if (!ImpliedMethod)
2521 ImpliedMethod =
2522 IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
2523 }
2524 if (!ImpliedMethod)
2525 return;
2527 if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
2528 S.Diag(Loc, diag::warn_objc_unsafe_perform_selector)
2529 << Method->getSelector()
2530 << (!Ret->isRecordType()
2531 ? 2
2532 : Ret->isUnionType() ? 1 : 0);
2534 diag::note_objc_unsafe_perform_selector_method_declared_here)
2536 }
2537}
2538
2539
2540
2541static void
2545 Expr **Args, unsigned NumArgs) {
2546 unsigned Idx = 0;
2547 bool Format = false;
2550 Idx = 0;
2551 Format = true;
2552 }
2553 else if (Method) {
2554 for (const auto *I : Method->specific_attrs()) {
2556 Format = true;
2557 break;
2558 }
2559 }
2560 }
2561 if (!Format || NumArgs <= Idx)
2562 return;
2563
2564 Expr *FormatExpr = Args[Idx];
2569 S.Diag(FormatExpr->getExprLoc(), diag::warn_objc_cdirective_format_string)
2570 << "%s" << 0 << 0;
2571 if (Method)
2572 S.Diag(Method->getLocation(), diag::note_method_declared_at)
2573 << Method->getDeclName();
2574 }
2575 }
2576}
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2615 Diag(Loc, diag::err_missing_open_square_message_send)
2617 LBracLoc = Loc;
2618 }
2620 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2621 SelectorSlotLocs = SelectorLocs;
2622 else
2623 SelectorSlotLocs = Loc;
2625
2627
2628
2629 unsigned NumArgs = ArgsIn.size();
2630 Expr **Args = ArgsIn.data();
2631 assert(SuperLoc.isInvalid() && "Message to super with dependent type");
2633 ReceiverTypeInfo, Sel, SelectorLocs,
2634 nullptr, ArrayRef(Args, NumArgs),
2635 RBracLoc, isImplicit);
2636 }
2637
2638
2641 if (!ClassType || !(Class = ClassType->getInterface())) {
2642 Diag(Loc, diag::err_invalid_receiver_class_message)
2643 << ReceiverType;
2645 }
2646 assert(Class && "We don't know which class we're messaging?");
2647
2649 (void)SemaRef.DiagnoseUseOfDecl(Class, SelectorSlotLocs);
2650
2655 if (SemaRef.RequireCompleteType(Loc, Context.getObjCInterfaceType(Class),
2657 ? diag::err_arc_receiver_forward_class
2658 : diag::warn_receiver_forward_class),
2659 TypeRange)) {
2660
2664 Diag(Method->getLocation(), diag::note_method_sent_forward_class)
2665 << Method->getDeclName();
2666 }
2669
2670
2672 Method = Class->lookupPrivateClassMethod(Sel);
2673
2674 if (Method && SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, nullptr,
2675 false, false, Class))
2677 }
2678
2679
2682
2683 unsigned NumArgs = ArgsIn.size();
2684 Expr **Args = ArgsIn.data();
2686 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
2690
2691 if (Method && ->getReturnType()->isVoidType() &&
2692 SemaRef.RequireCompleteType(
2693 LBracLoc, Method->getReturnType(),
2694 diag::err_illegal_message_expr_incomplete_type))
2696
2698 Diag(SuperLoc, diag::err_messaging_super_with_direct_method)
2700 SuperLoc, getLangOpts().ObjCAutoRefCount
2701 ? "self"
2702 : Method->getClassInterface()->getName());
2703 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
2704 << Method->getDeclName();
2705 }
2706
2707
2709 if (!SuperLoc.isValid()) {
2711 dyn_cast(Method->getDeclContext());
2712 if (ID == Class) {
2713 Diag(Loc, diag::warn_direct_initialize_call);
2714 Diag(Method->getLocation(), diag::note_method_declared_at)
2715 << Method->getDeclName();
2716 }
2718
2720 Diag(Loc, diag::warn_direct_super_initialize_call);
2721 Diag(Method->getLocation(), diag::note_method_declared_at)
2722 << Method->getDeclName();
2723 Diag(CurMeth->getLocation(), diag::note_method_declared_at)
2724 << CurMeth->getDeclName();
2725 }
2726 }
2727 }
2728
2730
2731
2735 Context, ReturnType, VK, LBracLoc, SuperLoc, false,
2736 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
2737 RBracLoc, isImplicit);
2738 else {
2740 Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, SelectorLocs,
2741 Method, ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
2742 if (!isImplicit)
2744 }
2747 ReceiverType, true);
2749}
2750
2751
2752
2753
2762 SemaRef.GetTypeFromParser(Receiver, &ReceiverTypeInfo);
2763 if (ReceiverType.isNull())
2765
2766 if (!ReceiverTypeInfo)
2767 ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
2768
2771 nullptr, LBracLoc, SelectorLocs, RBracLoc,
2772 Args);
2773}
2774
2780 Sel, Method, Loc, Loc, Loc, Args,
2781 true);
2782}
2783
2786 return false;
2787 const auto *Protocol = dyn_cast(M->getDeclContext());
2788 if (!Protocol)
2789 return false;
2792 if (const auto *RootClass = dyn_cast_or_null(
2795 for (const ObjCProtocolDecl *P : RootClass->all_referenced_protocols()) {
2796 if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
2797 return true;
2798 }
2799 }
2800 return false;
2801}
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2836 assert((Receiver || SuperLoc.isValid()) && "If the Receiver is null, the "
2837 "SuperLoc must be valid so we can "
2838 "use it instead.");
2840
2841
2846 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
2847 SelectorSlotLocs = SelectorLocs;
2848 else
2849 SelectorSlotLocs = Loc;
2851
2853 Diag(Loc, diag::err_missing_open_square_message_send)
2855 LBracLoc = Loc;
2856 }
2857
2858
2859
2860 if (Receiver) {
2863 if (Receiver->getType() == Context.UnknownAnyTy)
2865 SemaRef.forceUnknownAnyToType(Receiver, Context.getObjCIdType());
2866 else
2867 Result = SemaRef.CheckPlaceholderExpr(Receiver);
2869 Receiver = Result.get();
2870 }
2871
2873
2874
2875 unsigned NumArgs = ArgsIn.size();
2876 Expr **Args = ArgsIn.data();
2877 assert(SuperLoc.isInvalid() && "Message to super with dependent type");
2879 Context, Context.DependentTy, VK_PRValue, LBracLoc, Receiver, Sel,
2880 SelectorLocs, nullptr, ArrayRef(Args, NumArgs), RBracLoc,
2881 isImplicit);
2882 }
2883
2884
2885
2887 if (Result.isInvalid())
2889 Receiver = Result.get();
2890 ReceiverType = Receiver->getType();
2891
2892
2893
2894
2896
2897 } else if (().ObjCAutoRefCount &&
2898 !Context.getObjCIdType().isNull() &&
2901
2902
2903 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
2906 .ImpCastExprToType(Receiver, Context.getObjCIdType(),
2907 CK_CPointerToObjCPointerCast)
2908 .get();
2909 } else {
2910
2913 CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
2914 Receiver =
2915 SemaRef.ImpCastExprToType(Receiver, Context.getObjCIdType(), Kind)
2916 .get();
2917 }
2918 ReceiverType = Receiver->getType();
2920
2921 if (SemaRef.RequireCompleteType(Loc, Receiver->getType(),
2922 diag::err_incomplete_receiver_type))
2924
2926 SemaRef.PerformContextuallyConvertToObjCPointer(Receiver);
2928 Receiver = result.get();
2929 ReceiverType = Receiver->getType();
2930 }
2931 }
2932 }
2933
2934
2935
2936
2937
2939
2940
2943 typeBound);
2945 (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
2947
2949 true, typeBound);
2950 if (!Methods.empty()) {
2951
2952
2953 Method = Methods[0];
2954
2956 Sel, ArgsIn, Method->isInstanceMethod(), Methods))
2957 Method = BestMethod;
2958
2961 receiverIsIdLike, Methods))
2962 SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs);
2963 }
2966
2967
2968
2969
2973
2977
2979 Diag(SelLoc, diag::warn_instance_method_on_class_found)
2980 << Method->getSelector() << Sel;
2981 Diag(Method->getLocation(), diag::note_method_declared_at)
2982 << Method->getDeclName();
2983 }
2984 }
2985 } else {
2987 if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
2988
2989
2990
2991
2992 Method = ClassDecl->lookupClassMethod(Sel);
2993
2995 Method = ClassDecl->lookupPrivateClassMethod(Sel);
2996
2999 }
3000 }
3002
3003 if (!Receiver || (Receiver)) {
3004
3005
3008 false,
3009 true);
3010 if (!Methods.empty()) {
3011
3012
3013 Method = Methods[0];
3014
3015
3016 if (Method->isInstanceMethod()) {
3018 dyn_cast(Method->getDeclContext())) {
3019 if (ID->getSuperClass())
3020 Diag(SelLoc, diag::warn_root_inst_method_not_found)
3021 << Sel << SourceRange(LBracLoc, RBracLoc);
3022 }
3023 }
3024
3026 Sel, ArgsIn, Method->isInstanceMethod(), Methods))
3027 Method = BestMethod;
3028 }
3029 }
3030 }
3031 }
3032 } else {
3034
3035
3036
3037
3040
3048
3049 ClassDecl = OCIType->getInterfaceDecl();
3050
3051
3052
3053
3054
3056 if (SemaRef.RequireCompleteType(
3057 Loc, OCIType->getPointeeType(),
3059 ? diag::err_arc_receiver_forward_instance
3060 : diag::warn_receiver_forward_instance,
3061 RecRange)) {
3064
3065 forwardClass = OCIType->getInterfaceDecl();
3067 diag::note_receiver_is_id);
3069 } else {
3071 }
3072
3074
3076
3078
3080
3082 Diag(SelLoc, diag::err_arc_may_not_respond)
3083 << OCIType->getPointeeType() << Sel << RecRange
3084 << SourceRange(SelectorLocs.front(), SelectorLocs.back());
3086 }
3087
3089
3090
3091
3092 if (OCIType->qual_empty()) {
3095 true,
3096 false);
3097 if (!Methods.empty()) {
3098
3099
3100 Method = Methods[0];
3101
3103 Sel, ArgsIn, Method->isInstanceMethod(), Methods))
3104 Method = BestMethod;
3105
3108 true,
3109 Methods);
3110 }
3111 if (Method && !forwardClass)
3112 Diag(SelLoc, diag::warn_maynot_respond)
3113 << OCIType->getInterfaceDecl()->getIdentifier()
3114 << Sel << RecRange;
3115 }
3116 }
3117 }
3119 SemaRef.DiagnoseUseOfDecl(Method, SelectorSlotLocs, forwardClass))
3121 } else {
3122
3123 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3125 }
3126 }
3127 }
3128
3131 ? SemaRef.getEnclosingFunction()
3132 : nullptr;
3133
3135 if (ReceiverType->isObjCIdType() && !isImplicit) {
3137 diag::err_messaging_unqualified_id_with_direct_method);
3138 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3139 << Method->getDeclName();
3140 }
3141
3142
3143
3144
3147 {
3149 diag::err_messaging_class_with_direct_method);
3152 RecRange, Method->getClassInterface()->getName()));
3153 }
3154 }
3155 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3156 << Method->getDeclName();
3157 }
3158
3159 if (SuperLoc.isValid()) {
3160 {
3161 auto Builder =
3162 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3165 SuperLoc, Method->getClassInterface()->getName()));
3166 } else {
3168 }
3169 }
3170 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3171 << Method->getDeclName();
3172 }
3173 } else if (ReceiverType->isObjCIdType() && !isImplicit) {
3174 Diag(Receiver->getExprLoc(), diag::warn_messaging_unqualified_id);
3175 }
3176
3177 if (DIFunctionScopeInfo &&
3180 bool isDesignatedInitChain = false;
3181 if (SuperLoc.isValid()) {
3184 if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {
3185
3186
3187 if (!ID->declaresOrInheritsDesignatedInitializers() ||
3188 ID->isDesignatedInitializer(Sel)) {
3189 isDesignatedInitChain = true;
3191 }
3192 }
3193 }
3194 }
3195 if (!isDesignatedInitChain) {
3197 auto *CurMD = SemaRef.getCurMethodDecl();
3198 assert(CurMD && "Current method declaration should not be null");
3199 bool isDesignated =
3200 CurMD->isDesignatedInitializerForTheInterface(&InitMethod);
3201 assert(isDesignated && InitMethod);
3202 (void)isDesignated;
3204 diag::warn_objc_designated_init_non_designated_init_call :
3205 diag::warn_objc_designated_init_non_super_designated_init_call);
3207 diag::note_objc_designated_init_marked_here);
3208 }
3209 }
3210
3211 if (DIFunctionScopeInfo &&
3214 if (SuperLoc.isValid()) {
3215 Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
3216 } else {
3218 }
3219 }
3220
3221
3222 unsigned NumArgs = ArgsIn.size();
3223 Expr **Args = ArgsIn.data();
3229 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
3231 LBracLoc, RBracLoc, RecRange, ReturnType, VK))
3233
3234 if (Method && ->getReturnType()->isVoidType() &&
3235 SemaRef.RequireCompleteType(
3236 LBracLoc, Method->getReturnType(),
3237 diag::err_illegal_message_expr_incomplete_type))
3239
3240
3241
3245 switch (family) {
3249 break;
3250
3259 break;
3260
3266 Diag(SelLoc, diag::err_arc_illegal_explicit_message)
3267 << Sel << RecRange;
3268 break;
3269
3271 if (Method && NumArgs >= 1) {
3272 if (const auto *SelExp =
3273 dyn_cast(Args[0]->IgnoreParens())) {
3274 Selector ArgSel = SelExp->getSelector();
3277 SelExp->getSourceRange());
3278 if (!SelMethod)
3279 SelMethod =
3281 SelExp->getSourceRange());
3282 if (SelMethod) {
3284 switch (SelFamily) {
3290
3291 if (!SelMethod->hasAttr()) {
3292
3293 Diag(SelLoc,
3294 diag::err_arc_perform_selector_retains);
3295 Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3297 }
3298 break;
3299 default:
3300
3301 if (SelMethod->hasAttr()) {
3302
3303 Diag(SelLoc,
3304 diag::err_arc_perform_selector_retains);
3305 Diag(SelMethod->getLocation(), diag::note_method_declared_at)
3307 }
3308 break;
3309 }
3310 }
3311 } else {
3312
3313 Diag(SelLoc, diag::warn_arc_perform_selector_leaks);
3314 Diag(Args[0]->getExprLoc(), diag::note_used_here);
3315 }
3316 }
3317 break;
3318 }
3319 }
3320
3322
3323
3327 Context, ReturnType, VK, LBracLoc, SuperLoc, true,
3328 ReceiverType, Sel, SelectorLocs, Method, ArrayRef(Args, NumArgs),
3329 RBracLoc, isImplicit);
3330 else {
3332 Context, ReturnType, VK, LBracLoc, Receiver, Sel, SelectorLocs, Method,
3333 ArrayRef(Args, NumArgs), RBracLoc, isImplicit);
3334 if (!isImplicit)
3336 }
3338 bool IsClassObjectCall = ClassMessage;
3339
3340
3341
3342
3343 if (Receiver && isSelfExpr(Receiver)) {
3345 if (OPT->getObjectType()->isObjCClass()) {
3346 if (const auto *CurMeth = SemaRef.getCurMethodDecl()) {
3347 IsClassObjectCall = true;
3348 ReceiverType =
3349 Context.getObjCInterfaceType(CurMeth->getClassInterface());
3350 }
3351 }
3352 }
3353 }
3355 ReceiverType, IsClassObjectCall);
3356 }
3357
3359
3362
3363
3366
3367
3368 Result->setDelegateInitCall(true);
3370 }
3371 }
3372
3373
3374
3376 }
3377
3379 if (!isImplicit && Method) {
3381 bool IsWeak =
3385 if (IsWeak && .isUnevaluatedContext() &&
3386 ().isIgnored(diag::warn_arc_repeated_use_of_weak,
3387 LBracLoc))
3388 SemaRef.getCurFunction()->recordUseOfWeak(Result, Prop);
3389 }
3390 }
3391 }
3392
3394
3396}
3397
3401 Selector Sel = OSE->getSelector();
3406 }
3407}
3408
3409
3410
3411
3418 if (!Receiver)
3420
3421
3424 SemaRef.MaybeConvertParenListExprToParenExpr(S, Receiver);
3426 Receiver = Result.get();
3427 }
3428
3430 IdentifierInfo *SelectorId = &Context.Idents.get("respondsToSelector");
3432 }
3435
3438 nullptr, LBracLoc, SelectorLocs,
3439 RBracLoc, Args);
3440}
3441
3443
3445
3446
3448
3449
3451
3452
3454
3455
3457};
3458
3464
3470
3472 bool isIndirect = false;
3473
3474
3476 type = ref->getPointeeType();
3477 isIndirect = true;
3478 }
3479
3480
3481 while (true) {
3483 type = ptr->getPointeeType();
3484
3485
3486 if (!isIndirect) {
3489 }
3490 } else if (const ArrayType *array = type->getAsArrayTypeUnsafe()) {
3491 type = QualType(array->getElementType()->getBaseElementTypeUnsafe(), 0);
3492 } else {
3493 break;
3494 }
3495 isIndirect = true;
3496 }
3497
3498 if (isIndirect) {
3499 if (type->isObjCARCBridgableType())
3502 }
3503
3504 if (type->isObjCARCBridgableType())
3506
3508}
3509
3510namespace {
3511
3512 enum ACCResult {
3513
3514 ACC_invalid,
3515
3516
3517 ACC_bottom,
3518
3519
3520 ACC_plusZero,
3521
3522
3523 ACC_plusOne
3524 };
3525 ACCResult merge(ACCResult left, ACCResult right) {
3526 if (left == right) return left;
3527 if (left == ACC_bottom) return right;
3528 if (right == ACC_bottom) return left;
3529 return ACC_invalid;
3530 }
3531
3532
3533
3534 class ARCCastChecker : public StmtVisitor<ARCCastChecker, ACCResult> {
3535 typedef StmtVisitor<ARCCastChecker, ACCResult> super;
3536
3537 ASTContext &Context;
3540 bool Diagnose;
3541
3542 static bool isCFType(QualType type) {
3543
3544 return type->isCARCBridgableType();
3545 }
3546
3547 public:
3550 : Context(Context), SourceClass(source), TargetClass(target),
3551 Diagnose(diagnose) {}
3552
3553 using super::Visit;
3554 ACCResult Visit(Expr *e) {
3556 }
3557
3558 ACCResult VisitStmt(Stmt *s) {
3559 return ACC_invalid;
3560 }
3561
3562
3563 ACCResult VisitExpr(Expr *e) {
3565 return ACC_bottom;
3566 return ACC_invalid;
3567 }
3568
3569
3570 ACCResult VisitObjCStringLiteral(ObjCStringLiteral *e) {
3571
3572
3574
3575 return ACC_invalid;
3576 }
3577
3578
3579 ACCResult VisitCastExpr(CastExpr *e) {
3581 case CK_NullToPointer:
3582 return ACC_bottom;
3583
3584 case CK_NoOp:
3585 case CK_LValueToRValue:
3586 case CK_BitCast:
3587 case CK_CPointerToObjCPointerCast:
3588 case CK_BlockPointerToObjCPointerCast:
3589 case CK_AnyPointerToBlockPointerCast:
3591
3592 default:
3593 return ACC_invalid;
3594 }
3595 }
3596
3597
3598 ACCResult VisitUnaryExtension(UnaryOperator *e) {
3600 }
3601
3602
3603 ACCResult VisitBinComma(BinaryOperator *e) {
3604 return Visit(e->getRHS());
3605 }
3606
3607
3608 ACCResult VisitConditionalOperator(ConditionalOperator *e) {
3609 ACCResult left = Visit(e->getTrueExpr());
3610 if (left == ACC_invalid) return ACC_invalid;
3612 }
3613
3614
3615 ACCResult VisitPseudoObjectExpr(PseudoObjectExpr *e) {
3616
3618 }
3619
3620
3621 ACCResult VisitStmtExpr(StmtExpr *e) {
3623 }
3624
3625
3626 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
3627 VarDecl *var = dyn_cast(e->getDecl());
3628
3631 var &&
3632 ->hasDefinition(Context) &&
3633 var->getType().isConstQualified()) {
3634
3635
3636
3638 return ACC_bottom;
3639
3640 return ACC_plusZero;
3641 }
3642
3643
3644 return ACC_invalid;
3645 }
3646
3647
3648 ACCResult VisitCallExpr(CallExpr *e) {
3650 if (ACCResult result = checkCallToFunction(fn))
3651 return result;
3652
3653 return super::VisitCallExpr(e);
3654 }
3655
3656 ACCResult checkCallToFunction(FunctionDecl *fn) {
3657
3659 return ACC_invalid;
3660
3662 return ACC_invalid;
3663
3664
3665 if (fn->hasAttr())
3666 return ACC_plusZero;
3667
3668
3669
3670
3671 if (fn->hasAttr())
3672 return Diagnose ? ACC_plusOne
3673 : ACC_invalid;
3674
3675
3677 if (builtinID == Builtin::BI__builtin___CFStringMakeConstantString)
3678 return ACC_bottom;
3679
3680
3681 if (!fn->hasAttr())
3682 return ACC_invalid;
3683
3684
3686 return Diagnose ? ACC_plusOne
3687 : ACC_invalid;
3688
3689 return ACC_plusZero;
3690 }
3691
3692 ACCResult VisitObjCMessageExpr(ObjCMessageExpr *e) {
3694 }
3695
3696 ACCResult VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *e) {
3697 ObjCMethodDecl *method;
3700 else
3702 return checkCallToMethod(method);
3703 }
3704
3705 ACCResult checkCallToMethod(ObjCMethodDecl *method) {
3706 if (!method) return ACC_invalid;
3707
3708
3709
3710
3712 return ACC_invalid;
3713
3714
3715 if (method->hasAttr())
3716 return ACC_plusZero;
3717
3718
3719
3720 if (method->hasAttr())
3721 return ACC_plusOne;
3722
3728 return ACC_plusOne;
3729
3730 default:
3731
3732 return ACC_plusZero;
3733 }
3734 }
3735 };
3736}
3737
3740 if (name.empty())
3741 return false;
3744 return SemaRef.LookupName(R, SemaRef.TUScope, false);
3745}
3746
3747template
3751 Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName) {
3752
3753 switch (CCK) {
3758 break;
3760 return;
3761 }
3762
3763 if (CFBridgeName) {
3765 if (const CXXNamedCastExpr *NCE = dyn_cast(realCast)) {
3766 SourceRange range(NCE->getOperatorLoc(),
3767 NCE->getAngleBrackets().getEnd());
3769
3771 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3773 BridgeCall += ' ';
3774
3775 BridgeCall += CFBridgeName;
3777 }
3778 return;
3779 }
3781 if (CStyleCastExpr *CCE = dyn_cast(castedE))
3782 castedE = CCE->getSubExpr();
3785
3787
3789 char PrevChar = *SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
3791 BridgeCall += ' ';
3792
3793 BridgeCall += CFBridgeName;
3794
3797 BridgeCall));
3798 } else {
3799 BridgeCall += '(';
3801 BridgeCall));
3804 ")"));
3805 }
3806 return;
3807 }
3808
3812 if (const CXXNamedCastExpr *NCE = dyn_cast(realCast)) {
3813 std::string castCode = "(";
3814 castCode += bridgeKeyword;
3816 castCode += ")";
3817 SourceRange Range(NCE->getOperatorLoc(),
3818 NCE->getAngleBrackets().getEnd());
3820 }
3821 } else {
3822 std::string castCode = "(";
3823 castCode += bridgeKeyword;
3825 castCode += ")";
3830 castCode));
3831 } else {
3832 castCode += "(";
3834 castCode));
3837 ")"));
3838 }
3839 }
3840}
3841
3842template
3848 if (const RecordType *RT = QT->getAsCanonical()) {
3849 for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
3850 if (auto *attr = Redecl->getAttr<T>())
3851 return attr;
3852 }
3853 }
3854 }
3855 return nullptr;
3856}
3857
3860 while (const auto *TD = T->getAs<TypedefType>()) {
3861 TDNDecl = TD->getDecl();
3862 if (ObjCBridgeRelatedAttr *ObjCBAttr =
3864 return ObjCBAttr;
3866 }
3867 return nullptr;
3868}
3869
3878
3880 UnavailableAttr::IR_ARCForbiddenConversion))
3881 return;
3882
3884
3885
3891 return;
3892
3893 unsigned srcKind = 0;
3894 switch (exprACTC) {
3898 srcKind = (castExprType->isPointerType() ? 1 : 0);
3899 break;
3902 break;
3904 srcKind = 4;
3905 break;
3906 }
3907
3908
3911
3912 unsigned convKindForDiag = Sema::isCast(CCK) ? 0 : 1;
3913
3914
3916
3917 S.Diag(loc, diag::err_arc_cast_requires_bridge)
3918 << convKindForDiag
3919 << 2
3920 << castExprType
3922 << castType
3923 << castRange
3924 << castExpr->getSourceRange();
3926 ACCResult CreateRule =
3927 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
3928 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
3929 if (CreateRule != ACC_plusOne)
3930 {
3932 ? S.Diag(noteLoc, diag::note_arc_bridge)
3933 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
3934
3936 castType, castExpr, realCast, "__bridge ",
3937 nullptr);
3938 }
3939 if (CreateRule != ACC_plusZero)
3940 {
3942 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_transfer)
3943 << castExprType
3944 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
3945 diag::note_arc_bridge_transfer)
3946 << castExprType << br;
3947
3949 castType, castExpr, realCast, "__bridge_transfer ",
3950 br ? "CFBridgingRelease" : nullptr);
3951 }
3952
3953 return;
3954 }
3955
3956
3959 S.Diag(loc, diag::err_arc_cast_requires_bridge)
3960 << convKindForDiag
3962 << castExprType
3963 << 2
3964 << castType
3965 << castRange
3966 << castExpr->getSourceRange();
3967 ACCResult CreateRule =
3968 ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
3969 assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
3970 if (CreateRule != ACC_plusOne)
3971 {
3973 ? S.Diag(noteLoc, diag::note_arc_bridge)
3974 : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
3976 castType, castExpr, realCast, "__bridge ",
3977 nullptr);
3978 }
3979 if (CreateRule != ACC_plusZero)
3980 {
3982 ? S.Diag(noteLoc, diag::note_arc_cstyle_bridge_retained)
3983 << castType
3984 : S.Diag(br ? castExpr->getExprLoc() : noteLoc,
3985 diag::note_arc_bridge_retained)
3986 << castType << br;
3987
3989 castType, castExpr, realCast, "__bridge_retained ",
3990 br ? "CFBridgingRetain" : nullptr);
3991 }
3992
3993 return;
3994 }
3995
3996 S.Diag(loc, diag::err_arc_mismatched_cast)
3997 << !convKindForDiag
3998 << srcKind << castExprType << castType
3999 << castRange << castExpr->getSourceRange();
4000}
4001
4002template
4004 bool &HadTheAttribute, bool warn) {
4006 HadTheAttribute = false;
4007 while (const auto *TD = T->getAs<TypedefType>()) {
4010 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4011 HadTheAttribute = true;
4012 if (Parm->isStr("id"))
4013 return true;
4014
4015
4025 = InterfacePointerType->getObjectType()->getInterface();
4026 if ((CastClass == ExprClass) ||
4027 (CastClass && CastClass->isSuperClassOf(ExprClass)))
4028 return true;
4029 if (warn)
4030 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4032 return false;
4035 castType, ExprClass)))
4036
4037
4038
4039 return true;
4040 else {
4041 if (warn) {
4042 S.Diag(castExpr->getBeginLoc(), diag::warn_objc_invalid_bridge)
4043 << T << Target->getName() << castType;
4045 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4046 }
4047 return false;
4048 }
4049 }
4052 diag::err_objc_cf_bridged_not_interface)
4053 << castExpr->getType() << Parm;
4055 }
4056 return true;
4057 }
4058 return false;
4059 }
4061 }
4062 return true;
4063}
4064
4065template
4067 bool &HadTheAttribute, bool warn) {
4069 HadTheAttribute = false;
4070 while (const auto *TD = T->getAs<TypedefType>()) {
4073 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4074 HadTheAttribute = true;
4075 if (Parm->isStr("id"))
4076 return true;
4077
4079
4087 castExpr->getType()->getAsObjCInterfacePointerType()) {
4089 = InterfacePointerType->getObjectType()->getInterface();
4090 if ((CastClass == ExprClass) ||
4091 (ExprClass && CastClass->isSuperClassOf(ExprClass)))
4092 return true;
4093 if (warn) {
4095 diag::warn_objc_invalid_bridge_to_cf)
4096 << castExpr->getType()->getPointeeType() << T;
4098 }
4099 return false;
4100 } else if (castExpr->getType()->isObjCIdType() ||
4102 castExpr->getType(), CastClass)))
4103
4104
4105
4106 return true;
4107 else {
4108 if (warn) {
4110 diag::warn_objc_invalid_bridge_to_cf)
4111 << castExpr->getType() << castType;
4113 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4114 }
4115 return false;
4116 }
4117 }
4118 }
4120 diag::err_objc_ns_bridged_invalid_cfobject)
4121 << castExpr->getType() << castType;
4124 S.Diag(Target->getBeginLoc(), diag::note_declared_at);
4125 return true;
4126 }
4127 return false;
4128 }
4130 }
4131 return true;
4132}
4133
4136 return;
4137
4141 bool HasObjCBridgeAttr;
4144 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4145 return;
4146 bool HasObjCBridgeMutableAttr;
4147 bool ObjCBridgeMutableAttrWillNotWarn =
4149 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);
4150 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4151 return;
4152
4153 if (HasObjCBridgeAttr)
4155 HasObjCBridgeAttr, true);
4156 else if (HasObjCBridgeMutableAttr)
4158 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);
4159 }
4161 bool HasObjCBridgeAttr;
4164 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4165 return;
4166 bool HasObjCBridgeMutableAttr;
4167 bool ObjCBridgeMutableAttrWillNotWarn =
4169 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);
4170 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4171 return;
4172
4173 if (HasObjCBridgeAttr)
4175 HasObjCBridgeAttr, true);
4176 else if (HasObjCBridgeMutableAttr)
4178 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);
4179 }
4180}
4181
4185 if (PRE->isExplicitProperty()) {
4187 SrcType = PDecl->getType();
4188 }
4189 else if (PRE->isImplicitProperty()) {
4190 if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())
4191 SrcType = Getter->getReturnType();
4192 }
4193 }
4194
4198 return;
4201}
4202
4206 return false;
4214 : CK_CPointerToObjCPointerCast;
4215 return true;
4216 }
4217 return false;
4218}
4219
4224 bool Diagnose) {
4226 QualType T = CfToNs ? SrcType : DestType;
4228 if (!ObjCBAttr)
4229 return false;
4230
4231 IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();
4233 IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();
4234 if (!RCId)
4235 return false;
4237
4241 if (Diagnose) {
4242 Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
4243 << SrcType << DestType;
4245 }
4246 return false;
4247 }
4251 else {
4252 if (Diagnose) {
4253 Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
4254 << SrcType << DestType;
4257 Diag(Target->getBeginLoc(), diag::note_declared_at);
4258 }
4259 return false;
4260 }
4261
4262
4263 if (CfToNs && CMId) {
4264 Selector Sel = Context.Selectors.getUnarySelector(CMId);
4265 ClassMethod = RelatedClass->lookupMethod(Sel, false);
4266 if (!ClassMethod) {
4267 if (Diagnose) {
4268 Diag(Loc, diag::err_objc_bridged_related_known_method)
4269 << SrcType << DestType << Sel << false;
4271 }
4272 return false;
4273 }
4274 }
4275
4276
4277 if (!CfToNs && IMId) {
4278 Selector Sel = Context.Selectors.getNullarySelector(IMId);
4279 InstanceMethod = RelatedClass->lookupMethod(Sel, true);
4280 if (!InstanceMethod) {
4281 if (Diagnose) {
4282 Diag(Loc, diag::err_objc_bridged_related_known_method)
4283 << SrcType << DestType << Sel << true;
4285 }
4286 return false;
4287 }
4288 }
4289 return true;
4290}
4291
4295 Expr *&SrcExpr,
4296 bool Diagnose) {
4302 if (!CfToNs && !NsToCf)
4303 return false;
4304
4310 ClassMethod, InstanceMethod, TDNDecl,
4311 CfToNs, Diagnose))
4312 return false;
4313
4314 if (CfToNs) {
4315
4316 if (ClassMethod) {
4317 if (Diagnose) {
4318 std::string ExpressionString = "[";
4320 ExpressionString += " ";
4321 ExpressionString += ClassMethod->getSelector().getAsString();
4324
4325 Diag(Loc, diag::err_objc_bridged_related_known_method)
4326 << SrcType << DestType << ClassMethod->getSelector() << false
4328 ExpressionString)
4330 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4332
4333 QualType receiverType = Context.getObjCInterfaceType(RelatedClass);
4334
4335 Expr *args[] = { SrcExpr };
4337 ClassMethod->getLocation(),
4338 ClassMethod->getSelector(), ClassMethod,
4340 SrcExpr = msg.get();
4341 }
4342 return true;
4343 }
4344 }
4345 else {
4346
4347 if (InstanceMethod) {
4348 if (Diagnose) {
4349 std::string ExpressionString;
4352 if (InstanceMethod->isPropertyAccessor())
4354 InstanceMethod->findPropertyDecl()) {
4355
4356 ExpressionString = ".";
4357 ExpressionString += PDecl->getNameAsString();
4358 Diag(Loc, diag::err_objc_bridged_related_known_method)
4359 << SrcType << DestType << InstanceMethod->getSelector() << true
4361 }
4362 if (ExpressionString.empty()) {
4363
4364 ExpressionString = " ";
4365 ExpressionString += InstanceMethod->getSelector().getAsString();
4366 ExpressionString += "]";
4367
4368 Diag(Loc, diag::err_objc_bridged_related_known_method)
4369 << SrcType << DestType << InstanceMethod->getSelector() << true
4372 }
4373 Diag(RelatedClass->getBeginLoc(), diag::note_declared_at);
4375
4377 SrcExpr, SrcType, InstanceMethod->getLocation(),
4378 InstanceMethod->getSelector(), InstanceMethod, {});
4379 SrcExpr = msg.get();
4380 }
4381 return true;
4382 }
4383 }
4384 return false;
4385}
4386
4390 bool Diagnose, bool DiagnoseCFAudited,
4394
4395
4396
4397 QualType effCastType = castType;
4400
4403 if (exprACTC == castACTC) {
4404
4405
4409 castType != castExprType) {
4412
4413
4414
4415 if (const ParenType *PT = dyn_cast(DT))
4416 QDT = PT->desugar();
4417 else if (const TypeOfType *TP = dyn_cast(DT))
4418 QDT = TP->desugar();
4419 else if (const AttributedType *AT = dyn_cast(DT))
4420 QDT = AT->desugar();
4421 if (QDT != castType &&
4423 if (Diagnose) {
4426 Diag(loc, diag::err_arc_nolifetime_behavior);
4427 }
4429 }
4430 }
4432 }
4433
4434
4435
4438
4440
4441
4442
4445
4446
4447
4448
4449
4450
4451
4452
4463
4464 switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
4465
4466 case ACC_invalid:
4467 break;
4468
4469
4470 case ACC_bottom:
4471 case ACC_plusZero:
4473
4474
4475 case ACC_plusOne:
4477 CK_ARCConsumeObject, castExpr, nullptr,
4479 SemaRef.Cleanup.setExprNeedsCleanups(true);
4481 }
4482
4483
4484
4485
4489
4490
4491
4492
4496
4497
4498
4499
4500
4501 if ((!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
4504 (Opc == BO_NE || Opc == BO_EQ))) {
4505 if (Diagnose)
4509 }
4511}
4512
4513
4514
4516
4519
4523
4526 castType = cast->getTypeAsWritten();
4529 castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4530 castType = cast->getTypeAsWritten();
4532 } else {
4533 llvm_unreachable("Unexpected ImplicitCastExpr");
4534 }
4535
4538
4541
4544}
4545
4546
4547
4551
4552 if (ParenExpr *pe = dyn_cast(e)) {
4554 return new (Context) ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4555 } else if (UnaryOperator *uo = dyn_cast(e)) {
4556 assert(uo->getOpcode() == UO_Extension);
4560 uo->getOperatorLoc(), false,
4561 SemaRef.CurFPFeatureOverrides());
4563 assert(!gse->isResultDependent());
4564 assert(!gse->isTypePredicate());
4565
4566 unsigned n = gse->getNumAssocs();
4569 subExprs.reserve(n);
4570 subTypes.reserve(n);
4572 subTypes.push_back(assoc.getTypeSourceInfo());
4573 Expr *sub = assoc.getAssociationExpr();
4574 if (assoc.isSelected())
4576 subExprs.push_back(sub);
4577 }
4578
4580 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4581 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4582 gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4583 } else {
4586 }
4587}
4588
4602 return !ObjI->isArcWeakrefUnavailable();
4603 }
4604 return true;
4605}
4606
4607
4609 Expr *curExpr = e, *prevExpr = nullptr;
4610
4611
4612
4613 while (true) {
4614 if (auto *pe = dyn_cast(curExpr)) {
4615 prevExpr = curExpr;
4616 curExpr = pe->getSubExpr();
4617 continue;
4618 }
4619
4620 if (auto *ce = dyn_cast(curExpr)) {
4621 if (auto *ice = dyn_cast(ce))
4622 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4623 if (!prevExpr)
4624 return ice->getSubExpr();
4625 if (auto *pe = dyn_cast(prevExpr))
4626 pe->setSubExpr(ice->getSubExpr());
4627 else
4628 cast(prevExpr)->setSubExpr(ice->getSubExpr());
4629 return e;
4630 }
4631
4632 prevExpr = curExpr;
4633 curExpr = ce->getSubExpr();
4634 continue;
4635 }
4636
4637
4638 break;
4639 }
4640
4641 return e;
4642}
4643
4648 Expr *SubExpr) {
4652 SubExpr = SubResult.get();
4653
4656
4658
4659 bool MustConsume = false;
4661
4662 CK = CK_Dependent;
4663 } else if (T->isObjCARCBridgableType() && FromType->isCARCBridgableType()) {
4664
4665 CK = (T->isBlockPointerType() ? CK_AnyPointerToBlockPointerCast
4666 : CK_CPointerToObjCPointerCast);
4667 switch (Kind) {
4669 break;
4670
4672 bool br = isKnownName("CFBridgingRelease");
4673 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4674 << 2
4675 << FromType
4676 << (T->isBlockPointerType()? 1 : 0)
4677 << T
4679 << Kind;
4680 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4682 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4683 << FromType << br
4685 br ? "CFBridgingRelease "
4686 : "__bridge_transfer ");
4687
4689 break;
4690 }
4691
4693
4694 MustConsume = true;
4695 break;
4696 }
4698
4699 CK = CK_BitCast;
4700 switch (Kind) {
4702
4703
4705 break;
4706
4708
4712 break;
4713
4715 bool br = isKnownName("CFBridgingRetain");
4716 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4718 << FromType
4719 << 2
4720 << T
4722 << Kind;
4723
4724 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4726 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4727 << T << br
4729 br ? "CFBridgingRetain " : "__bridge_retained");
4730
4732 break;
4733 }
4734 }
4735 } else {
4736 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4737 << FromType << T << Kind
4741 }
4742
4744 BridgeKeywordLoc,
4745 TSInfo, SubExpr);
4746
4747 if (MustConsume) {
4748 SemaRef.Cleanup.setExprNeedsCleanups(true);
4751 }
4752
4754}
4755
4761 Expr *SubExpr) {
4767 if (!TSInfo)
4768 TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);
4770 SubExpr);
4771}
4772
4777
4778
4779 if (!CurMethod)
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791 bool IsClassMethod = CurMethod->isClassMethod();
4792
4793 bool LookForIvars;
4794 if (Lookup.empty())
4795 LookForIvars = true;
4796 else if (IsClassMethod)
4797 LookForIvars = false;
4798 else
4802 if (LookForIvars) {
4807
4808 if (IsClassMethod) {
4809 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
4811 }
4812
4813
4817 Diag(Loc, diag::err_private_ivar_access) << IV->getDeclName();
4818
4819
4820 return IV;
4821 }
4823
4829 Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
4830 }
4831 }
4834
4836 dyn_cast(Lookup.getFoundDecl())) {
4837 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
4839 }
4840 }
4841
4842
4844}
4845
4848 bool AllowBuiltinCreation) {
4849
4856
4857 if (Lookup.empty() && II && AllowBuiltinCreation)
4858 SemaRef.LookupBuiltin(Lookup);
4859
4860
4862}
4863
4869 "should not reference ivar from this context");
4870
4872 assert(IFace && "should not reference ivar from this context");
4873
4874
4875
4878
4879
4880 if (SemaRef.DiagnoseUseOfDecl(IV, Loc))
4882
4883
4884
4891 SemaRef.ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,
4892 false,
4893 false);
4896
4897 SelfExpr = SemaRef.DefaultLvalueConversion(SelfExpr.get());
4900
4901 SemaRef.MarkAnyDeclReferenced(Loc, IV, true);
4902
4906 Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName();
4907
4911
4913 if (.isUnevaluatedContext() &&
4914 ().isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
4915 SemaRef.getCurFunction()->recordUseOfWeak(Result);
4916 }
4917 if (getLangOpts().ObjCAutoRefCount && .isUnevaluatedContext())
4918 if (const BlockDecl *BD = SemaRef.CurContext->getInnermostBlockDecl())
4919 SemaRef.ImplicitlyRetainedSelfLocs.push_back({Loc, BD});
4920
4922}
4923
4930
4931
4932
4933
4935 (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
4936 RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,
4937 CK_CPointerToObjCPointerCast);
4938 return LHSTy;
4939 }
4941 (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
4942 LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,
4943 CK_CPointerToObjCPointerCast);
4944 return RHSTy;
4945 }
4946
4948 (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
4949 RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy,
4950 CK_CPointerToObjCPointerCast);
4951 return LHSTy;
4952 }
4954 (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
4955 LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy,
4956 CK_CPointerToObjCPointerCast);
4957 return RHSTy;
4958 }
4959
4960 if (Context.isObjCSelType(LHSTy) &&
4961 (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
4962 RHS = SemaRef.ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast);
4963 return LHSTy;
4964 }
4965 if (Context.isObjCSelType(RHSTy) &&
4966 (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
4967 LHS = SemaRef.ImpCastExprToType(LHS.get(), RHSTy, CK_BitCast);
4968 return RHSTy;
4969 }
4970
4972
4973 if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
4974
4975 return LHSTy;
4976 }
4981 QualType compositeType = LHSTy;
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996 if (!(compositeType = Context.areCommonBaseCompatible(LHSOPT, RHSOPT))
4997 .isNull()) {
4998
4999 } else if (Context.canAssignObjCInterfaces(LHSOPT, RHSOPT)) {
5000 compositeType = RHSOPT->isObjCBuiltinType() ? RHSTy : LHSTy;
5001 } else if (Context.canAssignObjCInterfaces(RHSOPT, LHSOPT)) {
5004 RHSOPT->isObjCQualifiedIdType()) &&
5005 Context.ObjCQualifiedIdTypesAreCompatible(LHSOPT, RHSOPT,
5006 true)) {
5007
5008
5009
5010
5011 compositeType = Context.getObjCIdType();
5013 compositeType = Context.getObjCIdType();
5014 } else {
5015 Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
5018 QualType incompatTy = Context.getObjCIdType();
5019 LHS = SemaRef.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
5020 RHS = SemaRef.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
5021 return incompatTy;
5022 }
5023
5024 LHS = SemaRef.ImpCastExprToType(LHS.get(), compositeType, CK_BitCast);
5025 RHS = SemaRef.ImpCastExprToType(RHS.get(), compositeType, CK_BitCast);
5026 return compositeType;
5027 }
5028
5031
5032
5033 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5036 LHS = RHS = true;
5038 }
5042 Context.getQualifiedType(lhptee, rhptee.getQualifiers());
5043 QualType destType = Context.getPointerType(destPointee);
5044
5045 LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_NoOp);
5046
5047 RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_BitCast);
5048 return destType;
5049 }
5052
5053
5054 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5057 LHS = RHS = true;
5059 }
5063 Context.getQualifiedType(rhptee, lhptee.getQualifiers());
5064 QualType destType = Context.getPointerType(destPointee);
5065
5066 RHS = SemaRef.ImpCastExprToType(RHS.get(), destType, CK_NoOp);
5067
5068 LHS = SemaRef.ImpCastExprToType(LHS.get(), destType, CK_BitCast);
5069 return destType;
5070 }
5072}
5073
5075 bool Diagnose) {
5077 return false;
5078
5080 if (!PT)
5081 return false;
5083
5084
5085
5086
5088 if (OpaqueValueExpr *OV = dyn_cast(SrcExpr))
5089 if (OV->getSourceExpr())
5091
5092 if (auto *SL = dyn_cast(SrcExpr)) {
5093 if (!PT->isObjCIdType() && !(ID && ID->getIdentifier()->isStr("NSString")))
5094 return false;
5095 if (!SL->isOrdinary())
5096 return false;
5097
5098 if (Diagnose) {
5099 Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)
5102 }
5103 return true;
5104 }
5105
5111 if (!ID || !ID->getIdentifier()->isStr("NSNumber"))
5112 return false;
5113 if (Diagnose) {
5114 Diag(SrcExpr->getBeginLoc(), diag::err_missing_atsign_prefix)
5115 << 1
5117 Expr *NumLit =
5119 if (NumLit)
5120 Exp = NumLit;
5121 }
5122 return true;
5123 }
5124
5125 return false;
5126}
5127
5128
5131 assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&
5132 "Unknown Objective-C Boolean value!");
5134 QualType BoolT = Context.ObjCBuiltinBoolTy;
5135 if (!Context.getBOOLDecl()) {
5139 Result.isSingleResult()) {
5141 if (TypedefDecl *TD = dyn_cast(ND))
5142 Context.setBOOLDecl(TD);
5143 }
5144 }
5145 if (Context.getBOOLDecl())
5146 BoolT = Context.getBOOLType();
5147 return new (Context)
5149}
5150
5155 auto FindSpecVersion =
5156 [&](StringRef Platform,
5157 const llvm::Triple::OSType &OS) -> std::optional {
5158 auto Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
5160 });
5161
5162
5163 if (Spec == AvailSpecs.end() && Platform == "maccatalyst") {
5164 Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
5166 });
5167 }
5168 if (Spec == AvailSpecs.end())
5169 return std::nullopt;
5170
5171 return llvm::Triple::getCanonicalVersionForOS(
5173 llvm::Triple::isValidVersionForOS(OS, Spec->getVersion()));
5174 };
5175
5176 VersionTuple Version;
5177 if (auto MaybeVersion =
5178 FindSpecVersion(Context.getTargetInfo().getPlatformName(),
5179 Context.getTargetInfo().getTriple().getOS()))
5180 Version = *MaybeVersion;
5181
5182
5183
5185 Context->HasPotentialAvailabilityViolations = true;
5186
5187 return new (Context)
5189}
5190
5191
5192
5195 if (type->isObjCObjectPointerType()) {
5196 return CK_BitCast;
5197 } else if (type->isBlockPointerType()) {
5198 SemaRef.maybeExtendBlockObject(E);
5199 return CK_BlockPointerToObjCPointerCast;
5200 } else {
5201 assert(type->isPointerType());
5202 return CK_CPointerToObjCPointerCast;
5203 }
5204}
5205
5209 default:
5210 break;
5211 case Stmt::ObjCStringLiteralClass:
5212
5214 case Stmt::ObjCArrayLiteralClass:
5215
5217 case Stmt::ObjCDictionaryLiteralClass:
5218
5220 case Stmt::BlockExprClass:
5222 case Stmt::ObjCBoxedExprClass: {
5225 case Stmt::IntegerLiteralClass:
5226 case Stmt::FloatingLiteralClass:
5227 case Stmt::CharacterLiteralClass:
5228 case Stmt::ObjCBoolLiteralExprClass:
5229 case Stmt::CXXBoolLiteralExprClass:
5230
5232 case Stmt::ImplicitCastExprClass: {
5234
5235 if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast)
5237 break;
5238 }
5239 default:
5240 break;
5241 }
5243 }
5244 }
5246}
Defines the clang::ASTContext interface.
static StringRef bytes(const std::vector< T, Allocator > &v)
Defines enum values for all the target-independent builtin functions.
llvm::MachO::Target Target
Defines the clang::Preprocessor interface.
static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)
Definition SemaExprObjC.cpp:4003
static ObjCMethodDecl * getNSNumberFactoryMethod(SemaObjC &S, SourceLocation Loc, QualType NumberType, bool isLiteral=false, SourceRange R=SourceRange())
Retrieve the NSNumber factory method that should be used to create an Objective-C literal for the giv...
Definition SemaExprObjC.cpp:247
static QualType stripObjCInstanceType(ASTContext &Context, QualType T)
Definition SemaExprObjC.cpp:1436
static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange, QualType castType, ARCConversionTypeClass castACTC, Expr *castExpr, Expr *realCast, ARCConversionTypeClass exprACTC, CheckedConversionKind CCK)
Definition SemaExprObjC.cpp:3870
static ObjCInterfaceDecl * LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)
Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
Definition SemaExprObjC.cpp:224
static ObjCMethodDecl * findMethodInCurrentClass(Sema &S, Selector Sel)
Definition SemaExprObjC.cpp:1274
static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg)
Definition SemaExprObjC.cpp:2488
static ObjCMethodDecl * LookupDirectMethodInGlobalPool(Sema &S, Selector Sel, bool &onlyDirect, bool &anyDirect)
Definition SemaExprObjC.cpp:1259
static Expr * maybeUndoReclaimObject(Expr *e)
Look for an ObjCReclaimReturnedObject cast and destroy it.
Definition SemaExprObjC.cpp:4608
static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)
Definition SemaExprObjC.cpp:4066
static void CheckObjCDictionaryLiteralDuplicateKeys(Sema &S, ObjCDictionaryLiteral *Literal)
Check for duplicate keys in an ObjC dictionary literal.
Definition SemaExprObjC.cpp:901
static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)
Validates ObjCInterfaceDecl availability.
Definition SemaExprObjC.cpp:201
static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind)
Maps ObjCLiteralKind to NSClassIdKindKind.
Definition SemaExprObjC.cpp:175
static bool isAnyCLike(ARCConversionTypeClass ACTC)
Definition SemaExprObjC.cpp:3465
static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc, ObjCMethodDecl *Method, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
Definition SemaExprObjC.cpp:1207
static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S, SourceLocation AtLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, ObjCMethodDecl *Method, ObjCMethodList &MethList)
Definition SemaExprObjC.cpp:1176
static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg, unsigned DiagID, bool(*refactor)(const ObjCMessageExpr *, const NSAPI &, edit::Commit &))
Definition SemaExprObjC.cpp:2449
static ObjCMethodDecl * LookupDirectMethodInMethodList(Sema &S, Selector Sel, ObjCMethodList &MethList, bool &onlyDirect, bool &anyDirect)
Definition SemaExprObjC.cpp:1233
static ObjCBridgeRelatedAttr * ObjCBridgeRelatedAttrFromType(QualType T, TypedefNameDecl *&TDNDecl)
Definition SemaExprObjC.cpp:3858
static T * getObjCBridgeAttr(const TypedefType *TD)
Definition SemaExprObjC.cpp:3843
static ARCConversionTypeClass classifyTypeForARCConversion(QualType type)
Definition SemaExprObjC.cpp:3471
static bool isAnyRetainable(ARCConversionTypeClass ACTC)
Definition SemaExprObjC.cpp:3459
static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg)
Definition SemaExprObjC.cpp:3398
ARCConversionTypeClass
Definition SemaExprObjC.cpp:3442
@ ACTC_voidPtr
void* might be a normal C type, or it might a CF type.
Definition SemaExprObjC.cpp:3453
@ ACTC_retainable
id, void (^)()
Definition SemaExprObjC.cpp:3447
@ ACTC_coreFoundation
struct A*
Definition SemaExprObjC.cpp:3456
@ ACTC_indirectRetainable
id*, id***, void (^*)(),
Definition SemaExprObjC.cpp:3450
@ ACTC_none
int, void, struct A
Definition SemaExprObjC.cpp:3444
static QualType getBaseMessageSendResultType(Sema &S, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)
Determine the result type of a message send based on the receiver type, method, and the kind of messa...
Definition SemaExprObjC.cpp:1458
static const ObjCMethodDecl * findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD, QualType instancetype)
Look for an ObjC method whose result type exactly matches the given type.
Definition SemaExprObjC.cpp:1621
static void DiagnoseCStringFormatDirectiveInObjCAPI(Sema &S, ObjCMethodDecl *Method, Selector Sel, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
Definition SemaExprObjC.cpp:2542
static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M)
Definition SemaExprObjC.cpp:2784
static bool validateBoxingMethod(Sema &S, SourceLocation Loc, const ObjCInterfaceDecl *Class, Selector Sel, const ObjCMethodDecl *Method)
Emits an error if the given method does not exist, or if the return type is not an Objective-C object...
Definition SemaExprObjC.cpp:151
static void checkFoundationAPI(Sema &S, SourceLocation Loc, const ObjCMethodDecl *Method, ArrayRef< Expr * > Args, QualType ReceiverType, bool IsClassObjectCall)
Definition SemaExprObjC.cpp:2493
static void addFixitForObjCARCConversion(Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK, SourceLocation afterLParen, QualType castType, Expr *castExpr, Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName)
Definition SemaExprObjC.cpp:3748
static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element, QualType T, bool ArrayLiteral=false)
Check that the given expression is a valid element of an Objective-C collection literal.
Definition SemaExprObjC.cpp:391
This file declares semantic analysis for Objective-C.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TypeLoc interface and its subclasses.
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT, ObjCInterfaceDecl *IDecl)
QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in QT's qualified-id protocol list adopt...
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl)
ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's protocol list adopt all protocols in Q...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
One specifier in an @available expression.
StringRef getPlatform() const
VersionTuple getVersion() const
Represents a block literal declaration, which is like an unnamed FunctionDecl.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Abstract class common to all of the C++ "named"/"keyword" casts.
Represents a C++ nested-name-specifier or a global scope specifier.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
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...
Simple template class for restricting typo correction candidates to ones having a single Decl* of the...
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
bool isInvalidDecl() const
SourceLocation getLocation() const
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
TranslationUnitDecl * getTranslationUnitDecl()
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
bool isIdentifier() const
Predicate functions for querying what type of name this is.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool isObjCSelfExpr() const
Check if this expression is the ObjC 'self' implicit parameter.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_NeverValueDependent
Specifies that the expression should never be value-dependent.
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Represents difference between two FPOptions values.
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
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.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
QualType getReturnType() const
Represents a C11 generic selection.
AssociationTy< false > Association
static GenericSelectionExpr * Create(const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr, ArrayRef< TypeSourceInfo * > AssocTypes, ArrayRef< Expr * > AssocExprs, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
Create a non-result-dependent generic selection expression accepting an expression predicate.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy 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 InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static bool isAsciiIdentifierContinueChar(char c, const LangOptions &LangOpts)
Returns true if the given character could appear in an identifier.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
SourceLocation getNameLoc() const
Gets the location of the identifier.
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.
@ NSDict_dictionaryWithObjectsForKeysCount
@ NSArr_arrayWithObjectsCount
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
static ObjCArrayLiteral * Create(const ASTContext &C, ArrayRef< Expr * > Elements, QualType T, ObjCMethodDecl *Method, SourceRange SR)
A runtime availability query.
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
ObjCBoxedExpr - used for generalized expression boxing.
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCContainerDecl - Represents a container for method declarations.
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
static ObjCDictionaryLiteral * Create(const ASTContext &C, ArrayRef< ObjCDictionaryElement > VK, bool HasPackExpansions, QualType T, ObjCMethodDecl *method, SourceRange SR)
ObjCEncodeExpr, used for @encode in Objective-C.
Represents an ObjC class declaration.
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
static ObjCInterfaceDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc=SourceLocation(), bool isInternal=false)
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
ObjCMethodDecl * lookupPrivateClassMethod(const Selector &Sel)
ObjCMethodDecl * getCategoryClassMethod(Selector Sel) const
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
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,...
ObjCInterfaceDecl * getSuperClass() const
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
AccessControl getAccessControl() const
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
static ObjCMessageExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ArrayRef< SourceLocation > SelLocs, ObjCMethodDecl *Method, ArrayRef< Expr * > Args, SourceLocation RBracLoc, bool isImplicit)
Create a message send to super.
Selector getSelector() const
const ObjCMethodDecl * getMethodDecl() const
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
bool isPropertyAccessor() const
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl, bool isInstance=true, bool isVariadic=false, bool isPropertyAccessor=false, bool isSynthesizedAccessorStub=false, bool isImplicitlyDeclared=false, bool isDefined=false, ObjCImplementationControl impControl=ObjCImplementationControl::None, bool HasRelatedResultType=false)
const ObjCPropertyDecl * findPropertyDecl(bool CheckOverrides=true) const
Returns the property associated with this method's selector.
void setMethodParams(ASTContext &C, ArrayRef< ParmVarDecl * > Params, ArrayRef< SourceLocation > SelLocs={})
Sets the method's parameters and selector source locations.
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
bool isInstanceMethod() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
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.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
ObjCInterfaceDecl * getInterfaceDecl() const
If this pointer points to an Objective @interface type, gets the declaration for that interface.
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.
ObjCMethodDecl * getGetterMethodDecl() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
ObjCMethodDecl * getImplicitPropertyGetter() const
bool isExplicitProperty() const
Represents an Objective-C protocol declaration.
bool hasDefinition() const
Determine whether this protocol has a definition.
ObjCProtocolDecl * getDefinition()
Retrieve the definition of this protocol, if any.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
ObjCProtocolExpr used for protocol expression in Objective-C.
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parenthesized expression, e.g.
Sugar for parentheses used when specifying types.
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
QualType withConst() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
QualType substObjCTypeArgs(ASTContext &ctx, ArrayRef< QualType > typeArgs, ObjCSubstitutionContext context) const
Substitute type arguments for the Objective-C type parameters used in the subject type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isInObjcMethodScope() const
isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool isUnarySelector() const
ObjCStringFormatFamily getStringFormatFamily() const
unsigned getNumArgs() const
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.
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
Definition SemaExprObjC.cpp:2284
ObjCMethodDecl * ValueWithBytesObjCTypeMethod
The declaration of the valueWithBytes:objCType: method.
ExprResult BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)
Definition SemaExprObjC.cpp:954
ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, bool Super)
HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an objective C interface.
Definition SemaExprObjC.cpp:1975
ExprResult BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C instance message expression.
Definition SemaExprObjC.cpp:2831
const ObjCMethodDecl * SelectorsForTypoCorrection(Selector Sel, QualType ObjectType=QualType())
ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
ParseObjCSelectorExpression - Build selector expression for @selector.
Definition SemaExprObjC.cpp:1295
ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C class message expression.
Definition SemaExprObjC.cpp:2606
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)
BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the numeric literal expression.
Definition SemaExprObjC.cpp:320
bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, SourceRange R, bool receiverIdOrClass, SmallVectorImpl< ObjCMethodDecl * > &Methods)
ObjCMethodDecl * LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupInstanceMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
ExprResult ActOnObjCBridgedCast(Scope *S, SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, ParsedType Type, SourceLocation RParenLoc, Expr *SubExpr)
Definition SemaExprObjC.cpp:4756
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
Definition SemaExprObjC.cpp:5206
ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc)
Definition SemaExprObjC.cpp:1129
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, QualType SrcType, Expr *&SrcExpr, bool Diagnose=true)
Definition SemaExprObjC.cpp:4292
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
Definition SemaExprObjC.cpp:794
ObjCInterfaceDecl * NSArrayDecl
The declaration of the Objective-C NSArray class.
ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)
Definition SemaExprObjC.cpp:2158
void CheckObjCCircularContainer(ObjCMessageExpr *Message)
Check whether receiver is mutable ObjC container which attempts to add itself into the container.
ObjCInterfaceDecl * getObjCInterfaceDecl(const IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection=false)
Look for an Objective-C class in the translation unit.
ObjCMethodDecl * LookupMethodInObjectType(Selector Sel, QualType Ty, bool IsInstance)
LookupMethodInType - Look up a method in an ObjCObjectType.
Definition SemaExprObjC.cpp:1938
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
ExprResult BuildClassMessageImplicit(QualType ReceiverType, bool isSuperReceiver, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
Definition SemaExprObjC.cpp:2430
ObjCInterfaceDecl * NSNumberDecl
The declaration of the Objective-C NSNumber class.
void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr)
Definition SemaExprObjC.cpp:4182
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.
Definition SemaExprObjC.cpp:507
ObjCInterfaceDecl * NSValueDecl
The declaration of the Objective-C NSValue class.
Selector RespondsToSelectorSel
will hold 'respondsToSelector:'
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, const ObjCMethodDecl *PrevMethod, MethodMatchStrategy strategy=MMS_strict)
MatchTwoMethodDeclarations - Checks if two methods' type match and returns true, or false,...
bool CheckMessageArgumentTypes(const Expr *Receiver, QualType ReceiverType, MultiExprArg Args, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, SourceRange RecRange, QualType &ReturnType, ExprValueKind &VK)
CheckMessageArgumentTypes - Check types in an Obj-C message send.
Definition SemaExprObjC.cpp:1711
ObjCInterfaceDecl * NSStringDecl
The declaration of the Objective-C NSString class.
llvm::MapVector< Selector, SourceLocation > ReferencedSelectors
Method selectors used in a @selector expression.
ObjCMethodDecl * LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass=false)
LookupFactoryMethodInGlobalPool - Returns the method and warns if there are multiple signatures.
ObjCMethodDecl * StringWithUTF8StringMethod
The declaration of the stringWithUTF8String: method.
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.
QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc)
FindCompositeObjCPointerType - Helper method to find composite type of two objective-c pointer types ...
Definition SemaExprObjC.cpp:4924
ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S)
Definition SemaExprObjC.cpp:83
ObjCInterfaceDecl * NSDictionaryDecl
The declaration of the Objective-C NSDictionary class.
ObjCMethodDecl * ArrayWithObjectsMethod
The declaration of the arrayWithObjects:count: method.
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc)
Definition SemaExprObjC.cpp:1160
QualType QIDNSCopying
id type.
bool CheckObjCString(Expr *Arg)
CheckObjCString - Checks that the argument to the builtin CFString constructor is correct Note: It mi...
ExprResult ActOnClassMessage(Scope *S, ParsedType Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
Definition SemaExprObjC.cpp:2754
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr)
Definition SemaExprObjC.cpp:4134
bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, bool Diagnose=true)
Definition SemaExprObjC.cpp:5074
ObjCMethodDecl * tryCaptureObjCSelf(SourceLocation Loc)
Try to capture an implicit reference to 'self'.
Definition SemaExprObjC.cpp:1421
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, ArrayRef< Expr * > Strings)
Definition SemaExprObjC.cpp:37
ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value)
Definition SemaExprObjC.cpp:371
ObjCMethodDecl * DictionaryWithObjectsMethod
The declaration of the dictionaryWithObjects:forKeys:count: method.
QualType NSStringPointer
Pointer to NSString type (NSString *).
ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, Expr *SubExpr)
Definition SemaExprObjC.cpp:4644
ObjCProtocolDecl * LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Find the protocol with the given name, if any.
QualType NSNumberPointer
Pointer to NSNumber type (NSNumber *).
DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S, IdentifierInfo *II)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
Definition SemaExprObjC.cpp:4773
ObjCMethodDecl * NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]
The Objective-C NSNumber methods used to create NSNumber literals.
GlobalMethodPool MethodPool
Method Pool - allows efficient lookup when typechecking messages to "id".
QualType getMessageSendResultType(const Expr *Receiver, QualType ReceiverType, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage)
Determine the result of a message send expression based on the type of the receiver,...
Definition SemaExprObjC.cpp:1520
ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)
ParseObjCProtocolExpression - Build protocol expression for @protocol.
Definition SemaExprObjC.cpp:1391
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
Definition SemaExprObjC.cpp:2775
void checkRetainCycles(ObjCMessageExpr *msg)
checkRetainCycles - Check whether an Objective-C message send might create an obvious retain cycle.
ObjCMessageKind
Describes the kind of message expression indicated by a message send that starts with an identifier.
@ ObjCClassMessage
The message is a class message, and the identifier is a type name.
@ ObjCInstanceMessage
The message is an instance message.
@ ObjCSuperMessage
The message is sent to 'super'.
ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, IdentifierInfo *II, bool AllowBuiltinCreation=false)
The parser has read a name in, and Sema has detected that we're currently inside an ObjC method.
Definition SemaExprObjC.cpp:4846
QualType NSValuePointer
Pointer to NSValue type (NSValue *).
void EmitRelatedResultTypeNote(const Expr *E)
If the given expression involves a message send to a method with a related result type,...
Definition SemaExprObjC.cpp:1684
ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
Definition SemaExprObjC.cpp:3412
bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)
ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV)
Definition SemaExprObjC.cpp:4864
ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
Definition SemaExprObjC.cpp:2380
CastKind PrepareCastToObjCObjectPointer(ExprResult &E)
Prepare a conversion of the given expression to an ObjC object pointer type.
Definition SemaExprObjC.cpp:5193
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.
bool checkObjCBridgeRelatedComponents(SourceLocation Loc, QualType DestType, QualType SrcType, ObjCInterfaceDecl *&RelatedClass, ObjCMethodDecl *&ClassMethod, ObjCMethodDecl *&InstanceMethod, TypedefNameDecl *&TDNDecl, bool CfToNs, bool Diagnose=true)
Definition SemaExprObjC.cpp:4220
void EmitRelatedResultTypeNoteForReturn(QualType destType)
Given that we had incompatible pointer types in a return statement, check whether we're in a method w...
Definition SemaExprObjC.cpp:1654
void diagnoseARCUnbridgedCast(Expr *e)
Given that we saw an expression with the ARCUnbridgedCastTy placeholder type, complain bitterly.
Definition SemaExprObjC.cpp:4515
ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)
LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...
Definition SemaExprObjC.cpp:1962
ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD, bool IsReinterpretCast=false)
Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...
Definition SemaExprObjC.cpp:4388
bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind)
Definition SemaExprObjC.cpp:4203
bool CheckObjCARCUnavailableWeakConversion(QualType castType, QualType ExprType)
Definition SemaExprObjC.cpp:4589
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef< const Expr * > Args)
Expr * stripARCUnbridgedCast(Expr *e)
stripARCUnbridgedCast - Given an expression of ARCUnbridgedCast type, remove the placeholder cast.
Definition SemaExprObjC.cpp:4548
ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod)
Build an ObjC subscript pseudo-object expression, given that that's supported by the runtime.
Definition SemaExprObjC.cpp:764
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
Definition SemaExprObjC.cpp:1920
ExprResult ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef< AvailabilitySpec > AvailSpecs, SourceLocation AtLoc, SourceLocation RParen)
Definition SemaExprObjC.cpp:5151
bool isKnownName(StringRef name)
Definition SemaExprObjC.cpp:3738
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
Sema - This implements semantic analysis and AST building for C.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
bool FormatStringHasSArg(const StringLiteral *FExpr)
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
ASTContext & getASTContext() const
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() const
const LangOptions & LangOpts
ExprResult DefaultLvalueConversion(Expr *E)
static bool isCast(CheckedConversionKind CCK)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
SourceManager & getSourceManager() const
bool makeUnavailableInSystemHeader(SourceLocation loc, UnavailableAttr::ImplicitReason reason)
makeUnavailableInSystemHeader - There is an error in the current context.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
SourceManager & SourceMgr
DiagnosticsEngine & Diags
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceLocation getEndLoc() const LLVM_READONLY
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
tokloc_iterator tokloc_begin() const
tokloc_iterator tokloc_end() const
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, ArrayRef< SourceLocation > Locs)
This is the "fully general" constructor that allows representation of strings formed from one or more...
StringRef getString() const
The top declaration context.
Represents a declaration of a type.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
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 isBlockPointerType() const
const ObjCObjectPointerType * getAsObjCQualifiedClassType() const
const ObjCObjectPointerType * getAsObjCQualifiedIdType() const
bool isObjCBuiltinType() const
bool isVoidPointerType() const
bool isObjCARCBridgableType() const
Determine whether the given type T is a "bridgable" Objective-C type, which is either an Objective-C ...
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs.
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool canHaveNullability(bool ResultIfUnknown=true) const
Determine whether the given type can have a nullability specifier applied to it, i....
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isCARCBridgableType() const
Determine whether the given type T is a "bridgeable" C type.
bool isObjCIdType() const
bool isObjCClassOrClassKindOfType() const
Whether the type is Objective-C 'Class' or a __kindof type of an Class type, e.g.,...
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjCObjectPointerType() const
bool isObjCQualifiedClassType() const
bool isObjCClassType() const
std::optional< ArrayRef< QualType > > getObjCSubstitutions(const DeclContext *dc) const
Retrieve the set of substitutions required when accessing a member of the Objective-C receiver type t...
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const ObjCObjectType * getAsObjCInterfaceType() const
bool isAnyPointerType() const
bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, const ObjCObjectType *&bound) const
Whether the type is Objective-C 'id' or a __kindof type of an object type, e.g., __kindof NSView * or...
const T * getAs() const
Member-template getAs'.
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
TypedefNameDecl * getDecl() const
Simple class containing the result of Sema::CorrectTypo.
DeclClass * getCorrectionDeclAs() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represents a C++ unqualified-id that has been parsed.
void setImplicitSelfParam(const IdentifierInfo *Id)
Specify that this unqualified-id is an implicit 'self' parameter.
void setType(QualType newType)
bool isCommitable() const
edit_iterator edit_begin() const
SmallVectorImpl< Edit >::const_iterator edit_iterator
edit_iterator edit_end() const
Retains information about a function, method, or block that is currently being parsed.
bool ObjCIsDesignatedInit
True when this is a method marked as a designated initializer.
bool ObjCWarnForNoInitDelegation
This starts true for a secondary initializer method and will be set to false if there is an invocatio...
bool ObjCIsSecondaryInit
True when this is an initializer method not marked as a designated initializer within a class that ha...
bool ObjCWarnForNoDesignatedInitChain
This starts true for a method marked as designated initializer and will be set to false if there is a...
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr
Matches any cast nodes of Clang's AST.
constexpr Variable var(Literal L)
Returns the variable of L.
bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool followsCreateRule(const FunctionDecl *FD)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
RangeSelector merge(RangeSelector First, RangeSelector Second)
Selects the merge of the two ranges, i.e.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Ambiguous
Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...
@ NotFound
No entity found met the criteria.
@ FoundOverloaded
Name lookup found a set of overloaded functions that met the criteria.
@ Found
Name lookup found a single declaration that met the criteria.
@ FoundUnresolvedValue
Name lookup found an unresolvable value declaration and cannot yet complete.
@ NotFoundInCurrentInstantiation
No entity found met the criteria within the current instantiation,, but there were dependent base cla...
NullabilityKind
Describes the nullability of a particular type.
@ Nullable
Values of this type can be null.
@ NonNull
Values of this type can never be null.
@ OK_ObjCProperty
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
@ OK_ObjCSubscript
An Objective-C array/dictionary subscripting which reads an object or writes at the subscripted array...
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
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.
MutableArrayRef< Expr * > MultiExprArg
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
const FunctionProtoType * T
ObjCBridgeCastKind
The kind of bridging performed by the Objective-C bridge cast.
@ OBC_Bridge
Bridging via __bridge, which does nothing but reinterpret the bits.
@ OBC_BridgeTransfer
Bridging via __bridge_transfer, which transfers ownership of an Objective-C pointer into ARC.
@ OBC_BridgeRetained
Bridging via __bridge_retain, which makes an ARC object available as a +1 C pointer.
CastKind
CastKind - The kind of operation required for a conversion.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
@ None
No keyword precedes the qualified type name.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
CheckedConversionKind
The kind of conversion being performed.
@ Implicit
An implicit conversion.
@ CStyleCast
A C-style cast.
@ ForBuiltinOverloadedOp
A conversion for an operand of a builtin overloaded operator.
@ OtherCast
A cast other than a C-style cast.
@ FunctionalCast
A functional-style cast.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
An element in an Objective-C dictionary literal.
a linked list of methods with the same selector name but different signatures.
ObjCMethodDecl * getMethod() const
ObjCMethodList * getNext() const
CharSourceRange getFileRange(SourceManager &SM) const
CharSourceRange getInsertFromRange(SourceManager &SM) const