clang: lib/CodeGen/CGObjC.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
26#include "llvm/Analysis/ObjCARCUtil.h"
27#include "llvm/BinaryFormat/MachO.h"
28#include "llvm/IR/Constants.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/InlineAsm.h"
31#include
32using namespace clang;
33using namespace CodeGen;
34
35typedef llvm::PointerIntPairllvm::Value\*,1,bool TryEmitResult;
41
42
43
46 return llvm::ConstantPointerNull::get(castllvm::PointerType(type));
47}
48
49
50llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)
51{
52 llvm::Constant *C =
54 return C;
55}
56
57
58
59
60
61
62llvm::Value *
64
65
66 const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod();
67 const Expr *SubExpr = E->getSubExpr();
68
69 if (E->isExpressibleAsConstantInitializer()) {
71 return ConstEmitter.tryEmitAbstract(E, E->getType());
72 }
73
74 assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method");
76
77
78
79
82 llvm::Value *Receiver = Runtime.GetClass(*this, ClassDecl);
83
87
88
89
91 if (ValueType->isObjCBoxableRecordType()) {
92
93
99
100
101 std::string Str;
104
105
109
111 } else {
113 }
114
117 Args, ClassDecl, BoxingMethod);
120}
121
127 if (!ALE)
128 DLE = cast(E);
129
130
134 StringRef ConstantName = ALE ? "__NSArray0__" : "__NSDictionary0__";
136 llvm::Constant *Constant =
140 castllvm::LoadInst(Ptr)->setMetadata(
141 llvm::LLVMContext::MD_invariant_load,
144 }
145
146
148 NumElements);
152 0);
153
154
157 if (DLE)
159
160
161
163 bool TrackNeededObjects =
166
167
168 for (uint64_t i = 0; i < NumElements; i++) {
169 if (ALE) {
170
174
177 if (TrackNeededObjects) {
178 NeededObjects.push_back(value);
179 }
180 } else {
181
187
188
194 if (TrackNeededObjects) {
195 NeededObjects.push_back(keyValue);
196 NeededObjects.push_back(valueValue);
197 }
198 }
199 }
200
201
207 if (DLE) {
208 argDecl = *PI++;
211 }
212 argDecl = *PI;
214 llvm::Value *Count =
217
218
223 assert(InterfacePointerType && "Unexpected InterfacePointerType - null");
227 llvm::Value *Receiver = Runtime.GetClass(*this, Class);
228
229
232 Receiver, Args, Class, MethodWithObjects);
233
234
235
236
237
238 if (TrackNeededObjects) {
240 }
241
244}
245
248}
249
253}
254
255
257
258
259
260
262}
263
265
267}
268
269
270
271
276
277
278 llvm::Type *ExpLLVMTy = CGF.ConvertType(ExpT);
279 if (ExpLLVMTy == Result.getScalarVal()->getType())
281
282
284 ExpLLVMTy));
285}
286
287
288
289static bool
292
293
294
297
298
299 if (auto opaque = dyn_cast(receiver)) {
300 if (opaque->getSourceExpr())
301 receiver = opaque->getSourceExpr()->IgnoreParens();
302 }
303
304 const ImplicitCastExpr *ice = dyn_cast(receiver);
305 if (!ice || ice->getCastKind() != CK_LValueToRValue) return true;
307
308
309 if (auto opaque = dyn_cast(receiver)) {
310 if (opaque->getSourceExpr())
311 receiver = opaque->getSourceExpr()->IgnoreParens();
312 }
313
314
316 return true;
317
318
319 if (isa(receiver) || isa(receiver))
320 return false;
321
322
324 if (!declRef) return true;
325 const VarDecl *var = dyn_cast(declRef->getDecl());
326 if (!var) return true;
327
328
329
330 return (var->hasLocalStorage() &&
331 !var->hasAttr());
332 }
333
336
337 return false;
338
340
341 return false;
342 }
343
344 llvm_unreachable("invalid receiver kind");
345}
346
347
348
352 if (auto CE = dyn_cast(E)) {
353 if (CE->getCastKind() == CK_LValueToRValue) {
355 return CE->getSubExpr();
356 }
357 }
358
359 return nullptr;
360}
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
379 bool isClassMessage) {
380 auto &CGM = CGF.CGM;
381 if (!CGM.getCodeGenOpts().ObjCConvertMessagesToRuntimeCalls)
382 return std::nullopt;
383
384 auto &Runtime = CGM.getLangOpts().ObjCRuntime;
387 if (isClassMessage &&
388 Runtime.shouldUseRuntimeFunctionsForAlloc() &&
390
391
394
395
397 Args.size() == 1 && Args.front().getType()->isPointerType() &&
399 const llvm::Value* arg = Args.front().getKnownRValue().getScalarVal();
400 if (isallvm::ConstantPointerNull(arg))
403 return std::nullopt;
404 }
405 }
406 break;
407
411 Runtime.shouldUseARCFunctionsForRetainRelease())
413 break;
414
418 Runtime.shouldUseARCFunctionsForRetainRelease())
420 break;
421
425 Runtime.shouldUseARCFunctionsForRetainRelease()) {
427 return nullptr;
428 }
429 break;
430
431 default:
432 break;
433 }
434 return std::nullopt;
435}
436
441 bool isClassMessage) {
442 if (std::optional<llvm::Value *> SpecializedResult =
444 Sel, Method, isClassMessage)) {
446 }
447 return GenerateMessageSend(CGF, Return, ResultType, Sel, Receiver, Args, OID,
448 Method);
449}
450
453 llvm::UniqueVector<const ObjCProtocolDecl *> &PDs) {
456 PDs.insert(Can);
457 return;
458 }
459
460 for (const auto *ParentPD : PD->protocols())
462}
463
464std::vector<const ObjCProtocolDecl *>
467 std::vector<const ObjCProtocolDecl *> RuntimePds;
468 llvm::DenseSet<const ObjCProtocolDecl *> NonRuntimePDs;
469
470 for (; begin != end; ++begin) {
471 const auto *It = *begin;
472 const auto *Can = It->getCanonicalDecl();
473 if (Can->isNonRuntimeProtocol())
474 NonRuntimePDs.insert(Can);
475 else
476 RuntimePds.push_back(Can);
477 }
478
479
480 if (NonRuntimePDs.empty())
481 return RuntimePds;
482
483
484
485
486
487 llvm::UniqueVector<const ObjCProtocolDecl *> FirstImpliedProtos;
488 for (const auto *PD : NonRuntimePDs)
490
491
492
493 llvm::DenseSet<const ObjCProtocolDecl *> AllImpliedProtocols;
494 for (const auto *PD : RuntimePds) {
495 const auto *Can = PD->getCanonicalDecl();
496 AllImpliedProtocols.insert(Can);
497 Can->getImpliedProtocols(AllImpliedProtocols);
498 }
499
500
501
502
503 for (const auto *PD : FirstImpliedProtos) {
504 PD->getImpliedProtocols(AllImpliedProtocols);
505 }
506
507
508
509
510
511 for (const auto *PD : FirstImpliedProtos) {
512 if (!AllImpliedProtocols.contains(PD)) {
513 RuntimePds.push_back(PD);
514 }
515 }
516
517 return RuntimePds;
518}
519
520
521
522
523static std::optional<llvm::Value *>
526 if (!Runtime.shouldUseRuntimeFunctionForCombinedAllocInit())
527 return std::nullopt;
528
529
534 return std::nullopt;
535
536
537
538 auto *SubOME =
540 if (!SubOME)
541 return std::nullopt;
542 Selector SubSel = SubOME->getSelector();
543
544 if (!SubOME->getType()->isObjCObjectPointerType() ||
546 return std::nullopt;
547
548 llvm::Value *Receiver = nullptr;
549 switch (SubOME->getReceiverKind()) {
551 if (!SubOME->getInstanceReceiver()->getType()->isObjCClassType())
552 return std::nullopt;
553 Receiver = CGF.EmitScalarExpr(SubOME->getInstanceReceiver());
554 break;
555
557 QualType ReceiverType = SubOME->getClassReceiver();
560 assert(ID && "null interface should be impossible here");
562 break;
563 }
566 return std::nullopt;
567 }
568
570}
571
574
575
576
577
578 bool isDelegateInit = E->isDelegateInitCall();
579
581
582
583
586 if (auto lvalueExpr = findWeakLValue(E->getInstanceReceiver())) {
590 }
591 }
592
595
596
597
598
599
600 bool retainSelf =
601 (!isDelegateInit &&
603 method &&
604 method->hasAttr());
605
607 bool isSuperMessage = false;
608 bool isClassMessage = false;
610
612 llvm::Value *Receiver = nullptr;
613 switch (E->getReceiverKind()) {
615 ReceiverType = E->getInstanceReceiver()->getType();
617 if (retainSelf) {
619 E->getInstanceReceiver());
620 Receiver = ter.getPointer();
621 if (ter.getInt()) retainSelf = false;
622 } else
624 break;
625
627 ReceiverType = E->getClassReceiver();
629 assert(OID && "Invalid Objective-C class message send");
630 Receiver = Runtime.GetClass(*this, OID);
631 isClassMessage = true;
632 break;
633 }
634
636 ReceiverType = E->getSuperType();
638 isSuperMessage = true;
639 break;
640
642 ReceiverType = E->getSuperType();
644 isSuperMessage = true;
645 isClassMessage = true;
646 break;
647 }
648
649 if (retainSelf)
651
652
653
654
655 if (getLangOpts().ObjCAutoRefCount && method &&
656 method->hasAttr() &&
659
661
663 EmitCallArgs(Args, method, E->arguments(), AbstractCallee(method));
664
665
666
667
668
669
670
671
672 if (isDelegateInit) {
674 "delegate init calls should only be marked in ARC");
675
676
680 }
681
683 if (isSuperMessage) {
684
686 bool isCategoryImpl = isa(OMD->getDeclContext());
688 E->getSelector(),
690 isCategoryImpl,
691 Receiver,
692 isClassMessage,
693 Args,
694 method);
695 } else {
696
698 *this, Return, ResultType, E->getSelector(), Receiver, Args, OID,
699 method, isClassMessage);
700 }
701
702
703
704 if (isDelegateInit) {
707 llvm::Value *newSelf = result.getScalarVal();
708
709
710
712 newSelf = Builder.CreateBitCast(newSelf, selfTy);
713
715 }
716
718}
719
720namespace {
724
728
729 bool isCategory = isa(impl);
730
731
733
738 iface,
739 isCategory,
740 self,
741 false,
742 args,
743 method);
744 }
745};
746}
747
748
749
750
755
756 if (OMD->hasAttr())
757 DebugInfo = nullptr;
758
760
763 Fn->setVisibility(llvm::Function::HiddenVisibility);
766 } else {
768 }
769
773
775
777 CurEHLocation = OMD->getEndLoc();
778
781
783
784
785
786
788 }
789
790
796 if (ident->isStr("dealloc"))
798 }
799}
800
803
804
805
809 assert(isa(OMD->getBody()));
813}
814
815
816
818 bool isAtomic, bool hasStrong) {
820
821 llvm::Value *src =
824
825
826
828
832
837
842}
843
844
845
846
848
849
850 return false;
851}
852
853
854
856 llvm::Triple::ArchType arch) {
857
858
859
860
861
863}
864
865namespace {
866 class PropertyImplStrategy {
867 public:
868 enum StrategyKind {
869
870
871 Native,
872
873
874 GetSetProperty,
875
876
877
878 SetPropertyAndExpressionGet,
879
880
881 CopyStruct,
882
883
884
886 };
887
888 StrategyKind getKind() const { return StrategyKind(Kind); }
889
890 bool hasStrongMember() const { return HasStrong; }
891 bool isAtomic() const { return IsAtomic; }
892 bool isCopy() const { return IsCopy; }
893
894 CharUnits getIvarSize() const { return IvarSize; }
895 CharUnits getIvarAlignment() const { return IvarAlignment; }
896
899
900 private:
901 LLVM_PREFERRED_TYPE(StrategyKind)
902 unsigned Kind : 8;
903 LLVM_PREFERRED_TYPE(bool)
904 unsigned IsAtomic : 1;
905 LLVM_PREFERRED_TYPE(bool)
906 unsigned IsCopy : 1;
907 LLVM_PREFERRED_TYPE(bool)
908 unsigned HasStrong : 1;
909
912 };
913}
914
915
916PropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,
920
923 HasStrong = false;
924
925
929 IvarSize = TInfo.Width;
930 IvarAlignment = TInfo.Align;
931
932
933
934
935 if (IsCopy) {
936 Kind = IsAtomic ? GetSetProperty : SetPropertyAndExpressionGet;
937 return;
938 }
939
940
942
944
945
946
947
948
949 } else if (CGM.getLangOpts().ObjCAutoRefCount && !IsAtomic) {
950
951
952
953
954
955
958 else
959 Kind = SetPropertyAndExpressionGet;
960 return;
961
962
963
964
965 } else if (!IsAtomic) {
966 Kind = SetPropertyAndExpressionGet;
967 return;
968
969
970 } else {
971 Kind = GetSetProperty;
972 return;
973 }
974 }
975
976
977 if (!IsAtomic) {
979 return;
980 }
981
982
983
986 return;
987 }
988
989
990
991
996 return;
997 }
998
999
1002 HasStrong = recordType->getDecl()->hasObjectMember();
1003
1004
1005
1006
1007 if (HasStrong) {
1008 Kind = CopyStruct;
1009 return;
1010 }
1011
1012
1013
1014
1015
1016
1017 if (!IvarSize.isPowerOfTwo()) {
1018 Kind = CopyStruct;
1019 return;
1020 }
1021
1022 llvm::Triple::ArchType arch =
1024
1025
1026
1027
1029 Kind = CopyStruct;
1030 return;
1031 }
1032
1033
1034
1036 Kind = CopyStruct;
1037 return;
1038 }
1039
1040
1041 Kind = Native;
1042}
1043
1044
1045
1046
1047
1050 llvm::Constant *AtomicHelperFn =
1053 assert(OMD && "Invalid call to generate getter (empty method)");
1055
1057
1059}
1060
1063 if (!getter) return true;
1064
1065
1066
1067
1068
1069
1070
1072 return false;
1073
1074
1075 if (const CXXConstructExpr *construct = dyn_cast(getter))
1076 return (construct->getConstructor()->isTrivial());
1077
1078
1079
1080 assert(isa(getter));
1081 return false;
1082}
1083
1084
1085
1087 llvm::Value *returnAddr,
1089 llvm::Constant *AtomicHelperFn) {
1090
1091
1093
1094
1096
1097
1098 llvm::Value *ivarAddr =
1102
1103
1105
1106 llvm::FunctionCallee copyCppAtomicObjectFn =
1112}
1113
1114
1115
1116
1117
1118
1119
1123
1124
1125
1127 return llvm::PoisonValue::get(selType);
1128 }
1129
1131}
1132
1133void
1137 llvm::Constant *AtomicHelperFn) {
1138
1140
1142 if (!AtomicHelperFn) {
1147 } else {
1150 ivar, AtomicHelperFn);
1151 }
1152 return;
1153 }
1154
1155
1157 if (!AtomicHelperFn) {
1160 nullptr);
1162 }
1163 else {
1166 ivar, AtomicHelperFn);
1167 }
1168 return;
1169 }
1170
1174
1175
1176 PropertyImplStrategy strategy(CGM, propImpl);
1177 switch (strategy.getKind()) {
1178 case PropertyImplStrategy::Native: {
1179
1180 if (strategy.getIvarSize().isZero())
1181 return;
1182
1184
1185
1186
1188 llvm::Type *bitcastType = llvm::Type::getIntNTy(getLLVMContext(), ivarSize);
1189
1190
1194 load->setAtomic(llvm::AtomicOrdering::Unordered);
1195
1196
1197
1198
1201 llvm::Value *ivarVal = load;
1202 if (ivarSize > retTySize) {
1203 bitcastType = llvm::Type::getIntNTy(getLLVMContext(), retTySize);
1204 ivarVal = Builder.CreateTrunc(load, bitcastType);
1205 }
1207
1208
1210 return;
1211 }
1212
1213 case PropertyImplStrategy::GetSetProperty: {
1214 llvm::FunctionCallee getPropertyFn =
1216 if (!getPropertyFn) {
1218 return;
1219 }
1221
1222
1223
1224
1227 llvm::Value *ivarOffset =
1229
1236
1237
1238
1239 llvm::CallBase *CallInstruction;
1241 getContext().getObjCIdType(), args),
1243 if (llvm::CallInst *call = dyn_castllvm::CallInst(CallInstruction))
1244 call->setTailCall();
1245
1246
1247
1248
1252
1253 EmitReturnOfRValue(RV, propType);
1254
1255
1257
1258 return;
1259 }
1260
1261 case PropertyImplStrategy::CopyStruct:
1263 strategy.hasStrongMember());
1264 return;
1265
1266 case PropertyImplStrategy::Expression:
1267 case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1269
1275 true);
1276 return;
1277 }
1279
1280
1281
1284 return;
1285 }
1287 llvm::Value *value;
1290 } else {
1291
1295 } else {
1297 }
1298
1299
1300
1301 } else {
1304 }
1305
1306 value = Builder.CreateBitCast(
1308 }
1309
1310 EmitReturnOfRValue(RValue::get(value), propType);
1311 return;
1312 }
1313 }
1314 llvm_unreachable("bad evaluation kind");
1315 }
1316
1317 }
1318 llvm_unreachable("bad @property implementation strategy!");
1319}
1320
1321
1322
1325
1326
1328
1329
1330 llvm::Value *ivarAddr =
1333 ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
1335
1336
1343
1344
1345 llvm::Value *size =
1348
1349
1351
1352
1353
1355
1361}
1362
1363
1364
1365
1369 llvm::Constant *AtomicHelperFn) {
1370
1371
1373
1374
1375 llvm::Value *ivarAddr =
1379
1380
1387
1388
1390
1391 llvm::FunctionCallee fn =
1397}
1398
1399
1402 if (!setter) return true;
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412 if (CallExpr *call = dyn_cast(setter)) {
1414 = dyn_cast_or_null(call->getCalleeDecl()))
1415 if (callee->isTrivial())
1416 return true;
1417 return false;
1418 }
1419
1420 assert(isa(setter));
1421 return false;
1422}
1423
1426 return false;
1428}
1429
1430void
1433 llvm::Constant *AtomicHelperFn) {
1436
1439 if (!AtomicHelperFn) {
1440
1441
1443 0);
1446 } else {
1447
1449 }
1450
1452 return;
1453 }
1454
1455
1456
1458 if (!AtomicHelperFn)
1459
1461 else
1462
1464 AtomicHelperFn);
1465 return;
1466 }
1467
1468 PropertyImplStrategy strategy(CGM, propImpl);
1469 switch (strategy.getKind()) {
1470 case PropertyImplStrategy::Native: {
1471
1472 if (strategy.getIvarSize().isZero())
1473 return;
1474
1476
1480
1481
1482
1483 llvm::Type *castType = llvm::Type::getIntNTy(
1485
1486
1489
1491
1492
1494 store->setAtomic(llvm::AtomicOrdering::Unordered);
1495 return;
1496 }
1497
1498 case PropertyImplStrategy::GetSetProperty:
1499 case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1500
1501 llvm::FunctionCallee setOptimizedPropertyFn = nullptr;
1502 llvm::FunctionCallee setPropertyFn = nullptr;
1504
1505 setOptimizedPropertyFn =
1507 strategy.isAtomic(), strategy.isCopy());
1508 if (!setOptimizedPropertyFn) {
1510 return;
1511 }
1512 }
1513 else {
1515 if (!setPropertyFn) {
1517 return;
1518 }
1519 }
1520
1521
1522
1524 llvm::Value *self =
1526 llvm::Value *ivarOffset =
1531
1535 if (setOptimizedPropertyFn) {
1541 } else {
1548
1549
1553 }
1554
1555 return;
1556 }
1557
1558 case PropertyImplStrategy::CopyStruct:
1560 return;
1561
1562 case PropertyImplStrategy::Expression:
1563 break;
1564 }
1565
1566
1571 CK_LValueToRValue, &self, VK_PRValue,
1575 &selfLoad, true, true);
1576
1584
1585
1586
1587
1589 if (ivarRef.getType()->isObjCObjectPointerType()) {
1590 if (argLoad.getType()->isObjCObjectPointerType())
1591 argCK = CK_BitCast;
1592 else if (argLoad.getType()->isBlockPointerType())
1593 argCK = CK_BlockPointerToObjCPointerCast;
1594 else
1595 argCK = CK_CPointerToObjCPointerCast;
1596 } else if (ivarRef.getType()->isBlockPointerType()) {
1597 if (argLoad.getType()->isBlockPointerType())
1598 argCK = CK_BitCast;
1599 else
1600 argCK = CK_AnyPointerToBlockPointerCast;
1601 } else if (ivarRef.getType()->isPointerType()) {
1602 argCK = CK_BitCast;
1603 } else if (argLoad.getType()->isAtomicType() &&
1604 !ivarRef.getType()->isAtomicType()) {
1605 argCK = CK_AtomicToNonAtomic;
1606 } else if (!argLoad.getType()->isAtomicType() &&
1607 ivarRef.getType()->isAtomicType()) {
1608 argCK = CK_NonAtomicToAtomic;
1609 }
1612 Expr *finalArg = &argLoad;
1613 if (().hasSameUnqualifiedType(ivarRef.getType(),
1614 argLoad.getType()))
1615 finalArg = &argCast;
1616
1618 getContext(), &ivarRef, finalArg, BO_Assign, ivarRef.getType(),
1621}
1622
1623
1624
1625
1626
1629 llvm::Constant *AtomicHelperFn =
1632 assert(OMD && "Invalid call to generate setter (empty method)");
1634
1636
1638}
1639
1640namespace {
1642 private:
1643 llvm::Value *addr;
1645 CodeGenFunction::Destroyer *destroyer;
1646 bool useEHCleanupForArray;
1647 public:
1648 DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
1649 CodeGenFunction::Destroyer *destroyer,
1650 bool useEHCleanupForArray)
1651 : addr(addr), ivar(ivar), destroyer(destroyer),
1652 useEHCleanupForArray(useEHCleanupForArray) {}
1653
1658 flags.isForNormalCleanup() && useEHCleanupForArray);
1659 }
1660 };
1661}
1662
1663
1669}
1670
1673 CodeGenFunction::RunCleanupsScope scope(CGF);
1674
1676
1681
1682
1684 if (!dtorKind) continue;
1685
1687
1688
1689
1692
1693
1694 } else {
1696 }
1697
1699
1700 CGF.EHStack.pushCleanup(cleanupKind, self, ivar, destroyer,
1702 }
1703
1704 assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?");
1705}
1706
1709 bool ctor) {
1712
1713
1714 if (ctor) {
1715
1717
1718 for (const auto *IvarInit : IMP->inits()) {
1720 ObjCIvarDecl *Ivar = cast(Field);
1728 }
1729
1732 llvm::Value *SelfAsId =
1734 EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
1735
1736
1737 } else {
1739 }
1741}
1742
1749}
1750
1757}
1758
1760 llvm::FunctionCallee EnumerationMutationFnPtr =
1762 if (!EnumerationMutationFnPtr) {
1764 return;
1765 }
1766 CGCallee EnumerationMutationFn =
1768
1770 if (DI)
1772
1773 RunCleanupsScope ForScope(*this);
1774
1775
1777 if (const DeclStmt *SD = dyn_cast(S.getElement()))
1778 variable = EmitAutoVarAlloca(*cast(SD->getSingleDecl()));
1779
1781
1782
1786
1787
1788 static const unsigned NumItems = 16;
1789
1790
1797
1799 getContext().getObjCIdType(), llvm::APInt(32, NumItems), nullptr,
1802
1803
1804 llvm::Value *Collection;
1807
1808
1810 } else {
1812 }
1813
1814
1815
1817
1818
1820
1821
1823
1824
1825
1826
1827
1828
1830
1831
1833 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumItems);
1835
1836
1840 FastEnumSel, Collection, Args);
1841
1842
1843 llvm::Value *initialBufferLimit = CountRV.getScalarVal();
1844
1845 llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
1846 llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
1847
1848 llvm::Value *zero = llvm::Constant::getNullValue(NSUIntegerTy);
1849
1850
1851
1852
1855 Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"), EmptyBB,
1856 LoopInitBB,
1857 createProfileWeights(EntryCount, getProfileCount(S.getBody())));
1858
1859
1861
1862
1863
1864
1865 Address StateMutationsPtrPtr =
1867 llvm::Value *StateMutationsPtr
1869
1871 llvm::Value *initialMutations =
1874
1875
1876
1877 llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");
1879
1880
1881 llvm::PHINode *index = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.index");
1882 index->addIncoming(zero, LoopInitBB);
1883
1884
1885 llvm::PHINode *count = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.count");
1886 count->addIncoming(initialBufferLimit, LoopInitBB);
1887
1889
1890
1891
1892
1893 StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
1894 llvm::Value *currentMutations
1897
1898 llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");
1899 llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");
1900
1901 Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),
1902 WasNotMutatedBB, WasMutatedBB);
1903
1904
1907 llvm::Value *V =
1908 Builder.CreateBitCast(Collection, ObjCIdType);
1911
1912
1916
1917
1919
1920
1921 RunCleanupsScope elementVariableScope(*this);
1922 bool elementIsVariable;
1923 LValue elementLValue;
1925 if (const DeclStmt *SD = dyn_cast(S.getElement())) {
1926
1928
1929 const VarDecl *D = cast(SD->getSingleDecl());
1932 elementLValue = EmitLValue(&tempDRE);
1933 elementType = D->getType();
1934 elementIsVariable = true;
1935
1936 if (D->isARCPseudoStrong())
1938 } else {
1939 elementLValue = LValue();
1940 elementType = cast(S.getElement())->getType();
1941 elementIsVariable = false;
1942 }
1943 llvm::Type *convertedElementType = ConvertType(elementType);
1944
1945
1946
1947
1950 llvm::Value *EnumStateItems =
1952
1953
1955 ObjCIdType, EnumStateItems, index, "currentitem.ptr");
1956 llvm::Value *CurrentItem =
1958
1959 if (SanOpts.has(SanitizerKind::ObjCCast)) {
1960
1961
1962
1963
1964
1969 if (InterfaceTy) {
1970 SanitizerScope SanScope(this);
1972 assert(InterfaceTy->getDecl() && "No decl for ObjC interface type");
1975 llvm::Value *Cls =
1977 IsKindOfClassArgs.add(RValue::get(Cls), C.getObjCClassType());
1978 llvm::Value *IsClass =
1981 IsKindOfClassSel, CurrentItem,
1982 IsKindOfClassArgs)
1984 llvm::Constant *StaticData[] = {
1987 EmitCheck({{IsClass, SanitizerKind::SO_ObjCCast}},
1988 SanitizerHandler::InvalidObjCCast,
1990 }
1991 }
1992
1993
1994 CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,
1995 "currentitem");
1996
1997
1998
1999 if (!elementIsVariable) {
2000 elementLValue = EmitLValue(cast(S.getElement()));
2002 } else {
2004 true);
2005 }
2006
2007
2008
2009 if (elementIsVariable)
2011
2012
2013 BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
2014 {
2015 RunCleanupsScope Scope(*this);
2017 }
2018 BreakContinueStack.pop_back();
2019
2020
2021 elementVariableScope.ForceCleanup();
2022
2023
2024 EmitBlock(AfterBody.getBlock());
2025
2026 llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
2027
2028
2029 llvm::Value *indexPlusOne =
2030 Builder.CreateNUWAdd(index, llvm::ConstantInt::get(NSUIntegerTy, 1));
2031
2032
2033
2034
2035
2037 Builder.CreateICmpULT(indexPlusOne, count), LoopBodyBB, FetchMoreBB,
2038 createProfileWeights(getProfileCount(S.getBody()), EntryCount));
2039
2040 index->addIncoming(indexPlusOne, AfterBody.getBlock());
2041 count->addIncoming(count, AfterBody.getBlock());
2042
2043
2045
2046 CountRV =
2049 FastEnumSel, Collection, Args);
2050
2051
2052 llvm::Value *refetchCount = CountRV.getScalarVal();
2053
2054
2055 index->addIncoming(zero, Builder.GetInsertBlock());
2056 count->addIncoming(refetchCount, Builder.GetInsertBlock());
2057
2058 Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),
2059 EmptyBB, LoopBodyBB);
2060
2061
2063
2064 if (!elementIsVariable) {
2065
2066
2067 llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
2068 elementLValue = EmitLValue(cast(S.getElement()));
2070 }
2071
2072 if (DI)
2074
2075 ForScope.ForceCleanup();
2077}
2078
2081}
2082
2085}
2086
2090}
2091
2092namespace {
2094 CallObjCRelease(llvm::Value *object) : object(object) {}
2095 llvm::Value *object;
2096
2098
2100 }
2101 };
2102}
2103
2104
2105
2107 llvm::Value *object) {
2108
2109
2110 pushFullExprCleanup(getARCCleanupKind(), object);
2111 return object;
2112}
2113
2115 llvm::Value *value) {
2117}
2118
2119
2120
2123 if (!fn)
2124 fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_use);
2125
2126
2127
2129}
2130
2131
2132
2135 if (!fn)
2136 fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_noop_use);
2138}
2139
2141 if (auto *F = dyn_castllvm::Function(RTF)) {
2142
2143
2144
2146 !CGM.getTriple().isOSBinFormatCOFF()) {
2147 F->setLinkage(llvm::Function::ExternalWeakLinkage);
2148 }
2149 }
2150}
2151
2153 llvm::FunctionCallee RTF) {
2155}
2156
2159 llvm::Function *fn = CGM.getIntrinsic(IntID);
2161 return fn;
2162}
2163
2164
2165
2166
2168 CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType,
2169 llvm::Function *&fn, llvm::Intrinsic::ID IntID,
2170 llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) {
2171 if (isallvm::ConstantPointerNull(value))
2172 return value;
2173
2174 if (!fn)
2176
2177
2178 llvm::Type *origType = returnType ? returnType : value->getType();
2180
2181
2183 call->setTailCallKind(tailKind);
2184
2185
2186 return CGF.Builder.CreateBitCast(call, origType);
2187}
2188
2189
2190
2192 llvm::Function *&fn,
2193 llvm::Intrinsic::ID IntID) {
2194 if (!fn)
2196
2198}
2199
2200
2201
2203 llvm::Value *value,
2204 llvm::Function *&fn,
2205 llvm::Intrinsic::ID IntID,
2206 bool ignored) {
2208
2209 if (!fn)
2211
2212 llvm::Type *origType = value->getType();
2213
2214 llvm::Value *args[] = {
2218
2219 if (ignored) return nullptr;
2220
2221 return CGF.Builder.CreateBitCast(result, origType);
2222}
2223
2224
2225
2227 llvm::Function *&fn,
2228 llvm::Intrinsic::ID IntID) {
2230
2231 if (!fn)
2233
2234 llvm::Value *args[] = {
2238}
2239
2240
2241
2242
2244 llvm::Value *value,
2245 llvm::Type *returnType,
2246 llvm::FunctionCallee &fn,
2247 StringRef fnName) {
2248 if (isallvm::ConstantPointerNull(value))
2249 return value;
2250
2251 if (!fn) {
2252 llvm::FunctionType *fnType =
2255
2256
2257 if (llvm::Function *f = dyn_castllvm::Function(fn.getCallee()))
2258 if (fnName == "objc_retain")
2259 f->addFnAttr(llvm::Attribute::NonLazyBind);
2260 }
2261
2262
2263 llvm::Type *origType = returnType ? returnType : value->getType();
2265
2266
2268
2269
2270
2271 if (fnName == "objc_autorelease")
2272 if (auto *Call = dyn_castllvm::CallInst(Inst))
2273 Call->setTailCall();
2274
2275
2276 return CGF.Builder.CreateBitCast(Inst, origType);
2277}
2278
2279
2280
2281
2283 if (type->isBlockPointerType())
2285 else
2287}
2288
2289
2290
2294 llvm::Intrinsic::objc_retain);
2295}
2296
2297
2298
2299
2300
2301
2302
2304 bool mandatory) {
2305 llvm::Value *result
2308 llvm::Intrinsic::objc_retainBlock);
2309
2310
2311
2312
2313
2314 if (!mandatory && isallvm::Instruction(result)) {
2315 llvm::CallInst *call
2316 = castllvm::CallInst(result->stripPointerCasts());
2317 assert(call->getCalledOperand() ==
2319
2320 call->setMetadata("clang.arc.copy_on_escape",
2321 llvm::MDNode::get(Builder.getContext(), {}));
2322 }
2323
2324 return result;
2325}
2326
2328
2329
2330 llvm::InlineAsm *&marker
2332 if (!marker) {
2333 StringRef assembly
2336
2337
2338 if (assembly.empty()) {
2339
2340
2341
2343 llvm::FunctionType *type =
2344 llvm::FunctionType::get(CGF.VoidTy, false);
2345
2346 marker = llvm::InlineAsm::get(type, assembly, "", true);
2347
2348
2349
2350
2351 } else {
2352 const char *retainRVMarkerKey = llvm::objcarc::getRVMarkerModuleFlagStr();
2353 if (!CGF.CGM.getModule().getModuleFlag(retainRVMarkerKey)) {
2354 auto *str = llvm::MDString::get(CGF.getLLVMContext(), assembly);
2355 CGF.CGM.getModule().addModuleFlag(llvm::Module::Error,
2356 retainRVMarkerKey, str);
2357 }
2358 }
2359 }
2360
2361
2362 if (marker)
2364}
2365
2367 bool IsRetainRV,
2370
2371
2372
2373
2374
2376 llvm::Function *&EP = IsRetainRV
2379 llvm::Intrinsic::ID IID =
2380 IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue
2381 : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
2383
2384 llvm::Triple::ArchType Arch = CGF.CGM.getTriple().getArch();
2385
2386
2387
2389 (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::x86_64)) {
2390 llvm::Value *bundleArgs[] = {EP};
2391 llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs);
2392 auto *oldCall = castllvm::CallBase(value);
2393 llvm::CallBase *newCall = llvm::CallBase::addOperandBundle(
2394 oldCall, llvm::LLVMContext::OB_clang_arc_attachedcall, OB,
2395 oldCall->getIterator());
2396 newCall->copyMetadata(*oldCall);
2397 oldCall->replaceAllUsesWith(newCall);
2398 oldCall->eraseFromParent();
2400 return newCall;
2401 }
2402
2403 bool isNoTail =
2405 llvm::CallInst::TailCallKind tailKind =
2406 isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None;
2408}
2409
2410
2411
2412
2413
2414
2415llvm::Value *
2418}
2419
2420
2421
2422
2423
2424
2425
2426
2427llvm::Value *
2430}
2431
2432
2433
2436 if (isallvm::ConstantPointerNull(value)) return;
2437
2439 if (!fn)
2441
2442
2444
2445
2447
2449 call->setMetadata("clang.imprecise_release",
2450 llvm::MDNode::get(Builder.getContext(), {}));
2451 }
2452}
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2468 return;
2469 }
2470
2473}
2474
2475
2476
2478 llvm::Value *value,
2479 bool ignored) {
2481
2483 if (!fn)
2485
2486 llvm::Value *args[] = {
2490
2491 if (ignored) return nullptr;
2492 return value;
2493}
2494
2495
2496
2497
2499 llvm::Value *newValue,
2500 bool ignored) {
2502 bool isBlock = type->isBlockPointerType();
2503
2504
2505
2507 !isBlock &&
2511 }
2512
2513
2514
2515
2517
2518
2520
2521
2522
2524
2525
2527
2528 return newValue;
2529}
2530
2531
2532
2536 llvm::Intrinsic::objc_autorelease);
2537}
2538
2539
2540
2541llvm::Value *
2545 llvm::Intrinsic::objc_autoreleaseReturnValue,
2546 llvm::CallInst::TCK_Tail);
2547}
2548
2549
2550
2551llvm::Value *
2555 llvm::Intrinsic::objc_retainAutoreleaseReturnValue,
2556 llvm::CallInst::TCK_Tail);
2557}
2558
2559
2560
2561
2562
2563
2565 llvm::Value *value) {
2566 if (->isBlockPointerType())
2568
2569 if (isallvm::ConstantPointerNull(value)) return value;
2570
2571 llvm::Type *origType = value->getType();
2575 return Builder.CreateBitCast(value, origType);
2576}
2577
2578
2579
2580llvm::Value *
2584 llvm::Intrinsic::objc_retainAutorelease);
2585}
2586
2587
2588
2592 llvm::Intrinsic::objc_loadWeak);
2593}
2594
2595
2599 llvm::Intrinsic::objc_loadWeakRetained);
2600}
2601
2602
2603
2605 llvm::Value *value,
2606 bool ignored) {
2609 llvm::Intrinsic::objc_storeWeak, ignored);
2610}
2611
2612
2613
2614
2615
2617
2618
2619
2620
2621 if (isallvm::ConstantPointerNull(value) &&
2624 return;
2625 }
2626
2629 llvm::Intrinsic::objc_initWeak, true);
2630}
2631
2632
2633
2636 if (!fn)
2638
2640}
2641
2642
2643
2644
2648 llvm::Intrinsic::objc_moveWeak);
2649}
2650
2651
2652
2653
2657 llvm::Intrinsic::objc_copyWeak);
2658}
2659
2665}
2666
2673}
2674
2675
2676
2679 if (!fn)
2680 fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush, CGM);
2681
2683}
2684
2685
2686
2688 assert(value->getType() == Int8PtrTy);
2689
2691
2692 llvm::FunctionCallee &fn =
2694 if (!fn) {
2695 llvm::FunctionType *fnType =
2696 llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);
2699 }
2700
2701
2703 } else {
2705 if (!fn)
2706 fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop, CGM);
2707
2709 }
2710}
2711
2712
2713
2714
2715
2716
2720
2727 AllocSel, Receiver, Args);
2728
2729
2736 InitSel, Receiver, Args);
2738}
2739
2740
2741
2743 llvm::Type *resultType) {
2746 "objc_alloc");
2747}
2748
2749
2750
2752 llvm::Type *resultType) {
2755 "objc_allocWithZone");
2756}
2757
2759 llvm::Type *resultType) {
2762 "objc_alloc_init");
2763}
2764
2765
2766
2773}
2774
2779}
2780
2785}
2786
2791}
2792
2797}
2798
2799
2800
2802 llvm::Type *returnType) {
2804 *this, value, returnType,
2806 "objc_autorelease");
2807}
2808
2809
2810
2812 llvm::Type *returnType) {
2814 *this, value, returnType,
2816}
2817
2818
2819
2822 if (isallvm::ConstantPointerNull(value)) return;
2823
2824 llvm::FunctionCallee &fn =
2826 if (!fn) {
2827 llvm::FunctionType *fnType =
2828 llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);
2831
2832 if (llvm::Function *f = dyn_castllvm::Function(fn.getCallee()))
2833 f->addFnAttr(llvm::Attribute::NonLazyBind);
2834 }
2835
2836
2838
2839
2841
2843 call->setMetadata("clang.imprecise_release",
2844 llvm::MDNode::get(Builder.getContext(), {}));
2845 }
2846}
2847
2848namespace {
2850 llvm::Value *Token;
2851
2852 CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
2853
2856 }
2857 };
2859 llvm::Value *Token;
2860
2861 CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
2862
2865 }
2866 };
2867}
2868
2872 else
2874}
2875
2877 switch (lifetime) {
2882 return true;
2883
2885 return false;
2886 }
2887
2888 llvm_unreachable("impossible lifetime!");
2889}
2890
2894 llvm::Value *result;
2896 if (shouldRetain) {
2898 } else {
2901 }
2903}
2904
2906 const Expr *e) {
2909
2910
2911
2912
2914 .isConstQualified() &&
2916
2918
2919
2922
2923
2925
2927 }
2928
2929
2930
2931
2933 .isVolatileQualified() &&
2935 isa(e) &&
2936 cast(e)->getOpcode() == BO_Assign)
2938
2939
2940
2941
2942 if (const auto *decl_expr = dyn_cast(e)) {
2943 auto *DRE = const_cast<DeclRefExpr *>(decl_expr);
2944 if (CodeGenFunction::ConstantEmission constant = CGF.tryEmitAsConstant(DRE))
2947 }
2948
2950}
2951
2952typedef llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
2953 llvm::Value *value)>
2955
2956
2957
2958
2959
2961 llvm::Value *value,
2964 CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
2965 auto *callBase = dyn_castllvm::CallBase(value);
2966
2967 if (callBase && llvm::objcarc::hasAttachedCallOpBundle(callBase)) {
2968
2969 value = doFallback(CGF, value);
2970 } else if (llvm::CallInst *call = dyn_castllvm::CallInst(value)) {
2971
2972 CGF.Builder.SetInsertPoint(call->getParent(),
2973 ++llvm::BasicBlock::iterator(call));
2974 value = doAfterCall(CGF, value);
2975 } else if (llvm::InvokeInst *invoke = dyn_castllvm::InvokeInst(value)) {
2976
2977 llvm::BasicBlock *BB = invoke->getNormalDest();
2978 CGF.Builder.SetInsertPoint(BB, BB->begin());
2979 value = doAfterCall(CGF, value);
2980
2981
2982
2983 } else if (llvm::BitCastInst *bitcast = dyn_castllvm::BitCastInst(value)) {
2984
2985
2986 CGF.Builder.SetInsertPoint(bitcast->getParent(), bitcast->getIterator());
2987 llvm::Value *operand = bitcast->getOperand(0);
2989 bitcast->setOperand(0, operand);
2990 value = bitcast;
2991 } else {
2992 auto *phi = dyn_castllvm::PHINode(value);
2993 if (phi && phi->getNumIncomingValues() == 2 &&
2994 isallvm::ConstantPointerNull(phi->getIncomingValue(1)) &&
2995 isallvm::CallBase(phi->getIncomingValue(0))) {
2996
2997
2998 llvm::Value *inVal = phi->getIncomingValue(0);
3000 phi->setIncomingValue(0, inVal);
3001 value = phi;
3002 } else {
3003
3004
3005
3006 value = doFallback(CGF, value);
3007 }
3008 }
3009
3010 CGF.Builder.restoreIP(ip);
3011 return value;
3012}
3013
3014
3015
3017 const Expr *e) {
3022 },
3025 });
3026}
3027
3028
3029
3031 const Expr *e) {
3036 },
3038 return value;
3039 });
3040}
3041
3043 bool allowUnsafeClaim) {
3044 if (allowUnsafeClaim &&
3047 } else {
3050 }
3051}
3052
3053
3054
3055
3059
3060
3061
3062 if (isa(e))
3063 return false;
3064
3065 if (const CastExpr *cast = dyn_cast(e)) {
3066 switch (cast->getCastKind()) {
3067
3068 case CK_LValueToRValue:
3069 case CK_ARCReclaimReturnedObject:
3070 case CK_ARCConsumeObject:
3071 case CK_ARCProduceObject:
3072 return false;
3073
3074
3075 case CK_NoOp:
3076 case CK_BitCast:
3078
3079
3080 case CK_AnyPointerToBlockPointerCast:
3081 default:
3082 return true;
3083 }
3084 }
3085
3086 return true;
3087}
3088
3089namespace {
3090
3091
3092template <typename Impl, typename Result> class ARCExprEmitter {
3093protected:
3095 Impl &asImpl() { return *static_cast<Impl*>(this); }
3096
3098
3099public:
3100 Result visit(const Expr *e);
3101 Result visitCastExpr(const CastExpr *e);
3103 Result visitBlockExpr(const BlockExpr *e);
3104 Result visitBinaryOperator(const BinaryOperator *e);
3106 Result visitBinAssignUnsafeUnretained(const BinaryOperator *e);
3107 Result visitBinAssignAutoreleasing(const BinaryOperator *e);
3109 Result visitBinAssignStrong(const BinaryOperator *e);
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121};
3122}
3123
3124
3125
3126
3127template <typename Impl, typename Result>
3129ARCExprEmitter<Impl,Result>::visitPseudoObjectExpr(const PseudoObjectExpr *E) {
3131
3132
3133 const Expr *resultExpr = E->getResultExpr();
3134 assert(resultExpr);
3136
3138 i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
3139 const Expr *semantic = *i;
3140
3141
3142
3143 if (const OpaqueValueExpr *ov = dyn_cast(semantic)) {
3144 typedef CodeGenFunction::OpaqueValueMappingData OVMA;
3145 OVMA opaqueData;
3146
3147
3148
3149 if (ov == resultExpr) {
3150 assert(!OVMA::shouldBindAsLValue(ov));
3151 result = asImpl().visit(ov->getSourceExpr());
3152 opaqueData = OVMA::bind(CGF, ov,
3153 RValue::get(asImpl().getValueOfResult(result)));
3154
3155
3156 } else {
3157 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
3158 }
3159 opaques.push_back(opaqueData);
3160
3161
3162
3163 } else if (semantic == resultExpr) {
3164 result = asImpl().visit(semantic);
3165
3166
3167 } else {
3168 CGF.EmitIgnoredExpr(semantic);
3169 }
3170 }
3171
3172
3173 for (unsigned i = 0, e = opaques.size(); i != e; ++i)
3174 opaques[i].unbind(CGF);
3175
3176 return result;
3177}
3178
3179template <typename Impl, typename Result>
3180Result ARCExprEmitter<Impl, Result>::visitBlockExpr(const BlockExpr *e) {
3181
3182 return asImpl().visitExpr(e);
3183}
3184
3185template <typename Impl, typename Result>
3186Result ARCExprEmitter<Impl,Result>::visitCastExpr(const CastExpr *e) {
3188
3189
3190 case CK_NoOp:
3191 return asImpl().visit(e->getSubExpr());
3192
3193
3194 case CK_CPointerToObjCPointerCast:
3195 case CK_BlockPointerToObjCPointerCast:
3196 case CK_AnyPointerToBlockPointerCast:
3197 case CK_BitCast: {
3198 llvm::Type *resultType = CGF.ConvertType(e->getType());
3201 return asImpl().emitBitCast(result, resultType);
3202 }
3203
3204
3205 case CK_LValueToRValue:
3206 return asImpl().visitLValueToRValue(e->getSubExpr());
3207 case CK_ARCConsumeObject:
3208 return asImpl().visitConsumeObject(e->getSubExpr());
3209 case CK_ARCExtendBlockObject:
3210 return asImpl().visitExtendBlockObject(e->getSubExpr());
3211 case CK_ARCReclaimReturnedObject:
3212 return asImpl().visitReclaimReturnedObject(e->getSubExpr());
3213
3214
3215 default:
3216 return asImpl().visitExpr(e);
3217 }
3218}
3219
3220template <typename Impl, typename Result>
3222ARCExprEmitter<Impl,Result>::visitBinaryOperator(const BinaryOperator *e) {
3224 case BO_Comma:
3225 CGF.EmitIgnoredExpr(e->getLHS());
3226 CGF.EnsureInsertPoint();
3227 return asImpl().visit(e->getRHS());
3228
3229 case BO_Assign:
3230 return asImpl().visitBinAssign(e);
3231
3232 default:
3233 return asImpl().visitExpr(e);
3234 }
3235}
3236
3237template <typename Impl, typename Result>
3238Result ARCExprEmitter<Impl,Result>::visitBinAssign(const BinaryOperator *e) {
3241 return asImpl().visitBinAssignUnsafeUnretained(e);
3242
3244 return asImpl().visitBinAssignWeak(e);
3245
3247 return asImpl().visitBinAssignAutoreleasing(e);
3248
3250 return asImpl().visitBinAssignStrong(e);
3251
3253 return asImpl().visitExpr(e);
3254 }
3255 llvm_unreachable("bad ObjC ownership qualifier");
3256}
3257
3258
3259
3260template <typename Impl, typename Result>
3261Result ARCExprEmitter<Impl,Result>::
3262 visitBinAssignUnsafeUnretained(const BinaryOperator *e) {
3263
3264
3265 Result result = asImpl().visit(e->getRHS());
3266
3267
3270 CGF.EmitStoreThroughLValue(RValue::get(asImpl().getValueOfResult(result)),
3271 lvalue);
3272
3273 return result;
3274}
3275
3276template <typename Impl, typename Result>
3278ARCExprEmitter<Impl,Result>::visitBinAssignAutoreleasing(const BinaryOperator *e) {
3279 return asImpl().visitExpr(e);
3280}
3281
3282template <typename Impl, typename Result>
3284ARCExprEmitter<Impl,Result>::visitBinAssignWeak(const BinaryOperator *e) {
3285 return asImpl().visitExpr(e);
3286}
3287
3288template <typename Impl, typename Result>
3290ARCExprEmitter<Impl,Result>::visitBinAssignStrong(const BinaryOperator *e) {
3291 return asImpl().visitExpr(e);
3292}
3293
3294
3295template <typename Impl, typename Result>
3296Result ARCExprEmitter<Impl,Result>::visit(const Expr *e) {
3297
3298
3299
3300
3301 assert(!isa(e));
3302
3303
3305
3306
3307 if (const CastExpr *ce = dyn_cast(e)) {
3308 return asImpl().visitCastExpr(ce);
3309
3310
3311 } else if (auto op = dyn_cast(e)) {
3312 return asImpl().visitBinaryOperator(op);
3313
3314
3315
3316
3317
3318
3319
3320 } else if (isa(e) ||
3321 (isa(e) &&
3322 !cast(e)->isDelegateInitCall())) {
3323 return asImpl().visitCall(e);
3324
3325
3326 } else if (const PseudoObjectExpr *pseudo = dyn_cast(e)) {
3327 return asImpl().visitPseudoObjectExpr(pseudo);
3328 } else if (auto *be = dyn_cast(e))
3329 return asImpl().visitBlockExpr(be);
3330
3331 return asImpl().visitExpr(e);
3332}
3333
3334namespace {
3335
3336
3337struct ARCRetainExprEmitter :
3338 public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> {
3339
3340 ARCRetainExprEmitter(CodeGenFunction &CGF) : ARCExprEmitter(CGF) {}
3341
3342 llvm::Value *getValueOfResult(TryEmitResult result) {
3343 return result.getPointer();
3344 }
3345
3347 llvm::Value *value = result.getPointer();
3348 value = CGF.Builder.CreateBitCast(value, resultType);
3349 result.setPointer(value);
3350 return result;
3351 }
3352
3355 }
3356
3357
3358
3360 llvm::Value *result = CGF.EmitScalarExpr(e);
3362 }
3363
3366
3367
3368 if (CGF.CGM.getCodeGenOpts().ObjCAvoidHeapifyLocalBlocks &&
3370 result.setInt(true);
3371 return result;
3372 }
3373
3374
3375
3376
3378 llvm::Value *result;
3379
3380
3381
3383 result = CGF.EmitScalarExpr(e);
3384
3385
3386 } else {
3388
3389
3390 if (subresult.getInt()) {
3391 return subresult;
3392 }
3393
3394
3395 result = subresult.getPointer();
3396 }
3397
3398
3399 result = CGF.EmitARCRetainBlock(result, true);
3401 }
3402
3403
3404
3408 }
3409
3410
3414 }
3415
3416
3417
3419
3420
3421 llvm::Value *result = CGF.EmitScalarExpr(e);
3423 }
3424};
3425}
3426
3429 return ARCRetainExprEmitter(CGF).visit(e);
3430}
3431
3436 llvm::Value *value = result.getPointer();
3437 if (!result.getInt())
3439 return value;
3440}
3441
3442
3443
3444
3445
3447
3448 if (const ExprWithCleanups *cleanups = dyn_cast(e)) {
3449 RunCleanupsScope scope(*this);
3451 }
3452
3454 llvm::Value *value = result.getPointer();
3455 if (!result.getInt())
3457 return value;
3458}
3459
3460llvm::Value *
3462
3463 if (const ExprWithCleanups *cleanups = dyn_cast(e)) {
3464 RunCleanupsScope scope(*this);
3466 }
3467
3469 llvm::Value *value = result.getPointer();
3470 if (result.getInt())
3472 else
3474 return value;
3475}
3476
3478 llvm::Value *result;
3479 bool doRetain;
3480
3483 doRetain = true;
3484 } else {
3486 result = subresult.getPointer();
3487 doRetain = !subresult.getInt();
3488 }
3489
3490 if (doRetain)
3493}
3494
3496
3498
3499
3501 }
3502
3503
3504
3505
3506
3507
3509}
3510
3511namespace {
3512
3513
3514struct ARCUnsafeUnretainedExprEmitter :
3515 public ARCExprEmitter<ARCUnsafeUnretainedExprEmitter, llvm::Value*> {
3516
3517 ARCUnsafeUnretainedExprEmitter(CodeGenFunction &CGF) : ARCExprEmitter(CGF) {}
3518
3519 llvm::Value *getValueOfResult(llvm::Value *value) {
3520 return value;
3521 }
3522
3523 llvm::Value *emitBitCast(llvm::Value *value, llvm::Type *resultType) {
3524 return CGF.Builder.CreateBitCast(value, resultType);
3525 }
3526
3527 llvm::Value *visitLValueToRValue(const Expr *e) {
3528 return CGF.EmitScalarExpr(e);
3529 }
3530
3531
3532
3533 llvm::Value *visitConsumeObject(const Expr *e) {
3534 llvm::Value *value = CGF.EmitScalarExpr(e);
3535 return CGF.EmitObjCConsumeObject(e->getType(), value);
3536 }
3537
3538
3539
3540 llvm::Value *visitExtendBlockObject(const Expr *e) {
3541 return CGF.EmitARCExtendBlockObject(e);
3542 }
3543
3544
3545 llvm::Value *visitReclaimReturnedObject(const Expr *e) {
3546 return CGF.EmitARCReclaimReturnedObject(e, true);
3547 }
3548
3549
3550
3551 llvm::Value *visitCall(const Expr *e) {
3552 return CGF.EmitScalarExpr(e);
3553 }
3554
3555
3556 llvm::Value *visitExpr(const Expr *e) {
3557 return CGF.EmitScalarExpr(e);
3558 }
3559};
3560}
3561
3563 const Expr *e) {
3564 return ARCUnsafeUnretainedExprEmitter(CGF).visit(e);
3565}
3566
3567
3568
3569
3570
3572
3573 if (const ExprWithCleanups *cleanups = dyn_cast(e)) {
3574 RunCleanupsScope scope(*this);
3576 }
3577
3579}
3580
3581std::pair<LValue,llvm::Value*>
3583 bool ignored) {
3584
3585
3586 llvm::Value *value;
3587 if (ignored) {
3589 } else {
3591 }
3592
3593
3596
3597 return std::pair<LValue,llvm::Value*>(std::move(lvalue), value);
3598}
3599
3600std::pair<LValue,llvm::Value*>
3602 bool ignored) {
3603
3605 llvm::Value *value = result.getPointer();
3606
3607 bool hasImmediateRetain = result.getInt();
3608
3609
3610
3611
3614 hasImmediateRetain = true;
3615 }
3616
3618
3619
3620 if (hasImmediateRetain) {
3624 } else {
3626 }
3627
3628 return std::pair<LValue,llvm::Value*>(lvalue, value);
3629}
3630
3631std::pair<LValue,llvm::Value*>
3635
3637
3638 return std::pair<LValue,llvm::Value*>(lvalue, value);
3639}
3640
3644 const CompoundStmt &S = cast(*subStmt);
3645
3647 if (DI)
3649
3650
3651 RunCleanupsScope Scope(*this);
3655 } else {
3657 EHStack.pushCleanup(NormalCleanup, token);
3658 }
3659
3660 for (const auto *I : S.body())
3662
3663 if (DI)
3665}
3666
3667
3668
3670
3671 llvm::FunctionType *extenderType
3673 llvm::InlineAsm *extender = llvm::InlineAsm::get(extenderType,
3674 "",
3675 "r",
3676 true);
3677
3679}
3680
3681
3682
3683
3684
3685llvm::Constant *
3690 return nullptr;
3691
3694
3696
3697
3698 CharUnits Alignment = C.getTypeAlignInChars(Ty);
3701 return Fn;
3702 }
3703
3706 return nullptr;
3708 return nullptr;
3709 llvm::Constant *HelperFn = nullptr;
3711 return nullptr;
3714 return HelperFn;
3715
3718
3720 QualType DestTy = C.getPointerType(Ty);
3723 SrcTy = C.getPointerType(SrcTy);
3724
3726 ArgTys.push_back(DestTy);
3727 ArgTys.push_back(SrcTy);
3728 QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
3729
3732 FunctionTy, nullptr, SC_Static, false, false, false);
3733
3739 nullptr);
3740 args.push_back(Params[0] = DstDecl);
3744 nullptr);
3745 args.push_back(Params[1] = SrcDecl);
3746 FD->setParams(Params);
3747
3750
3752
3753 llvm::Function *Fn =
3754 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
3755 "__assign_helper_atomic_property_",
3757
3759
3761
3766
3771
3772 Expr *Args[2] = {DST, SRC};
3777
3779
3781 HelperFn = Fn;
3783 return HelperFn;
3784}
3785
3790 return nullptr;
3791
3794
3796 CharUnits Alignment = C.getTypeAlignInChars(Ty);
3799 return Fn;
3800 }
3801
3804 return nullptr;
3806 return nullptr;
3807 llvm::Constant *HelperFn = nullptr;
3809 return nullptr;
3812 return HelperFn;
3813
3816
3818 QualType DestTy = C.getPointerType(Ty);
3821 SrcTy = C.getPointerType(SrcTy);
3822
3824 ArgTys.push_back(DestTy);
3825 ArgTys.push_back(SrcTy);
3826 QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
3827
3830 FunctionTy, nullptr, SC_Static, false, false, false);
3831
3837 nullptr);
3838 args.push_back(Params[0] = DstDecl);
3842 nullptr);
3843 args.push_back(Params[1] = SrcDecl);
3844 FD->setParams(Params);
3845
3848
3850
3851 llvm::Function *Fn = llvm::Function::Create(
3852 LTy, llvm::GlobalValue::InternalLinkage, "__copy_helper_atomic_property_",
3854
3856
3858
3861
3865
3868
3870 ConstructorArgs.push_back(SRC);
3871 ConstructorArgs.append(std::next(CXXConstExpr->arg_begin()),
3872 CXXConstExpr->arg_end());
3873
3878 ConstructorArgs,
3885
3888
3898
3900 HelperFn = Fn;
3902 return HelperFn;
3903}
3904
3905llvm::Value *
3907
3912 Selector AutoreleaseSelector =
3914
3915
3917 llvm::Value *Val = Block;
3920 Ty, CopySelector,
3922 Val = Result.getScalarVal();
3924 Ty, AutoreleaseSelector,
3926 Val = Result.getScalarVal();
3927 return Val;
3928}
3929
3931 switch (TT.getOS()) {
3932 case llvm::Triple::Darwin:
3933 case llvm::Triple::MacOSX:
3934 return llvm::MachO::PLATFORM_MACOS;
3935 case llvm::Triple::IOS:
3936 return llvm::MachO::PLATFORM_IOS;
3937 case llvm::Triple::TvOS:
3938 return llvm::MachO::PLATFORM_TVOS;
3939 case llvm::Triple::WatchOS:
3940 return llvm::MachO::PLATFORM_WATCHOS;
3941 case llvm::Triple::XROS:
3942 return llvm::MachO::PLATFORM_XROS;
3943 case llvm::Triple::DriverKit:
3944 return llvm::MachO::PLATFORM_DRIVERKIT;
3945 default:
3946 return llvm::MachO::PLATFORM_UNKNOWN;
3947 }
3948}
3949
3951 const VersionTuple &Version) {
3953
3954
3955
3957
3958 auto EmitArgs = [&](const VersionTuple &Version, const llvm::Triple &TT) {
3959 std::optional Min = Version.getMinor(),
3960 SMin = Version.getSubminor();
3961 Args.push_back(
3963 Args.push_back(llvm::ConstantInt::get(CGM.Int32Ty, Version.getMajor()));
3964 Args.push_back(llvm::ConstantInt::get(CGM.Int32Ty, Min.value_or(0)));
3965 Args.push_back(llvm::ConstantInt::get(CGM.Int32Ty, SMin.value_or(0)));
3966 };
3967
3968 assert(!Version.empty() && "unexpected empty version");
3970
3972 llvm::FunctionType *FTy = llvm::FunctionType::get(
3973 CGM.Int32Ty, {CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty},
3974 false);
3977 }
3978
3979 llvm::Value *Check =
3981 return CGF.Builder.CreateICmpNE(Check,
3982 llvm::Constant::getNullValue(CGM.Int32Ty));
3983}
3984
3985llvm::Value *
3987
3990
3992 llvm::FunctionType *FTy =
3996 }
3997
3998 std::optional Min = Version.getMinor(),
3999 SMin = Version.getSubminor();
4000 llvm::Value *Args[] = {
4001 llvm::ConstantInt::get(CGM.Int32Ty, Version.getMajor()),
4002 llvm::ConstantInt::get(CGM.Int32Ty, Min.value_or(0)),
4003 llvm::ConstantInt::get(CGM.Int32Ty, SMin.value_or(0))};
4004
4005 llvm::Value *CallRes =
4007
4008 return Builder.CreateICmpNE(CallRes, llvm::Constant::getNullValue(Int32Ty));
4009}
4010
4012 const llvm::Triple &TT, const VersionTuple &TargetVersion) {
4013 VersionTuple FoundationDroppedInVersion;
4014 switch (TT.getOS()) {
4015 case llvm::Triple::IOS:
4016 case llvm::Triple::TvOS:
4017 FoundationDroppedInVersion = VersionTuple(13);
4018 break;
4019 case llvm::Triple::WatchOS:
4020 FoundationDroppedInVersion = VersionTuple(6);
4021 break;
4022 case llvm::Triple::Darwin:
4023 case llvm::Triple::MacOSX:
4024 FoundationDroppedInVersion = VersionTuple(10, 15);
4025 break;
4026 case llvm::Triple::XROS:
4027
4028 return false;
4029 case llvm::Triple::DriverKit:
4030
4031 return false;
4032 default:
4033 llvm_unreachable("Unexpected OS");
4034 }
4035 return TargetVersion < FoundationDroppedInVersion;
4036}
4037
4038void CodeGenModule::emitAtAvailableLinkGuard() {
4040 return;
4041
4042 if (.getTriple().isOSDarwin())
4043 return;
4044
4045
4047 Target.getTriple(), Target.getPlatformMinVersion()))
4048 return;
4049
4050
4051
4052
4054 llvm::Metadata *Args[2] = {llvm::MDString::get(Context, "-framework"),
4055 llvm::MDString::get(Context, "CoreFoundation")};
4056 LinkerOptionsMetadata.push_back(llvm::MDNode::get(Context, Args));
4057
4058
4059 llvm::FunctionType *FTy =
4061 llvm::FunctionCallee CFFunc =
4063
4064 llvm::FunctionType *CheckFTy = llvm::FunctionType::get(VoidTy, {}, false);
4066 CheckFTy, "__clang_at_available_requires_core_foundation_framework",
4067 llvm::AttributeList(), true);
4068 llvm::Function *CFLinkCheckFunc =
4069 castllvm::Function(CFLinkCheckFuncRef.getCallee()->stripPointerCasts());
4070 if (CFLinkCheckFunc->empty()) {
4071 CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
4072 CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility);
4074 CGF.Builder.SetInsertPoint(CGF.createBasicBlock("", CFLinkCheckFunc));
4075 CGF.EmitNounwindRuntimeCall(CFFunc,
4076 llvm::Constant::getNullValue(VoidPtrTy));
4077 CGF.Builder.CreateUnreachable();
4079 }
4080}
4081
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
CodeGenFunction::ComplexPairTy ComplexPairTy
static llvm::Value * emitARCUnsafeClaimCallResult(CodeGenFunction &CGF, const Expr *e)
Given that the given expression is some sort of call (which does not return retained),...
static bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl)
static bool shouldRetainObjCLifetime(Qualifiers::ObjCLifetime lifetime)
static bool shouldEmitSeparateBlockRetain(const Expr *e)
Determine whether it might be important to emit a separate objc_retain_block on the result of the giv...
static std::optional< llvm::Value * > tryEmitSpecializedAllocInit(CodeGenFunction &CGF, const ObjCMessageExpr *OME)
Instead of '[[MyClass alloc] init]', try to generate 'objc_alloc_init(MyClass)'.
static llvm::Value * emitObjCValueOperation(CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType, llvm::FunctionCallee &fn, StringRef fnName)
Perform an operation having the signature i8* (i8*) where a null input causes a no-op and returns nul...
llvm::function_ref< llvm::Value *(CodeGenFunction &CGF, llvm::Value *value)> ValueTransform
static llvm::Value * emitARCUnsafeUnretainedScalarExpr(CodeGenFunction &CGF, const Expr *e)
static llvm::Value * emitARCLoadOperation(CodeGenFunction &CGF, Address addr, llvm::Function *&fn, llvm::Intrinsic::ID IntID)
Perform an operation having the following signature: i8* (i8**)
static llvm::Constant * getNullForVariable(Address addr)
Given the address of a variable of pointer type, find the correct null to store into it.
static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF)
static const Expr * findWeakLValue(const Expr *E)
Given an expression of ObjC pointer type, check whether it was immediately loaded from an ARC __weak ...
llvm::PointerIntPair< llvm::Value *, 1, bool > TryEmitResult
static bool hasUnalignedAtomics(llvm::Triple::ArchType arch)
Determine whether the given architecture supports unaligned atomic accesses.
static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src, llvm::Function *&fn, llvm::Intrinsic::ID IntID)
Perform an operation having the following signature: void (i8**, i8**)
static void AppendFirstImpliedRuntimeProtocols(const ObjCProtocolDecl *PD, llvm::UniqueVector< const ObjCProtocolDecl * > &PDs)
static TryEmitResult tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e)
static llvm::Value * emitOptimizedARCReturnCall(llvm::Value *value, bool IsRetainRV, CodeGenFunction &CGF)
static llvm::Value * emitCmdValueForGetterSetterBody(CodeGenFunction &CGF, ObjCMethodDecl *MD)
static llvm::Function * getARCIntrinsic(llvm::Intrinsic::ID IntID, CodeGenModule &CGM)
static bool isFoundationNeededForDarwinAvailabilityCheck(const llvm::Triple &TT, const VersionTuple &TargetVersion)
static bool shouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message)
Decide whether to extend the lifetime of the receiver of a returns-inner-pointer message.
static llvm::Value * emitARCStoreOperation(CodeGenFunction &CGF, Address addr, llvm::Value *value, llvm::Function *&fn, llvm::Intrinsic::ID IntID, bool ignored)
Perform an operation having the following signature: i8* (i8**, i8*)
static unsigned getBaseMachOPlatformID(const llvm::Triple &TT)
static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF, LValue lvalue, QualType type)
static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, llvm::Value *RTF)
static std::optional< llvm::Value * > tryGenerateSpecializedMessageSend(CodeGenFunction &CGF, QualType ResultType, llvm::Value *Receiver, const CallArgList &Args, Selector Sel, const ObjCMethodDecl *method, bool isClassMessage)
The ObjC runtime may provide entrypoints that are likely to be faster than an ordinary message send o...
static CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM, llvm::Triple::ArchType arch)
Return the maximum size that permits atomic accesses for the given architecture.
static llvm::Value * emitARCRetainCallResult(CodeGenFunction &CGF, const Expr *e)
Given that the given expression is some sort of call (which does not return retained),...
static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF, llvm::Value *returnAddr, ObjCIvarDecl *ivar, llvm::Constant *AtomicHelperFn)
emitCPPObjectAtomicGetterCall - Call the runtime function to copy the ivar into the resturn slot.
static llvm::Value * emitIsPlatformVersionAtLeast(CodeGenFunction &CGF, const VersionTuple &Version)
static void destroyARCStrongWithStore(CodeGenFunction &CGF, Address addr, QualType type)
Like CodeGenFunction::destroyARCStrong, but do it with a call.
static llvm::Value * emitARCRetainLoadOfScalar(CodeGenFunction &CGF, LValue lvalue, QualType type)
static void emitCXXDestructMethod(CodeGenFunction &CGF, ObjCImplementationDecl *impl)
static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, bool isAtomic, bool hasStrong)
emitStructGetterCall - Call the runtime function to load a property into the return value slot.
static llvm::Value * emitARCValueOperation(CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType, llvm::Function *&fn, llvm::Intrinsic::ID IntID, llvm::CallInst::TailCallKind tailKind=llvm::CallInst::TCK_None)
Perform an operation having the signature i8* (i8*) where a null input causes a no-op and returns nul...
static llvm::Value * emitARCOperationAfterCall(CodeGenFunction &CGF, llvm::Value *value, ValueTransform doAfterCall, ValueTransform doFallback)
Insert code immediately after a call.
static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, ObjCIvarDecl *ivar)
emitStructSetterCall - Call the runtime function to store the value from the first formal parameter i...
static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, ObjCIvarDecl *ivar, llvm::Constant *AtomicHelperFn)
emitCPPObjectAtomicSetterCall - Call the runtime function to store the value from the first formal pa...
static RValue AdjustObjCObjectType(CodeGenFunction &CGF, QualType ET, RValue Result)
Adjust the type of an Objective-C object that doesn't match up due to type erasure at various points,...
static bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID)
static bool UseOptimizedSetter(CodeGenModule &CGM)
enum clang::sema::@1726::IndirectLocalPathEntry::EntryKind Kind
static Decl::Kind getKind(const Decl *D)
llvm::MachO::Target Target
Defines the Objective-C statement AST node classes.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
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.
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
Qualifiers::GC getObjCGCAttrKind(QualType Ty) const
Return one of the GCNone, Weak or Strong Objective-C garbage collection attributes.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
TypeInfoChars getTypeInfoInChars(const Type *T) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
QualType getObjCIdType() const
Represents the Objective-CC id type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
A builtin binary operation expression such as "x + y" or "x <= y".
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
bool canAvoidCopyToHeap() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
const BlockDecl * getBlockDecl() const
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
bool hadMultipleCandidates() const
Whether the referred constructor was resolved from an overloaded set having size greater than 1.
static CXXConstructExpr * Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor, bool Elidable, ArrayRef< Expr * > Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool ZeroInitialization, CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange)
Create a C++ construction expression.
bool isStdInitListInitialization() const
Whether this constructor call was written as list-initialization, but was interpreted as forming a st...
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
CXXConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
A call to an overloaded operator written using operator syntax.
static CXXOperatorCallExpr * Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, ADLCallKind UsesADL=NotADL)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstArrayGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = [n x T]* ... produce name = getelementptr inbounds addr, i64 0, i64 index where i64 is a...
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
void EmitLexicalBlockEnd(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the end of a new lexical block and pop the current block.
void EmitLexicalBlockStart(CGBuilderTy &Builder, SourceLocation Loc)
Emit metadata to indicate the beginning of a new lexical block and push the block onto the stack.
CGFunctionInfo - Class to encapsulate the information about a function definition.
Implements runtime-specific code generation functions.
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual llvm::FunctionCallee GetPropertySetFunction()=0
Return the runtime function for setting properties.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtTryStmt &S)=0
virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &CallArgs, const ObjCInterfaceDecl *Class=nullptr, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation.
CodeGen::RValue GeneratePossiblySpecializedMessageSend(CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType, Selector Sel, llvm::Value *Receiver, const CallArgList &Args, const ObjCInterfaceDecl *OID, const ObjCMethodDecl *Method, bool isClassMessage)
Generate an Objective-C message send operation.
virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0
virtual llvm::Function * GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generate a function preamble for a method with the specified types.
virtual llvm::Value * GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *OPD)=0
Emit the code to return the named protocol as an object, as in a @protocol expression.
virtual CodeGen::RValue GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ReturnValueSlot ReturnSlot, QualType ResultType, Selector Sel, const ObjCInterfaceDecl *Class, bool isCategoryImpl, llvm::Value *Self, bool IsClassMessage, const CallArgList &CallArgs, const ObjCMethodDecl *Method=nullptr)=0
Generate an Objective-C message send operation to the super class initiated in a method for Class and...
virtual llvm::FunctionCallee EnumerationMutationFunction()=0
EnumerationMutationFunction - Return the function that's called by the compiler when a mutation is de...
virtual llvm::FunctionCallee GetGetStructFunction()=0
virtual ConstantAddress GenerateConstantString(const StringLiteral *)=0
Generate a constant string object.
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic, bool copy)=0
Return the runtime function for optimized setting properties.
virtual llvm::Value * GetSelector(CodeGenFunction &CGF, Selector Sel)=0
Get a selector for the specified name and type values.
virtual void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD)=0
Generates prologue for direct Objective-C Methods.
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
virtual llvm::FunctionCallee GetPropertyGetFunction()=0
Return the runtime function for getting properties.
virtual llvm::FunctionCallee GetSetStructFunction()=0
std::vector< const ObjCProtocolDecl * > GetRuntimeProtocolList(ObjCProtocolDecl::protocol_iterator begin, ObjCProtocolDecl::protocol_iterator end)
Walk the list of protocol references from a class, category or protocol to traverse the DAG formed fr...
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S)=0
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
static AutoVarEmission invalid()
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, ObjCMethodDecl *MD, bool ctor)
void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD)
void EmitARCDestroyWeak(Address addr)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
llvm::Value * EmitARCExtendBlockObject(const Expr *expr)
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitARCMoveWeak(Address dst, Address src)
void generateObjCGetterBody(const ObjCImplementationDecl *classImpl, const ObjCPropertyImplDecl *propImpl, const ObjCMethodDecl *GetterMothodDecl, llvm::Constant *AtomicHelperFn)
llvm::Value * EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)
Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
llvm::Value * EmitObjCAutoreleasePoolPush()
llvm::Value * EmitARCRetainAutoreleaseNonBlock(llvm::Value *value)
void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr)
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
llvm::Value * EmitARCRetainAutoreleasedReturnValue(llvm::Value *value)
llvm::Value * EmitObjCAllocWithZone(llvm::Value *value, llvm::Type *returnType)
CleanupKind getARCCleanupKind()
Retrieves the default cleanup kind for an ARC cleanup.
bool shouldUseFusedARCCalls()
llvm::Value * EmitARCAutoreleaseReturnValue(llvm::Value *value)
void GenerateObjCMethod(const ObjCMethodDecl *OMD)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::Value * EmitARCAutorelease(llvm::Value *value)
void EmitExtendGCLifetime(llvm::Value *object)
EmitExtendGCLifetime - Given a pointer to an Objective-C object, make sure it survives garbage collec...
void EmitARCNoopIntrinsicUse(ArrayRef< llvm::Value * > values)
llvm::Constant * GenerateObjCAtomicGetterCopyHelperFunction(const ObjCPropertyImplDecl *PID)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
void callCStructCopyConstructor(LValue Dst, LValue Src)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitARCLoadWeakRetained(Address addr)
const LangOptions & getLangOpts() const
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
llvm::Value * EmitARCRetainAutorelease(QualType type, llvm::Value *value)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Value * EmitObjCRetainNonBlock(llvm::Value *value, llvm::Type *returnType)
llvm::Value * EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType)
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Value * EmitARCUnsafeUnretainedScalarExpr(const Expr *expr)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void EmitAutoVarInit(const AutoVarEmission &emission)
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)
QualType TypeOfSelfObject()
TypeOfSelfObject - Return type of object that this self represents.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
llvm::Value * EmitARCLoadWeak(Address addr)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
llvm::Value * EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType)
llvm::Value * EmitObjCCollectionLiteral(const Expr *E, const ObjCMethodDecl *MethodWithObjects)
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
llvm::BasicBlock * getInvokeDest()
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
llvm::Value * EmitARCRetainAutoreleaseReturnValue(llvm::Value *value)
void EmitARCCopyWeak(Address dst, Address src)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
CGDebugInfo * getDebugInfo()
LValue EmitDeclRefLValue(const DeclRefExpr *E)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr)
llvm::Value * EmitARCRetainAutoreleaseScalarExpr(const Expr *expr)
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * EmitARCRetain(QualType type, llvm::Value *value)
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
llvm::Value * EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
llvm::Constant * GenerateObjCAtomicSetterCopyHelperFunction(const ObjCPropertyImplDecl *PID)
void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
static Destroyer destroyARCWeak
void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S)
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Value * EmitObjCMRRAutoreleasePoolPush()
llvm::Type * ConvertType(QualType T)
CodeGenTypes & getTypes() const
void EmitARCInitWeak(Address addr, llvm::Value *value)
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
void generateObjCSetterBody(const ObjCImplementationDecl *classImpl, const ObjCPropertyImplDecl *propImpl, llvm::Constant *AtomicHelperFn)
static Destroyer destroyARCStrongPrecise
void EmitARCIntrinsicUse(ArrayRef< llvm::Value * > values)
void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S)
void EmitReturnStmt(const ReturnStmt &S)
AggValueSlot::Overlap_t getOverlapForReturnValue()
Determine whether a return value slot may overlap some other object.
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
llvm::Value * EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr)
void GenerateObjCSetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID)
GenerateObjCSetter - Synthesize an Objective-C property setter function for the given property.
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
void GenerateObjCGetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID)
GenerateObjCGetter - Synthesize an Objective-C property getter function.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
static Destroyer destroyARCStrongImprecise
LValue EmitLValueForIvar(QualType ObjectTy, llvm::Value *Base, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)
llvm::Value * EmitObjCAlloc(llvm::Value *value, llvm::Type *returnType)
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
static Destroyer emitARCIntrinsicUse
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
void EmitObjCAtTryStmt(const ObjCAtTryStmt &S)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
This class organizes the cross-function state that is used while generating LLVM code.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
llvm::Constant * getAtomicGetterHelperFnMap(QualType Ty)
const LangOptions & getLangOpts() const
QualType getObjCFastEnumerationStateType()
Retrieve the record type that describes the state of an Objective-C fast enumeration loop (for....
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::FunctionCallee IsOSVersionAtLeastFn
const llvm::DataLayout & getDataLayout() const
ObjCEntrypoints & getObjCEntrypoints() const
const llvm::Triple & getTriple() const
void setAtomicSetterHelperFnMap(QualType Ty, llvm::Constant *Fn)
llvm::Constant * getAtomicSetterHelperFnMap(QualType Ty)
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
ASTContext & getContext() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
void setAtomicGetterHelperFnMap(QualType Ty, llvm::Constant *Fn)
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
llvm::FunctionCallee IsPlatformVersionAtLeastFn
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
ConstantAddress GetAddrOfConstantCString(const std::string &Str, const char *GlobalName=nullptr)
Returns a pointer to a character array containing the literal and a terminating '\0' character.
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD)
Objective-C methods are C functions with some implicit parameters.
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
llvm::Constant * getPointer() const
Information for lazily generating a cleanup.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
CharUnits getAlignment() const
llvm::Value * getPointer(CodeGenFunction &CGF) const
const Qualifiers & getQuals() const
Address getAddress() const
ARCPreciseLifetime_t isARCPreciseLifetime() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual StringRef getARCRetainAutoreleasedReturnValueMarker() const
Retrieve the address of a function to call immediately before calling objc_retainAutoreleasedReturnVa...
virtual bool markARCOptimizedReturnCallsAsNoTail() const
Determine whether a call to objc_retainAutoreleasedReturnValue or objc_unsafeClaimAutoreleasedReturnV...
CompoundStmt - This represents a group of statements like { stmt stmt }.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
SourceLocation getBodyRBrace() const
getBodyRBrace - Gets the right brace of the body, if a body exists.
SourceLocation getLocation() const
DeclContext * getDeclContext()
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, Expr *TrailingRequiresClause=nullptr)
GlobalDecl - represents a global declaration.
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.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
clang::ObjCRuntime ObjCRuntime
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Expr * getElement(unsigned Index)
getElement - Return the Element at the specified index.
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c array literal.
Represents Objective-C's @synchronized statement.
Represents Objective-C's @throw statement.
Represents Objective-C's @try ... @catch ... @finally statement.
Represents Objective-C's @autoreleasepool Statement.
const Stmt * getSubStmt() const
ObjCBoxedExpr - used for generalized expression boxing.
ObjCContainerDecl - Represents a container for method declarations.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
unsigned getNumElements() const
getNumElements - Return number of elements of objective-c dictionary literal.
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Represents Objective-C's collection statement.
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
ObjCInterfaceDecl * getSuperClass() const
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.
ObjCIvarDecl * getNextIvar()
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Selector getSelector() const
@ SuperInstance
The receiver is the instance of the superclass object.
@ Instance
The receiver is an object instance.
@ SuperClass
The receiver is a superclass.
@ Class
The receiver is a class.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
ObjCMethodDecl - Represents an instance or class method declaration.
ImplicitParamDecl * getSelfDecl() const
ArrayRef< ParmVarDecl * > parameters() const
param_const_iterator param_end() const
param_const_iterator param_begin() const
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
SourceLocation getEndLoc() const LLVM_READONLY
const ParmVarDecl *const * param_const_iterator
SourceLocation getBeginLoc() const LLVM_READONLY
bool isDirectMethod() const
True if the method is tagged as objc_direct.
Selector getSelector() const
ImplicitParamDecl * getCmdDecl() const
bool isInstanceMethod() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID)
createImplicitParams - Used to lazily create the self and cmd implicit parameters.
QualType getReturnType() const
bool isClassMethod() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
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.
bool isAtomic() const
isAtomic - Return true if the property is atomic.
SetterKind getSetterKind() const
getSetterKind - Return the method used for doing assignment in the property setter.
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
ObjCIvarDecl * getPropertyIvarDecl() const
Expr * getSetterCXXAssignment() const
ObjCPropertyDecl * getPropertyDecl() const
Expr * getGetterCXXConstructor() const
ObjCMethodDecl * getSetterMethodDecl() const
ObjCMethodDecl * getGetterMethodDecl() const
Represents an Objective-C protocol declaration.
bool isNonRuntimeProtocol() const
This is true iff the protocol is tagged with the objc_non_runtime_protocol attribute.
ObjCProtocolList::iterator protocol_iterator
ObjCProtocolDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this Objective-C protocol.
protocol_range protocols() const
ObjCProtocolExpr used for protocol expression in Objective-C.
The basic abstraction for the target Objective-C runtime.
bool hasEmptyCollections() const
Are the empty collection symbols available?
bool hasAtomicCopyHelper() const
bool hasARCUnsafeClaimAutoreleasedReturnValue() const
Is objc_unsafeClaimAutoreleasedReturnValue available?
bool hasNativeARC() const
Does this runtime natively provide the ARC entrypoints?
bool hasOptimizedSetter() const
Does this runtime supports optimized setter entrypoints?
ObjCSelectorExpr used for @selector in Objective-C.
ObjCStringLiteral, used for Objective-C string literals i.e.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
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)
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
const Expr *const * const_semantics_iterator
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
@ DK_objc_strong_lifetime
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const
Check if this is a non-trivial type that would cause a C struct transitively containing this type to ...
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool hasNonTrivialObjCLifetime() const
@ PCK_Struct
The type is a struct containing a field whose type is neither PCK_Trivial nor PCK_VolatileTrivial.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
void setObjCLifetime(ObjCLifetime type)
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
Scope - A scope is a transient data structure that is used while parsing the program.
Selector getNullarySelector(const IdentifierInfo *ID)
Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)
Can create any sort of selector.
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
bool isKeywordSelector() const
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool isUnarySelector() const
unsigned getNumArgs() const
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Token - This structure provides full information about a lexed token.
bool isBlockPointerType() const
const T * castAs() const
Member-template castAs.
bool isReferenceType() const
const ObjCObjectPointerType * getAsObjCInterfacePointerType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCObjectPointerType() const
bool isObjCClassType() const
const T * getAs() const
Member-template getAs'.
bool isRecordType() const
bool isObjCRetainableType() const
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::Function * getNonTrivialCStructCopyConstructor(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)
Returns the copy constructor for a C struct with non-trivially copyable fields, generating it if nece...
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
llvm::Function * getNonTrivialCStructMoveAssignmentOperator(CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment, bool IsVolatile, QualType QT)
Return the move assignment operator for a C struct with non-trivially copyable fields,...
ARCPreciseLifetime_t
Does an ARC strong l-value have precise lifetime?
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< RecordType > recordType
Matches record types (e.g.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool BitCast(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
@ 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.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
llvm::PointerType * VoidPtrTy
llvm::PointerType * Int8PtrPtrTy
unsigned char PointerSizeInBytes
llvm::IntegerType * Int32Ty
unsigned char PointerAlignInBytes
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
llvm::Function * objc_retainAutoreleasedReturnValue
id objc_retainAutoreleasedReturnValue(id);
llvm::Function * objc_retainAutoreleaseReturnValue
id objc_retainAutoreleaseReturnValue(id);
llvm::FunctionCallee objc_alloc
void objc_alloc(id);
llvm::Function * objc_retain
id objc_retain(id);
llvm::FunctionCallee objc_alloc_init
void objc_alloc_init(id);
llvm::Function * objc_autorelease
id objc_autorelease(id);
llvm::Function * objc_moveWeak
void objc_moveWeak(id *dest, id *src);
llvm::FunctionCallee objc_autoreleasePoolPopInvoke
void objc_autoreleasePoolPop(void*); Note this method is used when we are using exception handling
llvm::InlineAsm * retainAutoreleasedReturnValueMarker
A void(void) inline asm to use to mark that the return value of a call will be immediately retain.
llvm::Function * clang_arc_use
void clang.arc.use(...);
llvm::Function * objc_initWeak
id objc_initWeak(id*, id);
llvm::FunctionCallee objc_retainRuntimeFunction
id objc_retain(id); Note this is the runtime method not the intrinsic.
llvm::Function * objc_copyWeak
void objc_copyWeak(id *dest, id *src);
llvm::Function * objc_destroyWeak
void objc_destroyWeak(id*);
llvm::Function * objc_retainAutorelease
id objc_retainAutorelease(id);
llvm::Function * objc_autoreleasePoolPush
void *objc_autoreleasePoolPush(void);
llvm::Function * objc_retainBlock
id objc_retainBlock(id);
llvm::Function * objc_storeStrong
void objc_storeStrong(id*, id);
llvm::Function * objc_loadWeak
id objc_loadWeak(id*);
llvm::Function * clang_arc_noop_use
void clang.arc.noop.use(...);
llvm::Function * objc_loadWeakRetained
id objc_loadWeakRetained(id*);
llvm::Function * objc_release
void objc_release(id);
llvm::FunctionCallee objc_autoreleaseRuntimeFunction
id objc_autorelease(id); Note this is the runtime method not the intrinsic.
llvm::Function * objc_autoreleaseReturnValue
id objc_autoreleaseReturnValue(id);
llvm::FunctionCallee objc_releaseRuntimeFunction
void objc_release(id); Note this is the runtime method not the intrinsic.
llvm::FunctionCallee objc_allocWithZone
void objc_allocWithZone(id);
llvm::FunctionCallee objc_autoreleasePoolPop
void objc_autoreleasePoolPop(void*);
llvm::Function * objc_storeWeak
id objc_storeWeak(id*, id);
llvm::Function * objc_unsafeClaimAutoreleasedReturnValue
id objc_unsafeClaimAutoreleasedReturnValue(id);
Expr * Value
The value of the dictionary element.
Expr * Key
The key for the dictionary element.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.