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
44 StringLiteral *S = cast(Strings[0]);
45
46
47 if (Strings.size() != 1) {
48
51
53 S = cast(E);
54
55
56 if (!S->isOrdinary()) {
57 Diag(S->getBeginLoc(), diag::err_cfstring_literal_not_string_constant)
58 << S->getSourceRange();
59 return true;
60 }
61
62
63 StrBuf += S->getString();
64
65
66 StrLocs.append(S->tokloc_begin(), S->tokloc_end());
67 }
68
69
70
72 assert(CAT && "String literal not of constant array type!");
74 CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1), nullptr,
77 false, StrTy, &StrLocs[0],
78 StrLocs.size());
79 }
80
82}
83
87
89 return true;
90
91
92
93
94
98 } else if (getLangOpts().NoConstantCFStrings) {
100 std::string StringClass(getLangOpts().ObjCConstantStringClass);
101
102 if (StringClass.empty())
103 NSIdent = &Context.Idents.get("NSConstantString");
104 else
105 NSIdent = &Context.Idents.get(StringClass);
106
109 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null(IF)) {
113 } else {
114
115
116 Diag(S->getBeginLoc(), diag::err_no_nsconstant_string_class)
117 << NSIdent << S->getSourceRange();
119 }
120 } else {
124 if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null(IF)) {
128 } else {
129
130
131
132
142 }
144 }
145 }
146
148}
149
150
151
155 if (!Method) {
156
157 S.Diag(Loc, diag::err_undeclared_boxing_method) << Sel << Class->getName();
158 return false;
159 }
160
161
164 S.Diag(Loc, diag::err_objc_literal_method_sig)
165 << Sel;
166 S.Diag(Method->getLocation(), diag::note_objc_literal_method_return)
167 << ReturnType;
168 return false;
169 }
170
171 return true;
172}
173
174
177 switch (LiteralKind) {
188
189
190
193 break;
194 }
195 llvm_unreachable("LiteralKind can't be converted into a ClassKind");
196}
197
198
199
200
201static bool
208 S.Diag(Loc, diag::err_undeclared_objc_literal_class)
209 << II->getName() << LiteralKind;
210 return false;
211 } else if (->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {
212 S.Diag(Loc, diag::err_undeclared_objc_literal_class)
213 << Decl->getName() << LiteralKind;
215 return false;
216 }
217
218 return true;
219}
220
221
222
223
232 if (!ID && S.getLangOpts().DebuggerObjCLiteral) {
237 }
238
240 ID = nullptr;
241 }
242
243 return ID;
244}
245
246
247
250 bool isLiteral = false,
252 std::optionalNSAPI::NSNumberLiteralMethodKind Kind =
253 S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
254
255 if (!Kind) {
256 if (isLiteral) {
257 S.Diag(Loc, diag::err_invalid_nsnumber_type)
258 << NumberType << R;
259 }
260 return nullptr;
261 }
262
263
264 if (S.NSNumberLiteralMethods[*Kind])
265 return S.NSNumberLiteralMethods[*Kind];
266
267 Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind,
268 false);
269
271
272
273
274 if (!S.NSNumberDecl) {
275 S.NSNumberDecl =
277 if (!S.NSNumberDecl) {
278 return nullptr;
279 }
280 }
281
282 if (S.NSNumberPointer.isNull()) {
283
286 }
287
288
289 ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel);
290 if (!Method && S.getLangOpts().DebuggerObjCLiteral) {
291
295 ReturnTInfo, S.NSNumberDecl,
296 false, false,
297 false,
298 false,
299 true,
301 false);
305 NumberType, nullptr, SC_None, nullptr);
307 }
308
310 return nullptr;
311
312
313
314
315 S.NSNumberLiteralMethods[*Kind] = Method;
316 return Method;
317}
318
319
320
322 Expr *Number) {
324
326 if (CharacterLiteral *Char = dyn_cast(Number)) {
327
328
329 switch (Char->getKind()) {
332 NumberType = Context.CharTy;
333 break;
334
337 break;
338
340 NumberType = Context.Char16Ty;
341 break;
342
344 NumberType = Context.Char32Ty;
345 break;
346 }
347 }
348
349
350
353 true, NR);
354 if (!Method)
356
357
360 ParamDecl);
365 Number = ConvertedNumber.get();
366
367
370}
371
378 Value ? tok::kw_true : tok::kw_false);
379 } else {
380
381
384 CK_IntegralToBoolean);
385 }
386
388}
389
390
391
394 bool ArrayLiteral = false) {
395
396 if (Element->isTypeDependent())
397 return Element;
398
400 if (Result.isInvalid())
402 Element = Result.get();
403
404
405
406 if (S.getLangOpts().CPlusPlus && Element->getType()->isRecordType()) {
409 false);
413 if (.Failed())
414 return Seq.Perform(S, Entity, Kind, Element);
415 }
416
417 Expr *OrigElement = Element;
418
419
421 if (Result.isInvalid())
423 Element = Result.get();
424
425
426 if (!Element->getType()->isObjCObjectPointerType() &&
427 !Element->getType()->isBlockPointerType()) {
428 bool Recovered = false;
429
430
431 if (isa(OrigElement) ||
432 isa(OrigElement) ||
433 isa(OrigElement) ||
434 isa(OrigElement) ||
435 isa(OrigElement)) {
436 if (S.ObjC().NSAPIObj->getNSNumberFactoryMethodKind(
437 OrigElement->getType())) {
438 int Which = isa(OrigElement) ? 1
439 : (isa(OrigElement) ||
440 isa(OrigElement)) ? 2
441 : 3;
442
443 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
446
448 OrigElement);
449 if (Result.isInvalid())
451
452 Element = Result.get();
453 Recovered = true;
454 }
455 }
456
457 else if (StringLiteral *String = dyn_cast(OrigElement)) {
458 if (String->isOrdinary()) {
459 S.Diag(OrigElement->getBeginLoc(), diag::err_box_literal_collection)
462
465 if (Result.isInvalid())
467
468 Element = Result.get();
469 Recovered = true;
470 }
471 }
472
473 if (!Recovered) {
474 S.Diag(Element->getBeginLoc(), diag::err_invalid_collection_element)
475 << Element->getType();
477 }
478 }
479 if (ArrayLiteral)
481 dyn_cast(OrigElement)) {
483 unsigned numConcat = SL->getNumConcatenated();
484 if (numConcat > 1) {
485
486 bool hasMacro = false;
487 for (unsigned i = 0; i < numConcat ; ++i)
488 if (SL->getStrTokenLoc(i).isMacroID()) {
489 hasMacro = true;
490 break;
491 }
492 if (!hasMacro)
493 S.Diag(Element->getBeginLoc(),
494 diag::warn_concatenated_nsarray_literal)
495 << Element->getType();
496 }
497 }
498 }
499
500
501
504 false),
505 Element->getBeginLoc(), Element);
506}
507
513 return BoxedExpr;
514 }
517
521 }
523 ValueExpr = RValue.get();
528
534 }
537 }
538
539
540
541 if (auto *CE = dyn_cast(ValueExpr))
542 if (CE->getCastKind() == CK_ArrayToPointerDecay)
543 if (auto *SL =
544 dyn_cast(CE->getSubExpr()->IgnoreParens())) {
545 assert((SL->isOrdinary() || SL->isUTF8()) &&
546 "unexpected character encoding");
547 StringRef Str = SL->getString();
548 const llvm::UTF8 *StrBegin = Str.bytes_begin();
549 const llvm::UTF8 *StrEnd = Str.bytes_end();
550
551 if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {
554 return new (Context) ObjCBoxedExpr(CE, BoxedType, nullptr, SR);
555 }
556
557 Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)
559 }
560
564
565
567 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
568
573 false, false,
574 false,
575 false,
576 true,
578 false);
585 nullptr,
588 BoxingMethod = M;
589 }
590
592 stringWithUTF8String, BoxingMethod))
594
596 }
597
600
601 std::optional Nullability =
603 if (Nullability)
604 BoxedType =
606 }
608
609
610
611
612
613
615 dyn_cast(ValueExpr->IgnoreParens())) {
616
617
618 switch (Char->getKind()) {
621 ValueType = Context.CharTy;
622 break;
623
626 break;
627
629 ValueType = Context.Char16Ty;
630 break;
631
633 ValueType = Context.Char32Ty;
634 break;
635 }
636 }
637
638
639
643 if (!ET->getDecl()->isComplete()) {
644 Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)
647 }
648
650 ET->getDecl()->getIntegerType());
653
654
655
656
657
662 }
663
664
667 }
668
671 &Context.Idents.get("objCType")};
673
674
676 if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
677
682 false,
683 false,
684 false,
685 false,
686 true,
688 false);
689
691
697 nullptr,
699 Params.push_back(bytes);
700
707 nullptr,
709 Params.push_back(type);
710
712 BoxingMethod = M;
713 }
714
716 ValueWithBytesObjCType, BoxingMethod))
718
720 }
721
723 Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)
726 }
727
730 }
731
732 if (!BoxingMethod) {
733 Diag(Loc, diag::err_objc_illegal_boxed_expression_type)
736 }
737
739
744 IE, ValueExpr->getExprLoc(), ValueExpr);
745 } else {
746
749 ParamDecl);
750 ConvertedValueExpr =
752 }
753
754 if (ConvertedValueExpr.isInvalid())
756 ValueExpr = ConvertedValueExpr.get();
757
759 new (Context) ObjCBoxedExpr(ValueExpr, BoxedType,
760 BoxingMethod, SR);
762}
763
764
765
769 assert(().isSubscriptPointerArithmetic());
771
772
773
775 "base or index cannot have dependent type here");
776
777
778
780 if (Result.isInvalid())
782 IndexExpr = Result.get();
783
784
786 if (Result.isInvalid())
788 BaseExpr = Result.get();
789
790
793 getterMethod, setterMethod, RB);
794}
795
800
806 }
807 }
808
809
815 if (!Method && getLangOpts().DebuggerObjCLiteral) {
820 false ,
821 false, false,
822 true, false,
830 nullptr,
832 Params.push_back(objects);
838 nullptr, SC_None,
839 nullptr);
840 Params.push_back(cnt);
842 }
843
846
847
850 if (!PtrT ||
852 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
853 << Sel;
855 diag::note_objc_literal_method_param)
856 << 0 << T
859 }
860
861
862 if (!Method->parameters()[1]->getType()->isIntegerType()) {
863 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
864 << Sel;
866 diag::note_objc_literal_method_param)
867 << 1
868 << Method->parameters()[1]->getType()
869 << "integral";
871 }
872
873
875 }
876
879
880
881
882 Expr **ElementsBuffer = Elements.data();
883 for (unsigned I = 0, N = Elements.size(); I != N; ++I) {
885 SemaRef, ElementsBuffer[I], RequiredType, true);
888
889 ElementsBuffer[I] = Converted.get();
890 }
891
895
898}
899
900
901
902static void
905 if (Literal->isValueDependent() || Literal->isTypeDependent())
906 return;
907
908
909
910
911 struct APSIntCompare {
912 bool operator()(const llvm::APSInt &LHS, const llvm::APSInt &RHS) const {
913 return llvm::APSInt::compareValues(LHS, RHS) < 0;
914 }
915 };
916
917 llvm::DenseMap<StringRef, SourceLocation> StringKeys;
918 std::map<llvm::APSInt, SourceLocation, APSIntCompare> IntegralKeys;
919
920 auto checkOneKey = [&](auto &Map, const auto &Key, SourceLocation Loc) {
921 auto Pair = Map.insert({Key, Loc});
922 if (!Pair.second) {
923 S.Diag(Loc, diag::warn_nsdictionary_duplicate_key);
924 S.Diag(Pair.first->second, diag::note_nsdictionary_duplicate_key_here);
925 }
926 };
927
928 for (unsigned Idx = 0, End = Literal->getNumElements(); Idx != End; ++Idx) {
929 Expr *Key = Literal->getKeyValueElement(Idx).Key->IgnoreParenImpCasts();
930
931 if (auto *StrLit = dyn_cast(Key)) {
932 StringRef Bytes = StrLit->getString()->getBytes();
934 checkOneKey(StringKeys, Bytes, Loc);
935 }
936
937 if (auto *BE = dyn_cast(Key)) {
938 Expr *Boxed = BE->getSubExpr();
940
941
943 checkOneKey(StringKeys, Str->getBytes(), Loc);
944 continue;
945 }
946
950 checkOneKey(IntegralKeys, Result.Val.getInt(), Loc);
951 }
952 }
953 }
954}
955
960
966 }
967 }
968
969
970
976 if (!Method && getLangOpts().DebuggerObjCLiteral) {
980 false , false ,
981 false,
982 false,
983 true, false,
991 nullptr, SC_None,
992 nullptr);
993 Params.push_back(objects);
999 nullptr, SC_None,
1000 nullptr);
1001 Params.push_back(keys);
1007 nullptr, SC_None,
1008 nullptr);
1009 Params.push_back(cnt);
1011 }
1012
1014 Method))
1016
1017
1020 if (!PtrValue ||
1022 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1023 << Sel;
1025 diag::note_objc_literal_method_param)
1026 << 0 << ValueT
1029 }
1030
1031
1034 if (!PtrKey ||
1036 IdT)) {
1037 bool err = true;
1038 if (PtrKey) {
1040
1048 }
1049 }
1053 }
1054
1055 if (err) {
1056 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1057 << Sel;
1059 diag::note_objc_literal_method_param)
1060 << 1 << KeyT
1063 }
1064 }
1065
1066
1067 QualType CountType = Method->parameters()[2]->getType();
1069 Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
1070 << Sel;
1071 Diag(Method->parameters()[2]->getLocation(),
1072 diag::note_objc_literal_method_param)
1073 << 2 << CountType
1074 << "integral";
1076 }
1077
1078
1080 }
1081
1082 QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();
1084 QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();
1086
1087
1088
1089 bool HasPackExpansions = false;
1091
1096
1097
1100 if (Value.isInvalid())
1102
1103 Element.Key = Key.get();
1104 Element.Value = Value.get();
1105
1106 if (Element.EllipsisLoc.isInvalid())
1107 continue;
1108
1109 if (!Element.Key->containsUnexpandedParameterPack() &&
1110 !Element.Value->containsUnexpandedParameterPack()) {
1111 Diag(Element.EllipsisLoc,
1112 diag::err_pack_expansion_without_parameter_packs)
1113 << SourceRange(Element.Key->getBeginLoc(),
1114 Element.Value->getEndLoc());
1116 }
1117
1118 HasPackExpansions = true;
1119 }
1120
1123
1126 DictionaryWithObjectsMethod, SR);
1128 return SemaRef.MaybeBindToTemporary(Literal);
1129}
1130
1139 else {
1140 if (!EncodedType->getAsArrayTypeUnsafe() &&
1141 !EncodedType->isVoidType())
1143 diag::err_incomplete_type_objc_at_encode,
1146
1147 std::string Str;
1150 if (!NotEncodedT.isNull())
1151 Diag(AtLoc, diag::warn_incomplete_encoded_type)
1152 << EncodedType << NotEncodedT;
1153
1154
1155
1157 }
1158
1159 return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
1160}
1161
1168
1171 if (!TInfo)
1174
1176}
1177
1185 bool Warned = false;
1188 if (MatchingMethodDecl == Method ||
1189 isa(MatchingMethodDecl->getDeclContext()) ||
1191 continue;
1194 if (!Warned) {
1195 Warned = true;
1196 S.Diag(AtLoc, diag::warn_multiple_selectors)
1199 S.Diag(Method->getLocation(), diag::note_method_declared_at)
1201 }
1202 S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)
1204 }
1205 }
1206 return Warned;
1207}
1208
1213 bool WarnMultipleSelectors) {
1214 if (!WarnMultipleSelectors ||
1216 return;
1217 bool Warned = false;
1218 for (SemaObjC::GlobalMethodPool::iterator b = S.ObjC().MethodPool.begin(),
1221
1224 Method, InstMethList))
1225 Warned = true;
1226
1227
1230 Method, ClsMethList) || Warned)
1231 return;
1232 }
1233}
1234
1237 bool &onlyDirect,
1238 bool &anyDirect) {
1239 (void)Sel;
1242 for (; M; M = M->getNext()) {
1244 if (!Method)
1245 continue;
1246 assert(Method->getSelector() == Sel && "Method with wrong selector in method list");
1248 anyDirect = true;
1249 DirectMethod = Method;
1250 } else
1251 onlyDirect = false;
1252 }
1253
1254 return DirectMethod;
1255}
1256
1257
1258
1259
1260
1262 bool &onlyDirect,
1263 bool &anyDirect) {
1266 return nullptr;
1267
1269 S, Sel, Iter->second.first, onlyDirect, anyDirect);
1271 S, Sel, Iter->second.second, onlyDirect, anyDirect);
1272
1273 return DirectInstance ? DirectInstance : DirectClass;
1274}
1275
1278 if (!CurMD)
1279 return nullptr;
1281
1282
1283
1284
1286 return MD;
1288 return MD;
1290 return MD;
1292 return MD;
1293
1294 return nullptr;
1295}
1296
1302 bool WarnMultipleSelectors) {
1306 if (!Method)
1309 if (!Method) {
1311 Selector MatchedSel = OM->getSelector();
1314 Diag(SelLoc, diag::warn_undeclared_selector_with_typo)
1315 << Sel << MatchedSel
1317
1318 } else
1319 Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1320 } else {
1322 WarnMultipleSelectors);
1323
1324 bool onlyDirect = true;
1325 bool anyDirect = false;
1328
1329 if (onlyDirect) {
1330 Diag(AtLoc, diag::err_direct_selector_expression)
1332 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
1334 } else if (anyDirect) {
1335
1336
1337
1340 if (LikelyTargetMethod && LikelyTargetMethod->isDirectMethod()) {
1341 Diag(AtLoc, diag::warn_potentially_direct_selector_expression) << Sel;
1343 diag::note_direct_method_declared_at)
1345 } else if (!LikelyTargetMethod) {
1346
1347
1348 Diag(AtLoc, diag::warn_strict_potentially_direct_selector_expression)
1349 << Sel;
1351 diag::note_direct_method_declared_at)
1353 }
1354 }
1355 }
1356
1357 if (Method &&
1362
1363
1364
1372 Diag(AtLoc, diag::err_arc_illegal_selector) <<
1373 Sel << SourceRange(LParenLoc, RParenLoc);
1374 break;
1375
1386 break;
1387 }
1388 }
1390 return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
1391}
1392
1401 if (!PDecl) {
1402 Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
1403 return true;
1404 }
1406 Diag(ProtoLoc, diag::err_objc_non_runtime_protocol_in_protocol_expr)
1407 << PDecl;
1409 Diag(ProtoLoc, diag::err_atprotocol_protocol) << PDecl;
1410 Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
1411 } else {
1413 }
1414
1417 return true;
1419 return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, ProtoIdLoc, RParenLoc);
1420}
1421
1422
1425
1426
1427
1428
1429 ObjCMethodDecl *method = dyn_cast(DC);
1430 if (!method)
1431 return nullptr;
1432
1434
1435 return method;
1436}
1437
1444 }
1445
1446 return origType;
1447 }
1448
1451
1452 return origType;
1453}
1454
1455
1456
1457
1458
1459
1463 bool isClassMessage,
1464 bool isSuperMessage) {
1465 assert(Method && "Must have a method");
1468
1470
1471
1472
1474
1475 if (auto nullability =
1477
1479
1480
1482 }
1483
1484 return type;
1485 };
1486
1487
1488
1489
1490
1494
1495
1496
1497 if (isSuperMessage) {
1500 return transferNullability(
1503 }
1504 }
1505
1506
1509
1510
1515
1516
1517
1518
1519 return transferNullability(ReceiverType);
1520}
1521
1525 bool isClassMessage,
1526 bool isSuperMessage) {
1528
1530 SemaRef, ReceiverType, Method, isClassMessage, isSuperMessage);
1531
1532
1533 if (isClassMessage) {
1534
1535
1536
1537
1538
1540 assert(ReceiverType->isObjCClassType() && "expected a Class self");
1545 cast(
1547 ->getDeclContext());
1548 assert(MD->isClassMethod() && "expected a class method");
1551 if (auto Nullability = resultType->getNullability())
1552 NewResultType = Context.getAttributedType(*Nullability, NewResultType,
1553 NewResultType);
1554 return NewResultType;
1555 }
1556 }
1557 return resultType;
1558 }
1559
1560
1561
1563 return resultType;
1564
1565
1566 unsigned receiverNullabilityIdx = 0;
1567 if (std::optional nullability =
1571 receiverNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1572 }
1573
1574 unsigned resultNullabilityIdx = 0;
1575 if (std::optional nullability =
1579 resultNullabilityIdx = 1 + static_cast<unsigned>(*nullability);
1580 }
1581
1582
1583
1584 static const uint8_t None = 0;
1585 static const uint8_t NonNull = 1;
1586 static const uint8_t Nullable = 2;
1588 static const uint8_t nullabilityMap[4][4] = {
1589
1594 };
1595
1596 unsigned newResultNullabilityIdx
1597 = nullabilityMap[receiverNullabilityIdx][resultNullabilityIdx];
1598 if (newResultNullabilityIdx == resultNullabilityIdx)
1599 return resultType;
1600
1601
1602
1603 do {
1604 if (auto attributed = dyn_cast(resultType.getTypePtr())) {
1605 resultType = attributed->getModifiedType();
1606 } else {
1608 }
1610
1611
1612 if (newResultNullabilityIdx > 0) {
1613 auto newNullability
1614 = static_cast<NullabilityKind>(newResultNullabilityIdx-1);
1615 return Context.getAttributedType(newNullability, resultType, resultType);
1616 }
1617
1618 return resultType;
1619}
1620
1621
1626 return MD;
1627
1628
1629
1634 dyn_cast(impl)) {
1635 iface = catImpl->getCategoryDecl();
1636 } else {
1637 iface = impl->getClassInterface();
1638 }
1639
1643 }
1644
1647 for (unsigned i = 0, e = overrides.size(); i != e; ++i) {
1650 return result;
1651 }
1652
1653 return nullptr;
1654}
1655
1658
1659
1663 return;
1664
1665
1666
1669 SourceRange range = overridden->getReturnTypeSourceRange();
1672 loc = overridden->getLocation();
1673 Diag(loc, diag::note_related_result_type_explicit)
1674 << 1 << range;
1675 return;
1676 }
1677
1678
1679
1681 Diag(MD->getLocation(), diag::note_related_result_type_family)
1682 << 1
1683 << family;
1684}
1685
1689 const ObjCMessageExpr *MsgSend = dyn_cast(E);
1690 if (!MsgSend)
1691 return;
1692
1694 if (!Method)
1695 return;
1696
1698 return;
1699
1702 return;
1703
1706 return;
1707
1708 Diag(Method->getLocation(), diag::note_related_result_type_inferred)
1711}
1712
1716 bool isClassMessage, bool isSuperMessage, SourceLocation lbrac,
1721 if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
1722 SelLoc = SelectorLocs.front();
1723 else
1724 SelLoc = lbrac;
1725
1726 if (!Method) {
1727
1728 for (unsigned i = 0, e = Args.size(); i != e; i++) {
1729 if (Args[i]->isTypeDependent())
1730 continue;
1731
1734 QualType paramTy;
1736 } else {
1738 }
1740 return true;
1741 Args[i] = result.get();
1742 }
1743
1744 unsigned DiagID;
1746 DiagID = diag::err_arc_method_not_found;
1747 else
1748 DiagID = isClassMessage ? diag::warn_class_method_not_found
1749 : diag::warn_inst_method_not_found;
1754 DiagID = diag::err_method_not_found_with_typo;
1755 else
1756 DiagID = isClassMessage ? diag::warn_class_method_not_found_with_typo
1757 : diag::warn_instance_method_not_found_with_typo;
1759 SourceRange SelectorRange(SelectorLocs.front(), SelectorLocs.back());
1761 Diag(SelLoc, DiagID)
1762 << Sel<< isClassMessage << MatchedSel
1764 else
1765 Diag(SelLoc, DiagID) << Sel<< isClassMessage << MatchedSel;
1766 }
1767 else
1768 Diag(SelLoc, DiagID)
1769 << Sel << isClassMessage << SourceRange(SelectorLocs.front(),
1770 SelectorLocs.back());
1771
1774 Diag(ThisClass->getLocation(), diag::note_receiver_class_declared);
1776 if (ThisClass->lookupClassMethod(Sel))
1777 Diag(RecRange.getBegin(), diag::note_receiver_expr_here)
1779 ThisClass->getNameAsString());
1780 }
1781 }
1782 }
1783
1784
1785
1788 } else {
1790 }
1792 return false;
1793 }
1794
1796 isClassMessage, isSuperMessage);
1798
1799 unsigned NumNamedArgs = Sel.getNumArgs();
1800
1801
1803 NumNamedArgs = Method->param_size();
1804
1805 if (Args.size() < NumNamedArgs) {
1806 Diag(SelLoc, diag::err_typecheck_call_too_few_args)
1807 << 2 << NumNamedArgs << static_cast(Args.size())
1808 << 0;
1809 return false;
1810 }
1811
1812
1813
1814 std::optional<ArrayRef> typeArgs =
1816 bool IsError = false;
1817 for (unsigned i = 0; i < NumNamedArgs; i++) {
1818
1819 if (Args[i]->isTypeDependent())
1820 continue;
1821
1822 Expr *argExpr = Args[i];
1823
1825 assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
1826
1827 if (param->hasAttr() &&
1829 if (auto *BE = dyn_cast(
1831 BE->getBlockDecl()->setDoesNotEscape();
1832
1833
1834
1836 !param->hasAttr())
1838
1839
1840
1845 IsError = true;
1846 } else {
1847 Args[i] = argE.get();
1848
1849
1850 param->setType(paramType);
1851 }
1852 continue;
1853 }
1854
1857 if (typeArgs)
1859 Context,
1860 *typeArgs,
1862
1865 diag::err_call_incomplete_argument, argExpr))
1866 return true;
1867
1873 IsError = true;
1874 else {
1876
1877
1878
1879
1880 if (typeArgs && Args[i]->isPRValue() && paramType->isBlockPointerType() &&
1881 Args[i]->getType()->isBlockPointerType() &&
1885 Args[i] = arg.get();
1886 }
1887 }
1888 }
1889
1890
1892 for (unsigned i = NumNamedArgs, e = Args.size(); i < e; ++i) {
1893 if (Args[i]->isTypeDependent())
1894 continue;
1895
1899 Args[i] = Arg.get();
1900 }
1901 } else {
1902
1903 if (Args.size() != NumNamedArgs) {
1904 Diag(Args[NumNamedArgs]->getBeginLoc(),
1905 diag::err_typecheck_call_too_many_args)
1906 << 2 << NumNamedArgs << static_cast(Args.size())
1908 << SourceRange(Args[NumNamedArgs]->getBeginLoc(),
1909 Args.back()->getEndLoc());
1910 }
1911 }
1912
1914
1915
1916 IsError |=
1918
1919 return IsError;
1920}
1921
1923
1924 ObjCMethodDecl *Method = dyn_cast_or_null(
1927}
1928
1930 if (!method) return false;
1931
1933 if (DeclRefExpr *DRE = dyn_cast(receiver))
1934 if (DRE->getDecl() == method->getSelfDecl())
1935 return true;
1936 return false;
1937}
1938
1939
1941 bool isInstance) {
1944
1945 if (ObjCMethodDecl *method = iface->lookupMethod(sel, isInstance))
1946 return method;
1947
1948
1949
1950 if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
1951 return method;
1952 }
1953
1954
1955 for (const auto *I : objType->quals())
1956 if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance))
1957 return method;
1958
1959 return nullptr;
1960}
1961
1962
1963
1967 for (const auto *PROTO : OPT->quals()) {
1968 if ((MD = PROTO->lookupMethod(Sel, Instance))) {
1969 return MD;
1970 }
1971 }
1972 return nullptr;
1973}
1974
1975
1976
1984
1986 Diag(MemberLoc, diag::err_invalid_property_name)
1987 << MemberName << QualType(OPT, 0);
1989 }
1990
1992
1996 diag::err_property_not_found_forward_class,
1997 MemberName, BaseRange))
1999
2002
2005 if (Super)
2006 return new (Context)
2009 else
2010 return new (Context)
2013 }
2014
2015 for (const auto *I : OPT->quals())
2018
2021
2022 if (Super)
2025 SuperLoc, SuperType);
2026 else
2027 return new (Context)
2030 }
2031
2032
2033
2034
2035
2036
2039
2040
2041 if (!Getter)
2043
2044
2045 if (!Getter)
2047
2048 if (Getter) {
2049
2052 }
2053
2054
2058
2059
2060 if (!Setter)
2062
2063 if (!Setter) {
2064
2065
2067 }
2068
2071
2072
2073
2074
2079
2080
2081 if (!(PDecl->getPropertyAttributes() &
2083 Diag(MemberLoc,
2084 diag::warn_property_access_suggest)
2085 << MemberName << QualType(OPT, 0) << PDecl->getName()
2087 }
2088 }
2089
2090 if (Getter || Setter) {
2091 if (Super)
2092 return new (Context)
2095 else
2096 return new (Context)
2099
2100 }
2101
2102
2110
2112 Corrected.isKeyword() ? nullptr : Corrected.getFoundDecl();
2113 if (ChosenDecl && isa(ChosenDecl))
2114 if (cast(ChosenDecl)->isClassProperty()) {
2115
2116
2117 Diag(MemberLoc, diag::err_class_property_found) << MemberName
2122 }
2123 } else {
2125 PDiag(diag::err_property_not_found_suggest)
2126 << MemberName << QualType(OPT, 0));
2128 TypoResult, MemberLoc,
2129 SuperLoc, SuperType, Super);
2130 }
2131 }
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 }
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 {
2215 &propertyName);
2216 }
2217
2218
2220
2221
2222 if (!Getter)
2224
2225 if (Getter) {
2226
2227
2230 }
2231
2232
2234 if (!Setter) {
2235
2236
2238 }
2239
2240 if (!Setter)
2242
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)
2259}
2260
2261namespace {
2262
2264 public:
2266
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
2293 if (IsSuper && S->isInObjcMethodScope())
2295
2298
2299 switch (Result.getResultKind()) {
2301
2302
2303
2304
2307
2309 }
2310
2313 ClassDeclared))
2315 }
2316
2317
2318 break;
2319
2324 Result.suppressDiagnostics();
2326
2328
2329
2330 if (HasTrailingDot)
2332
2333
2338 else if (TypeDecl *Type = dyn_cast(ND)) {
2341 }
2342 else
2344
2345
2346
2350 }
2351 }
2352
2355 Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC,
2357 if (Corrected.isKeyword()) {
2358
2359
2361 << Name);
2365
2366
2368 << Name);
2373 }
2374 }
2375
2376
2378}
2379
2386
2388 if (!Method) {
2389 Diag(SuperLoc, diag::err_invalid_receiver_to_message_super);
2391 }
2392
2395 Diag(SuperLoc, diag::err_no_super_class_message)
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
2412
2414
2415
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())
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");
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
2491}
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)
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)
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
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
2650
2651 if (!Method) {
2657 ? diag::err_arc_receiver_forward_class
2658 : diag::warn_receiver_forward_class),
2659 TypeRange)) {
2660
2663 if (Method && ().ObjCAutoRefCount)
2664 Diag(Method->getLocation(), diag::note_method_sent_forward_class)
2666 }
2667 if (!Method)
2668 Method = Class->lookupClassMethod(Sel);
2669
2670
2671 if (!Method)
2672 Method = Class->lookupPrivateClassMethod(Sel);
2673
2675 false, false, Class))
2677 }
2678
2679
2682
2683 unsigned NumArgs = ArgsIn.size();
2684 Expr **Args = ArgsIn.data();
2686 MultiExprArg(Args, NumArgs), Sel, SelectorLocs,
2687 Method, true, SuperLoc.isValid(), LBracLoc,
2688 RBracLoc, SourceRange(), ReturnType, VK))
2690
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"
2703 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
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)
2716 }
2718
2720 Diag(Loc, diag::warn_direct_super_initialize_call);
2721 Diag(Method->getLocation(), diag::note_method_declared_at)
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 }
2745 if (Method)
2747 ReceiverType, true);
2749}
2750
2751
2752
2753
2763 if (ReceiverType.isNull())
2765
2766 if (!ReceiverTypeInfo)
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) {
2866 else
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");
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 &&
2901
2902
2903 Diag(Loc, diag::warn_bad_receiver_type) << ReceiverType << RecRange;
2907 CK_CPointerToObjCPointerCast)
2909 } else {
2910
2913 CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
2914 Receiver =
2917 }
2918 ReceiverType = Receiver->getType();
2920
2922 diag::err_incomplete_receiver_type))
2924
2928 Receiver = result.get();
2929 ReceiverType = Receiver->getType();
2930 }
2931 }
2932 }
2933
2934
2935
2936
2937
2938 if (!Method) {
2939
2940
2943 typeBound);
2947
2949 true, typeBound);
2950 if (!Methods.empty()) {
2951
2952
2953 Method = Methods[0];
2954
2957 Method = BestMethod;
2958
2961 receiverIsIdLike, Methods))
2963 }
2966
2967
2968
2969
2973
2975 if (!Method) {
2977
2979 Diag(SelLoc, diag::warn_instance_method_on_class_found)
2981 Diag(Method->getLocation(), diag::note_method_declared_at)
2983 }
2984 }
2985 } else {
2987 if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
2988
2989
2990
2991
2992 Method = ClassDecl->lookupClassMethod(Sel);
2993
2994 if (!Method)
2995 Method = ClassDecl->lookupPrivateClassMethod(Sel);
2996
2999 }
3000 }
3001 if (!Method) {
3002
3003 if (!Receiver || (Receiver)) {
3004
3005
3008 false,
3009 true);
3010 if (!Methods.empty()) {
3011
3012
3013 Method = Methods[0];
3014
3015
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
3027 Method = BestMethod;
3028 }
3029 }
3030 }
3031 }
3032 } else {
3034
3035
3036
3037
3040
3042 if (!Method)
3048
3049 ClassDecl = OCIType->getInterfaceDecl();
3050
3051
3052
3053
3054
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);
3068 Method = nullptr;
3069 } else {
3071 }
3072
3073 if (!Method)
3074
3076
3077 if (!Method) {
3078
3080
3081 if (!Method && getLangOpts().ObjCAutoRefCount) {
3082 Diag(SelLoc, diag::err_arc_may_not_respond)
3083 << OCIType->getPointeeType() << Sel << RecRange
3084 << SourceRange(SelectorLocs.front(), SelectorLocs.back());
3086 }
3087
3088 if (!Method && (!Receiver || (Receiver))) {
3089
3090
3091
3092 if (OCIType->qual_empty()) {
3095 true,
3096 false);
3097 if (!Methods.empty()) {
3098
3099
3100 Method = Methods[0];
3101
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 }
3118 if (Method &&
3121 } else {
3122
3123 Diag(Loc, diag::err_bad_receiver_type) << ReceiverType << RecRange;
3125 }
3126 }
3127 }
3128
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)
3140 }
3141
3142
3143
3144
3147 {
3149 diag::err_messaging_class_with_direct_method);
3153 }
3154 }
3155 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
3157 }
3158
3159 if (SuperLoc.isValid()) {
3160 {
3161 auto Builder =
3162 Diag(SuperLoc, diag::err_messaging_super_with_direct_method);
3166 } else {
3168 }
3169 }
3170 Diag(Method->getLocation(), diag::note_direct_method_declared_at)
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) {
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,
3230 Method, ClassMessage, SuperLoc.isValid(),
3231 LBracLoc, RBracLoc, RecRange, ReturnType, VK))
3233
3237 diag::err_illegal_message_expr_incomplete_type))
3239
3240
3241
3245 switch (family) {
3247 if (Method)
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 }
3337 if (Method) {
3338 bool IsClassObjectCall = ClassMessage;
3339
3340
3341
3342
3343 if (Receiver && isSelfExpr(Receiver)) {
3345 if (OPT->getObjectType()->isObjCClass()) {
3347 IsClassObjectCall = true;
3348 ReceiverType =
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 =
3386 ().isIgnored(diag::warn_arc_repeated_use_of_weak,
3387 LBracLoc))
3389 }
3390 }
3391 }
3392
3394
3396}
3397
3401 Selector Sel = OSE->getSelector();
3403 auto Pos = S.ReferencedSelectors.find(Sel);
3404 if (Pos != S.ReferencedSelectors.end() && Pos->second == Loc)
3405 S.ReferencedSelectors.erase(Pos);
3406 }
3407}
3408
3409
3410
3411
3418 if (!Receiver)
3420
3421
3422 if (isa(Receiver)) {
3426 Receiver = Result.get();
3427 }
3428
3432 }
3435
3438 nullptr, LBracLoc, SelectorLocs,
3439 RBracLoc, Args);
3440}
3441
3443
3445
3446
3448
3449
3451
3452
3454
3455
3458
3463}
3464
3469}
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> {
3536
3540 bool Diagnose;
3541
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
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
3604 return Visit(e->getRHS());
3605 }
3606
3607
3609 ACCResult left = Visit(e->getTrueExpr());
3610 if (left == ACC_invalid) return ACC_invalid;
3611 return merge(left, Visit(e->getFalseExpr()));
3612 }
3613
3614
3616
3618 }
3619
3620
3621 ACCResult VisitStmtExpr(StmtExpr *e) {
3623 }
3624
3625
3626 ACCResult VisitDeclRefExpr(DeclRefExpr *e) {
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
3694 }
3695
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;
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
3795 if (isa(castedE)) {
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 += ")";
3818 NCE->getAngleBrackets().getEnd());
3820 }
3821 } else {
3822 std::string castCode = "(";
3823 castCode += bridgeKeyword;
3825 castCode += ")";
3828 if (isa(castedE)) {
3830 castCode));
3831 } else {
3832 castCode += "(";
3834 castCode));
3837 ")"));
3838 }
3839 }
3840}
3841
3842template
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
3861 TDNDecl = TD->getDecl();
3862 if (ObjCBridgeRelatedAttr *ObjCBAttr =
3863 getObjCBridgeAttr(TD))
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;
4009 if (TB *ObjCBAttr = getObjCBridgeAttr(TD)) {
4010 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4011 HadTheAttribute = true;
4012 if (Parm->isStr("id"))
4013 return true;
4014
4015
4020 if (Target && isa(Target)) {
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;
4072 if (TB *ObjCBAttr = getObjCBridgeAttr(TD)) {
4073 if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
4074 HadTheAttribute = true;
4075 if (Parm->isStr("id"))
4076 return true;
4077
4079
4084 if (Target && isa(Target)) {
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;
4142 bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeNSCast(
4144 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4145 return;
4146 bool HasObjCBridgeMutableAttr;
4147 bool ObjCBridgeMutableAttrWillNotWarn =
4148 CheckObjCBridgeNSCast(
4149 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);
4150 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4151 return;
4152
4153 if (HasObjCBridgeAttr)
4154 CheckObjCBridgeNSCast(SemaRef, castType, castExpr,
4155 HasObjCBridgeAttr, true);
4156 else if (HasObjCBridgeMutableAttr)
4157 CheckObjCBridgeNSCast(
4158 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, true);
4159 }
4161 bool HasObjCBridgeAttr;
4162 bool ObjCBridgeAttrWillNotWarn = CheckObjCBridgeCFCast(
4164 if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
4165 return;
4166 bool HasObjCBridgeMutableAttr;
4167 bool ObjCBridgeMutableAttrWillNotWarn =
4168 CheckObjCBridgeCFCast(
4169 SemaRef, castType, castExpr, HasObjCBridgeMutableAttr, false);
4170 if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
4171 return;
4172
4173 if (HasObjCBridgeAttr)
4174 CheckObjCBridgeCFCast(SemaRef, castType, castExpr,
4175 HasObjCBridgeAttr, true);
4176 else if (HasObjCBridgeMutableAttr)
4177 CheckObjCBridgeCFCast(
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 }
4249 if (Target && isa(Target))
4250 RelatedClass = cast(Target);
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) {
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) {
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
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
4459
4460 switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
4461
4462 case ACC_invalid:
4463 break;
4464
4465
4466 case ACC_bottom:
4467 case ACC_plusZero:
4469
4470
4471 case ACC_plusOne:
4473 CK_ARCConsumeObject, castExpr, nullptr,
4477 }
4478
4479
4480
4481
4485
4486
4487
4488
4492
4493
4494
4495
4496
4497 if ((!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
4500 (Opc == BO_NE || Opc == BO_EQ))) {
4501 if (Diagnose)
4505 }
4507}
4508
4509
4510
4512
4515
4519
4522 castType = cast->getTypeAsWritten();
4525 castRange = cast->getTypeInfoAsWritten()->getTypeLoc().getSourceRange();
4526 castType = cast->getTypeAsWritten();
4528 } else {
4529 llvm_unreachable("Unexpected ImplicitCastExpr");
4530 }
4531
4534
4537
4540}
4541
4542
4543
4547
4548 if (ParenExpr *pe = dyn_cast(e)) {
4550 return new (Context) ParenExpr(pe->getLParen(), pe->getRParen(), sub);
4551 } else if (UnaryOperator *uo = dyn_cast(e)) {
4552 assert(uo->getOpcode() == UO_Extension);
4556 uo->getOperatorLoc(), false,
4559 assert(!gse->isResultDependent());
4560 assert(!gse->isTypePredicate());
4561
4562 unsigned n = gse->getNumAssocs();
4565 subExprs.reserve(n);
4566 subTypes.reserve(n);
4568 subTypes.push_back(assoc.getTypeSourceInfo());
4569 Expr *sub = assoc.getAssociationExpr();
4570 if (assoc.isSelected())
4572 subExprs.push_back(sub);
4573 }
4574
4576 Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
4577 subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
4578 gse->containsUnexpandedParameterPack(), gse->getResultIndex());
4579 } else {
4580 assert(isa(e) && "bad form of unbridged cast!");
4581 return cast(e)->getSubExpr();
4582 }
4583}
4584
4592 if (isa(canCastType) &&
4598 return !ObjI->isArcWeakrefUnavailable();
4599 }
4600 return true;
4601}
4602
4603
4605 Expr *curExpr = e, *prevExpr = nullptr;
4606
4607
4608
4609 while (true) {
4610 if (auto *pe = dyn_cast(curExpr)) {
4611 prevExpr = curExpr;
4612 curExpr = pe->getSubExpr();
4613 continue;
4614 }
4615
4616 if (auto *ce = dyn_cast(curExpr)) {
4617 if (auto *ice = dyn_cast(ce))
4618 if (ice->getCastKind() == CK_ARCReclaimReturnedObject) {
4619 if (!prevExpr)
4620 return ice->getSubExpr();
4621 if (auto *pe = dyn_cast(prevExpr))
4622 pe->setSubExpr(ice->getSubExpr());
4623 else
4624 cast(prevExpr)->setSubExpr(ice->getSubExpr());
4625 return e;
4626 }
4627
4628 prevExpr = curExpr;
4629 curExpr = ce->getSubExpr();
4630 continue;
4631 }
4632
4633
4634 break;
4635 }
4636
4637 return e;
4638}
4639
4644 Expr *SubExpr) {
4648 SubExpr = SubResult.get();
4649
4652
4654
4655 bool MustConsume = false;
4657
4658 CK = CK_Dependent;
4660
4662 : CK_CPointerToObjCPointerCast);
4663 switch (Kind) {
4665 break;
4666
4668 bool br = isKnownName("CFBridgingRelease");
4669 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4670 << 2
4671 << FromType
4673 << T
4675 << Kind;
4676 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4678 Diag(BridgeKeywordLoc, diag::note_arc_bridge_transfer)
4679 << FromType << br
4681 br ? "CFBridgingRelease "
4682 : "__bridge_transfer ");
4683
4685 break;
4686 }
4687
4689
4690 MustConsume = true;
4691 break;
4692 }
4694
4695 CK = CK_BitCast;
4696 switch (Kind) {
4698
4699
4701 break;
4702
4704
4708 break;
4709
4711 bool br = isKnownName("CFBridgingRetain");
4712 Diag(BridgeKeywordLoc, diag::err_arc_bridge_cast_wrong_kind)
4714 << FromType
4715 << 2
4716 << T
4718 << Kind;
4719
4720 Diag(BridgeKeywordLoc, diag::note_arc_bridge)
4722 Diag(BridgeKeywordLoc, diag::note_arc_bridge_retained)
4723 << T << br
4725 br ? "CFBridgingRetain " : "__bridge_retained");
4726
4728 break;
4729 }
4730 }
4731 } else {
4732 Diag(LParenLoc, diag::err_arc_bridge_cast_incompatible)
4733 << FromType << T << Kind
4737 }
4738
4740 BridgeKeywordLoc,
4741 TSInfo, SubExpr);
4742
4743 if (MustConsume) {
4747 }
4748
4750}
4751
4757 Expr *SubExpr) {
4763 if (!TSInfo)
4766 SubExpr);
4767}
4768
4773
4774
4775 if (!CurMethod)
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787 bool IsClassMethod = CurMethod->isClassMethod();
4788
4789 bool LookForIvars;
4790 if (Lookup.empty())
4791 LookForIvars = true;
4792 else if (IsClassMethod)
4793 LookForIvars = false;
4794 else
4798 if (LookForIvars) {
4803
4804 if (IsClassMethod) {
4807 }
4808
4809
4814
4815
4816 return IV;
4817 }
4819
4825 Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
4826 }
4827 }
4830
4832 dyn_cast(Lookup.getFoundDecl())) {
4833 Diag(Loc, diag::err_ivar_use_in_class_method) << IV->getDeclName();
4835 }
4836 }
4837
4838
4840}
4841
4844 bool AllowBuiltinCreation) {
4845
4851 cast(Ivar.get()));
4852
4853 if (Lookup.empty() && II && AllowBuiltinCreation)
4855
4856
4858}
4859
4865 "should not reference ivar from this context");
4866
4868 assert(IFace && "should not reference ivar from this context");
4869
4870
4871
4874
4875
4878
4879
4880
4888 false,
4889 false);
4892
4896
4898
4903
4907
4912 }
4916
4918}
4919
4926
4927
4928
4929
4933 CK_CPointerToObjCPointerCast);
4934 return LHSTy;
4935 }
4939 CK_CPointerToObjCPointerCast);
4940 return RHSTy;
4941 }
4942
4946 CK_CPointerToObjCPointerCast);
4947 return LHSTy;
4948 }
4952 CK_CPointerToObjCPointerCast);
4953 return RHSTy;
4954 }
4955
4959 return LHSTy;
4960 }
4964 return RHSTy;
4965 }
4966
4968
4970
4971 return LHSTy;
4972 }
4977 QualType compositeType = LHSTy;
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4993 .isNull()) {
4994
5000 RHSOPT->isObjCQualifiedIdType()) &&
5002 true)) {
5003
5004
5005
5006
5010 } else {
5011 Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
5017 return incompatTy;
5018 }
5019
5022 return compositeType;
5023 }
5024
5027
5028
5029 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5032 LHS = RHS = true;
5034 }
5040
5042
5044 return destType;
5045 }
5048
5049
5050 Diag(QuestionLoc, diag::err_cond_voidptr_arc)
5053 LHS = RHS = true;
5055 }
5061
5063
5065 return destType;
5066 }
5068}
5069
5071 bool Diagnose) {
5073 return false;
5074
5076 if (!PT)
5077 return false;
5079
5080
5081
5082
5084 if (OpaqueValueExpr *OV = dyn_cast(SrcExpr))
5085 if (OV->getSourceExpr())
5087
5088 if (auto *SL = dyn_cast(SrcExpr)) {
5089 if (!PT->isObjCIdType() && !(ID && ID->getIdentifier()->isStr("NSString")))
5090 return false;
5091 if (!SL->isOrdinary())
5092 return false;
5093
5094 if (Diagnose) {
5095 Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)
5098 }
5099 return true;
5100 }
5101
5102 if ((isa(SrcExpr) || isa(SrcExpr) ||
5103 isa(SrcExpr) || isa(SrcExpr) ||
5104 isa(SrcExpr)) &&
5107 if (!ID || !ID->getIdentifier()->isStr("NSNumber"))
5108 return false;
5109 if (Diagnose) {
5110 Diag(SrcExpr->getBeginLoc(), diag::err_missing_atsign_prefix)
5111 << 1
5113 Expr *NumLit =
5115 if (NumLit)
5116 Exp = NumLit;
5117 }
5118 return true;
5119 }
5120
5121 return false;
5122}
5123
5124
5127 assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) &&
5128 "Unknown Objective-C Boolean value!");
5135 Result.isSingleResult()) {
5137 if (TypedefDecl *TD = dyn_cast(ND))
5139 }
5140 }
5143 return new (Context)
5145}
5146
5151 auto FindSpecVersion =
5152 [&](StringRef Platform) -> std::optional {
5153 auto Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
5155 });
5156
5157
5158 if (Spec == AvailSpecs.end() && Platform == "maccatalyst") {
5159 Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
5161 });
5162 }
5163 if (Spec == AvailSpecs.end())
5164 return std::nullopt;
5166 };
5167
5168 VersionTuple Version;
5169 if (auto MaybeVersion =
5171 Version = *MaybeVersion;
5172
5173
5174
5176 Context->HasPotentialAvailabilityViolations = true;
5177
5178 return new (Context)
5180}
5181
5182
5183
5186 if (type->isObjCObjectPointerType()) {
5187 return CK_BitCast;
5188 } else if (type->isBlockPointerType()) {
5190 return CK_BlockPointerToObjCPointerCast;
5191 } else {
5192 assert(type->isPointerType());
5193 return CK_CPointerToObjCPointerCast;
5194 }
5195}
5196
5200 default:
5201 break;
5202 case Stmt::ObjCStringLiteralClass:
5203
5205 case Stmt::ObjCArrayLiteralClass:
5206
5208 case Stmt::ObjCDictionaryLiteralClass:
5209
5211 case Stmt::BlockExprClass:
5213 case Stmt::ObjCBoxedExprClass: {
5214 Expr *Inner = cast(FromE)->getSubExpr()->IgnoreParens();
5215 switch (Inner->getStmtClass()) {
5216 case Stmt::IntegerLiteralClass:
5217 case Stmt::FloatingLiteralClass:
5218 case Stmt::CharacterLiteralClass:
5219 case Stmt::ObjCBoolLiteralExprClass:
5220 case Stmt::CXXBoolLiteralExprClass:
5221
5223 case Stmt::ImplicitCastExprClass: {
5224 CastKind CK = cast(Inner)->getCastKind();
5225
5226 if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast)
5228 break;
5229 }
5230 default:
5231 break;
5232 }
5234 }
5235 }
5237}
Defines the clang::ASTContext interface.
static StringRef bytes(const std::vector< T, Allocator > &v)
Defines enum values for all the target-independent builtin functions.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::Preprocessor interface.
static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)
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...
static QualType stripObjCInstanceType(ASTContext &Context, QualType T)
static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange, QualType castType, ARCConversionTypeClass castACTC, Expr *castExpr, Expr *realCast, ARCConversionTypeClass exprACTC, CheckedConversionKind CCK)
static ObjCInterfaceDecl * LookupObjCInterfaceDeclForLiteral(Sema &S, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)
Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
static ObjCMethodDecl * findMethodInCurrentClass(Sema &S, Selector Sel)
static void checkCocoaAPI(Sema &S, const ObjCMessageExpr *Msg)
static ObjCMethodDecl * LookupDirectMethodInGlobalPool(Sema &S, Selector Sel, bool &onlyDirect, bool &anyDirect)
static Expr * maybeUndoReclaimObject(Expr *e)
Look for an ObjCReclaimReturnedObject cast and destroy it.
static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr, bool &HadTheAttribute, bool warn)
static void CheckObjCDictionaryLiteralDuplicateKeys(Sema &S, ObjCDictionaryLiteral *Literal)
Check for duplicate keys in an ObjC dictionary literal.
static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, SourceLocation Loc, SemaObjC::ObjCLiteralKind LiteralKind)
Validates ObjCInterfaceDecl availability.
static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind(SemaObjC::ObjCLiteralKind LiteralKind)
Maps ObjCLiteralKind to NSClassIdKindKind.
static bool isAnyCLike(ARCConversionTypeClass ACTC)
static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc, ObjCMethodDecl *Method, SourceLocation LParenLoc, SourceLocation RParenLoc, bool WarnMultipleSelectors)
static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S, SourceLocation AtLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, ObjCMethodDecl *Method, ObjCMethodList &MethList)
static void applyCocoaAPICheck(Sema &S, const ObjCMessageExpr *Msg, unsigned DiagID, bool(*refactor)(const ObjCMessageExpr *, const NSAPI &, edit::Commit &))
static ObjCMethodDecl * LookupDirectMethodInMethodList(Sema &S, Selector Sel, ObjCMethodList &MethList, bool &onlyDirect, bool &anyDirect)
static ObjCBridgeRelatedAttr * ObjCBridgeRelatedAttrFromType(QualType T, TypedefNameDecl *&TDNDecl)
static T * getObjCBridgeAttr(const TypedefType *TD)
static ARCConversionTypeClass classifyTypeForARCConversion(QualType type)
static bool isAnyRetainable(ARCConversionTypeClass ACTC)
static void RemoveSelectorFromWarningCache(SemaObjC &S, Expr *Arg)
@ ACTC_voidPtr
void* might be a normal C type, or it might a CF type.
@ ACTC_retainable
id, void (^)()
@ ACTC_coreFoundation
struct A*
@ ACTC_indirectRetainable
id*, id***, void (^*)(),
@ ACTC_none
int, void, struct A
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...
static const ObjCMethodDecl * findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD, QualType instancetype)
Look for an ObjC method whose result type exactly matches the given type.
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...
static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M)
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...
static void checkFoundationAPI(Sema &S, SourceLocation Loc, const ObjCMethodDecl *Method, ArrayRef< Expr * > Args, QualType ReceiverType, bool IsClassObjectCall)
static void addFixitForObjCARCConversion(Sema &S, DiagBuilderT &DiagB, CheckedConversionKind CCK, SourceLocation afterLParen, QualType castType, Expr *castExpr, Expr *realCast, const char *bridgeKeyword, const char *CFBridgeName)
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.
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()
TranslationUnitDecl * getTranslationUnitDecl() const
const ConstantArrayType * getAsConstantArrayType(QualType T) const
void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl)
QualType areCommonBaseCompatible(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
bool ObjCQualifiedIdTypesAreCompatible(const ObjCObjectPointerType *LHS, const ObjCObjectPointerType *RHS, bool ForCompare)
ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an ObjCQualifiedIDType.
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType, const Attr *attr=nullptr) const
void getObjCEncodingForType(QualType T, std::string &S, const FieldDecl *Field=nullptr, QualType *NotEncodedT=nullptr) const
Emit the Objective-CC type encoding for the given type T into S.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
void setObjCNSStringType(QualType T)
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getObjCSelRedefinitionType() const
Retrieve the type that 'SEL' has been defined to, which may be different from the built-in 'SEL' if '...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT)
canAssignObjCInterfaces - Return true if the two interface types are compatible for assignment from R...
bool isObjCSelType(QualType T) const
bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT, ObjCInterfaceDecl *IDecl)
QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in QT's qualified-id protocol list adopt...
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
SelectorTable & Selectors
TypedefDecl * getBOOLDecl() const
Retrieve declaration of 'BOOL' typedef.
QualType getObjCInstanceType()
Retrieve the Objective-C "instancetype" type, if already known; otherwise, returns a NULL type;.
QualType getObjCProtoType() const
Retrieve the type of the Objective-C Protocol class.
CanQualType ObjCBuiltinIdTy
void setBOOLDecl(TypedefDecl *TD)
Save declaration of 'BOOL' typedef.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType UnsignedLongTy
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getStringLiteralArrayType(QualType EltTy, unsigned Length) const
Return a type for a constant array for a string literal of the specified element type and length.
QualType getBOOLType() const
type of 'BOOL' type.
CanQualType PseudoObjectTy
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
CanQualType ObjCBuiltinBoolTy
QualType getObjCObjectType(QualType Base, ObjCProtocolDecl *const *Protocols, unsigned NumProtocols) const
Legacy interface: cannot provide type arguments or __kindof.
static bool isObjCNSObjectType(QualType Ty)
Return true if this is an NSObject object with its NSObject attribute set.
QualType getObjCIdType() const
Represents the Objective-CC id type.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl)
ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's protocol list adopt all protocols in Q...
QualType getObjCConstantStringInterface() const
QualType getObjCIdRedefinitionType() const
Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...
const TargetInfo & getTargetInfo() const
QualType getObjCNSStringType() const
QualType getWideCharType() const
Return the type of wide characters.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
unsigned getIndexTypeCVRQualifiers() const
An attributed type is a type to which a type attribute has been applied.
static std::optional< NullabilityKind > stripOuterNullability(QualType &T)
Strip off the top-level nullability annotation on the given type, if it's there.
One specifier in an @available expression.
StringRef getPlatform() const
VersionTuple getVersion() const
A builtin binary operation expression such as "x + y" or "x <= y".
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.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
QualType withConst() const
Retrieves a version of this type with const applied.
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
void setExprNeedsCleanups(bool SideEffects)
ConditionalOperator - The ?: ternary operator.
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...
Decl * getNonClosureAncestor()
Find the nearest non-closure ancestor of this context, i.e.
const BlockDecl * getInnermostBlockDecl() const
Return this DeclContext if it is a BlockDecl.
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
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() 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
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
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.
Represents a function declaration or definition.
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.
@ FoundOverloaded
Name lookup found a set of overloaded functions that met the criteria.
@ FoundUnresolvedValue
Name lookup found an unresolvable value declaration and cannot yet complete.
@ 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.
@ NotFoundInCurrentInstantiation
No entity found met the criteria within the current instantiation,, but there were dependent base cla...
@ Found
Name lookup found a single declaration that met the criteria.
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...
Interfaces are the core concept in Objective-C for object oriented design.
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
unsigned param_size() 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.
QualType getSendResultType() const
Determine the type of an expression that sends a message to this function.
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
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isInstanceMethod() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
QualType getReturnType() const
ObjCImplementationControl getImplementationControl() 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 a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Represents one property declaration in an Objective-C interface.
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
IdentifierTable & getIdentifierTable()
SelectorTable & getSelectorTable()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
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 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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Selector getNullarySelector(const IdentifierInfo *ID)
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
Selector getUnarySelector(const IdentifierInfo *ID)
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
bool isNull() const
Determine whether this is the empty selector.
ObjCStringFormatFamily getStringFormatFamily() const
unsigned getNumArgs() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
ObjCMethodDecl * ValueWithBytesObjCTypeMethod
The declaration of the valueWithBytes:objCType: method.
ExprResult BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)
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.
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.
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.
ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD)
Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...
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.
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number)
BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the numeric literal expression.
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)
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc)
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, QualType DestType, QualType SrcType, Expr *&SrcExpr, bool Diagnose=true)
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
ObjCInterfaceDecl * NSArrayDecl
The declaration of the Objective-C NSArray class.
ExprResult ActOnClassPropertyRefExpr(const IdentifierInfo &receiverName, const IdentifierInfo &propertyName, SourceLocation receiverNameLoc, SourceLocation propertyNameLoc)
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.
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)
void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr)
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.
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.
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 ...
ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S)
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)
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)
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr)
bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, bool Diagnose=true)
ObjCMethodDecl * tryCaptureObjCSelf(SourceLocation Loc)
Try to capture an implicit reference to 'self'.
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, ArrayRef< Expr * > Strings)
ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value)
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)
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.
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,...
ExprResult ParseObjCProtocolExpression(IdentifierInfo *ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, SourceLocation ProtoIdLoc, SourceLocation RParenLoc)
ParseObjCProtocolExpression - Build protocol expression for @protocol.
ExprResult BuildInstanceMessageImplicit(Expr *Receiver, QualType ReceiverType, SourceLocation Loc, Selector Sel, ObjCMethodDecl *Method, MultiExprArg Args)
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.
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,...
ExprResult ActOnInstanceMessage(Scope *S, Expr *Receiver, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx)
ExprResult BuildIvarRefExpr(Scope *S, SourceLocation Loc, ObjCIvarDecl *IV)
ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, Selector Sel, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args)
CastKind PrepareCastToObjCObjectPointer(ExprResult &E)
Prepare a conversion of the given expression to an ObjC object pointer type.
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)
void EmitRelatedResultTypeNoteForReturn(QualType destType)
Given that we had incompatible pointer types in a return statement, check whether we're in a method w...
void diagnoseARCUnbridgedCast(Expr *e)
Given that we saw an expression with the ARCUnbridgedCastTy placeholder type, complain bitterly.
ObjCMethodDecl * LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance)
LookupMethodInQualifiedType - Lookups up a method in protocol qualifier list of a qualified objective...
bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind)
bool CheckObjCARCUnavailableWeakConversion(QualType castType, QualType ExprType)
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.
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.
bool isSelfExpr(Expr *RExpr)
Private Helper predicate to check for 'self'.
ExprResult ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef< AvailabilitySpec > AvailSpecs, SourceLocation AtLoc, SourceLocation RParen)
bool isKnownName(StringRef name)
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
Sema - This implements semantic analysis and AST building for C.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
ExprResult PerformContextuallyConvertToObjCPointer(Expr *From)
PerformContextuallyConvertToObjCPointer - Perform a contextual conversion of the expression From to a...
Scope * getCurScope() const
Retrieve the parser's current scope.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
void DiagnoseSentinelCalls(const NamedDecl *D, SourceLocation Loc, ArrayRef< Expr * > Args)
DiagnoseSentinelCalls - This routine checks whether a call or message-send is to a declaration with t...
bool FormatStringHasSArg(const StringLiteral *FExpr)
ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, CorrectionCandidateCallback *CCC=nullptr, bool IsInlineAsmIdentifier=false, Token *KeywordReplacement=nullptr)
ExprResult MaybeBindToTemporary(Expr *E)
MaybeBindToTemporary - If the passed in expression has a record type with a non-trivial destructor,...
FPOptionsOverride CurFPFeatureOverrides()
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME)
This is not an AltiVec-style cast or or C++ direct-initialization, so turn the ParenListExpr into a s...
bool LookupBuiltin(LookupResult &R)
Lookup a builtin function, when name lookup would otherwise fail.
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
bool tryCaptureVariable(ValueDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt)
Try to capture the given variable.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
ExprResult DefaultArgumentPromotion(Expr *E)
DefaultArgumentPromotion (C99 6.5.2.2p6).
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
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)
ActOnCXXBoolLiteral - Parse {true,false} literals.
const LangOptions & LangOpts
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)
Perform marking for a reference to an arbitrary declaration.
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
sema::FunctionScopeInfo * getCurFunction() const
ExprResult DefaultLvalueConversion(Expr *E)
void maybeExtendBlockObject(ExprResult &E)
Do an explicit extend of the given block pointer if we're in ARC.
static bool isCast(CheckedConversionKind CCK)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ObjCMethodDecl * SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance, SmallVectorImpl< ObjCMethodDecl * > &Methods)
DeclContext * getFunctionLevelDeclContext(bool AllowLambda=false) const
If AllowLambda is true, treat lambda as function.
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.
sema::FunctionScopeInfo * getCurFunctionAvailabilityContext()
Retrieve the current function, if any, that should be analyzed for potential availability violations.
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
ExprResult forceUnknownAnyToType(Expr *E, QualType ToType)
Force an expression with unknown-type to an expression of the given type.
SourceManager & SourceMgr
DiagnosticsEngine & Diags
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
ExprResult ActOnIntegerConstant(SourceLocation Loc, int64_t Val)
sema::FunctionScopeInfo * getEnclosingFunction() const
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
ExprResult checkUnknownAnyArg(SourceLocation callLoc, Expr *result, QualType ¶mType)
Type-check an expression that's being passed to an __unknown_anytype parameter.
llvm::SmallVector< std::pair< SourceLocation, const BlockDecl * >, 1 > ImplicitlyRetainedSelfLocs
List of SourceLocations where 'self' is implicitly retained inside a block.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
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
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
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.
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
StringRef getString() const
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
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.
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
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 isBuiltinType() const
Helper methods to distinguish type categories.
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 isObjCBoxableRecordType() const
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 ObjCObjectType * getAsObjCInterfaceType() 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 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)
Represents a variable declaration or definition.
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.
void recordUseOfWeak(const ExprT *E, bool IsRead=true)
Record that a weak object was accessed.
bool ObjCIsDesignatedInit
True when this is a method marked as a designated initializer.
bool ObjCShouldCallSuper
A flag that is set when parsing a method that must call super's implementation, such as -dealloc,...
bool ObjCWarnForNoInitDelegation
This starts true for a secondary initializer method and will be set to false if there is an invocatio...
bool ObjCIsSecondaryInit
True when this is an initializer method not marked as a designated initializer within a class that ha...
bool ObjCWarnForNoDesignatedInitChain
This starts true for a method marked as designated initializer and will be set to false if there is a...
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
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.
uint32_t Literal
Literals are represented as positive integers.
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.
The JSON file list parser is used to communicate input to InstallAPI.
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.
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_None
No particular method family.
@ Parameter
The parameter type of a method or function.
@ Result
The result type of a method or function.
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.
ActionResult< Expr * > ExprResult
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.
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
ActionResult< Decl * > DeclResult
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
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.
MutableArrayRef< Expr * > MultiExprArg
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