clang: lib/CodeGen/CGObjC.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
27#include "llvm/Analysis/ObjCARCUtil.h"
28#include "llvm/BinaryFormat/MachO.h"
29#include "llvm/IR/Constants.h"
30#include "llvm/IR/DataLayout.h"
31#include "llvm/IR/InlineAsm.h"
32#include
33using namespace clang;
35
36typedef llvm::PointerIntPairllvm::Value\*,1,bool TryEmitResult;
42
43
44
49
50
52{
53 llvm::Constant *C =
54 CGM.getObjCRuntime().GenerateConstantString(E->getString()).getPointer();
55 return C;
56}
57
58
59
60
61
62
63llvm::Value *
65
66
69
73 }
74
75 assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method");
77
78
79
80
83 llvm::Value *Receiver = Runtime.GetClass(*this, ClassDecl);
84
88
89
90
92 if (ValueType->isObjCBoxableRecordType()) {
93
94
97 llvm::Value *BitCast = Builder.CreateBitCast(
100
101
102 std::string Str;
104 llvm::Constant *GV = CGM.GetAddrOfConstantCString(Str).getPointer();
105
106
109 llvm::Value *Cast = Builder.CreateBitCast(GV, ConvertType(EncodingQT));
110
112 } else {
114 }
115
118 Args, ClassDecl, BoxingMethod);
121}
122
128 if (!ALE)
130
131
132 uint64_t NumElements =
134 if (NumElements == 0 && CGM.getLangOpts().ObjCRuntime.hasEmptyCollections()) {
135 StringRef ConstantName = ALE ? "__NSArray0__" : "__NSDictionary0__";
136 QualType IdTy(CGM.getContext().getObjCIdType());
137 llvm::Constant *Constant =
138 CGM.CreateRuntimeVariable(ConvertType(IdTy), ConstantName);
142 llvm::LLVMContext::MD_invariant_load,
145 }
146
147
148 llvm::APInt APNumElements(Context.getTypeSize(Context.getSizeType()),
149 NumElements);
151 QualType ElementArrayType = Context.getConstantArrayType(
153 0);
154
155
158 if (DLE)
160
161
162
164 bool TrackNeededObjects =
166 CGM.getCodeGenOpts().OptimizationLevel != 0);
167
168
169 for (uint64_t i = 0; i < NumElements; i++) {
170 if (ALE) {
171
175
178 if (TrackNeededObjects) {
179 NeededObjects.push_back(value);
180 }
181 } else {
182
188
189
195 if (TrackNeededObjects) {
196 NeededObjects.push_back(keyValue);
197 NeededObjects.push_back(valueValue);
198 }
199 }
200 }
201
202
208 if (DLE) {
209 argDecl = *PI++;
212 }
213 argDecl = *PI;
215 llvm::Value *Count =
216 llvm::ConstantInt::get(CGM.getTypes().ConvertType(ArgQT), NumElements);
218
219
224 assert(InterfacePointerType && "Unexpected InterfacePointerType - null");
226 = InterfacePointerType->getObjectType()->getInterface();
228 llvm::Value *Receiver = Runtime.GetClass(*this, Class);
229
230
233 Receiver, Args, Class, MethodWithObjects);
234
235
236
237
238
239 if (TrackNeededObjects) {
241 }
242
245}
246
250
255
256
258
259
260
261
262 return CGM.getObjCRuntime().GetSelector(*this, E->getSelector());
263}
264
266
267 return CGM.getObjCRuntime().GenerateProtocolRef(*this, E->getProtocol());
268}
269
270
271
272
276 return Result;
277
278
279 llvm::Type *ExpLLVMTy = CGF.ConvertType(ExpT);
280 if (ExpLLVMTy == Result.getScalarVal()->getType())
281 return Result;
282
283
285 ExpLLVMTy));
286}
287
288
289
290static bool
293
294
295
298
299
300 if (auto opaque = dyn_cast(receiver)) {
301 if (opaque->getSourceExpr())
302 receiver = opaque->getSourceExpr()->IgnoreParens();
303 }
304
305 const ImplicitCastExpr *ice = dyn_cast(receiver);
306 if (!ice || ice->getCastKind() != CK_LValueToRValue) return true;
308
309
310 if (auto opaque = dyn_cast(receiver)) {
311 if (opaque->getSourceExpr())
312 receiver = opaque->getSourceExpr()->IgnoreParens();
313 }
314
315
317 return true;
318
319
321 return false;
322
323
325 if (!declRef) return true;
326 const VarDecl *var = dyn_cast(declRef->getDecl());
327 if (!var) return true;
328
329
330
331 return (var->hasLocalStorage() &&
332 !var->hasAttr());
333 }
334
337
338 return false;
339
341
342 return false;
343 }
344
345 llvm_unreachable("invalid receiver kind");
346}
347
348
349
353 if (auto CE = dyn_cast(E)) {
354 if (CE->getCastKind() == CK_LValueToRValue) {
356 return CE->getSubExpr();
357 }
358 }
359
360 return nullptr;
361}
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
380 bool isClassMessage) {
381 auto &CGM = CGF.CGM;
382 if (!CGM.getCodeGenOpts().ObjCConvertMessagesToRuntimeCalls)
383 return std::nullopt;
384
388 if (isClassMessage &&
389 Runtime.shouldUseRuntimeFunctionsForAlloc() &&
391
392
395
396
398 Args.size() == 1 && Args.front().getType()->isPointerType() &&
400 const llvm::Value* arg = Args.front().getKnownRValue().getScalarVal();
404 return std::nullopt;
405 }
406 }
407 break;
408
412 Runtime.shouldUseARCFunctionsForRetainRelease())
414 break;
415
419 Runtime.shouldUseARCFunctionsForRetainRelease())
421 break;
422
426 Runtime.shouldUseARCFunctionsForRetainRelease()) {
428 return nullptr;
429 }
430 break;
431
432 default:
433 break;
434 }
435 return std::nullopt;
436}
437
442 bool isClassMessage) {
443 if (std::optional<llvm::Value *> SpecializedResult =
445 Sel, Method, isClassMessage)) {
447 }
448 return GenerateMessageSend(CGF, Return, ResultType, Sel, Receiver, Args, OID,
450}
451
454 llvm::UniqueVector<const ObjCProtocolDecl *> &PDs) {
457 PDs.insert(Can);
458 return;
459 }
460
461 for (const auto *ParentPD : PD->protocols())
463}
464
465std::vector<const ObjCProtocolDecl *>
468 std::vector<const ObjCProtocolDecl *> RuntimePds;
469 llvm::DenseSet<const ObjCProtocolDecl *> NonRuntimePDs;
470
471 for (; begin != end; ++begin) {
472 const auto *It = *begin;
473 const auto *Can = It->getCanonicalDecl();
474 if (Can->isNonRuntimeProtocol())
475 NonRuntimePDs.insert(Can);
476 else
477 RuntimePds.push_back(Can);
478 }
479
480
481 if (NonRuntimePDs.empty())
482 return RuntimePds;
483
484
485
486
487
488 llvm::UniqueVector<const ObjCProtocolDecl *> FirstImpliedProtos;
489 for (const auto *PD : NonRuntimePDs)
491
492
493
494 llvm::DenseSet<const ObjCProtocolDecl *> AllImpliedProtocols;
495 for (const auto *PD : RuntimePds) {
496 const auto *Can = PD->getCanonicalDecl();
497 AllImpliedProtocols.insert(Can);
498 Can->getImpliedProtocols(AllImpliedProtocols);
499 }
500
501
502
503
504 for (const auto *PD : FirstImpliedProtos) {
505 PD->getImpliedProtocols(AllImpliedProtocols);
506 }
507
508
509
510
511
512 for (const auto *PD : FirstImpliedProtos) {
513 if (!AllImpliedProtocols.contains(PD)) {
514 RuntimePds.push_back(PD);
515 }
516 }
517
518 return RuntimePds;
519}
520
521
522
523
524static std::optional<llvm::Value *>
527 if (!Runtime.shouldUseRuntimeFunctionForCombinedAllocInit())
528 return std::nullopt;
529
530
535 return std::nullopt;
536
537
538
539 auto *SubOME =
541 if (!SubOME)
542 return std::nullopt;
543 Selector SubSel = SubOME->getSelector();
544
545 if (!SubOME->getType()->isObjCObjectPointerType() ||
547 return std::nullopt;
548
549 llvm::Value *Receiver = nullptr;
550 switch (SubOME->getReceiverKind()) {
552 if (!SubOME->getInstanceReceiver()->getType()->isObjCClassType())
553 return std::nullopt;
554 Receiver = CGF.EmitScalarExpr(SubOME->getInstanceReceiver());
555 break;
556
558 QualType ReceiverType = SubOME->getClassReceiver();
561 assert(ID && "null interface should be impossible here");
563 break;
564 }
567 return std::nullopt;
568 }
569
571}
572
575
576
577
578
580
582
583
584
591 }
592 }
593
596
597
598
599
600
601 bool retainSelf =
602 (!isDelegateInit &&
603 CGM.getLangOpts().ObjCAutoRefCount &&
604 method &&
605 method->hasAttr());
606
608 bool isSuperMessage = false;
609 bool isClassMessage = false;
611
613 llvm::Value *Receiver = nullptr;
618 if (retainSelf) {
621 Receiver = ter.getPointer();
622 if (ter.getInt()) retainSelf = false;
623 } else
625 break;
626
630 assert(OID && "Invalid Objective-C class message send");
631 Receiver = Runtime.GetClass(*this, OID);
632 isClassMessage = true;
633 break;
634 }
635
639 isSuperMessage = true;
640 break;
641
645 isSuperMessage = true;
646 isClassMessage = true;
647 break;
648 }
649
650 if (retainSelf)
652
653
654
655
656 if (getLangOpts().ObjCAutoRefCount && method &&
657 method->hasAttr() &&
660
662
665
666
667
668
669
670
671
672
673 if (isDelegateInit) {
675 "delegate init calls should only be marked in ARC");
676
677
681 }
682
684 if (isSuperMessage) {
685
691 isCategoryImpl,
692 Receiver,
693 isClassMessage,
694 Args,
695 method);
696 } else {
697
699 *this, Return, ResultType, E->getSelector(), Receiver, Args, OID,
700 method, isClassMessage);
701 }
702
703
704
705 if (isDelegateInit) {
708 llvm::Value *newSelf = result.getScalarVal();
709
710
711
713 newSelf = Builder.CreateBitCast(newSelf, selfTy);
714
715 Builder.CreateStore(newSelf, selfAddr);
716 }
717
719}
720
721namespace {
722struct FinishARCDealloc final : EHScopeStack::Cleanup {
725
729
731
732
734
739 iface,
740 isCategory,
741 self,
742 false,
743 args,
744 method);
745 }
746};
747}
748
749
750
751
756
757 if (OMD->hasAttr())
758 DebugInfo = nullptr;
759
760 llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
761
762 const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(OMD);
764 Fn->setVisibility(llvm::Function::HiddenVisibility);
765 CGM.SetLLVMFunctionAttributes(OMD, FI, Fn, false);
766 CGM.SetLLVMFunctionAttributesForDefinition(OMD, Fn);
767 } else {
768 CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
769 }
770
774
776
778 CurEHLocation = OMD->getEndLoc();
779
782
784
785
786
787
788 CGM.getObjCRuntime().GenerateDirectMethodPrologue(*this, Fn, OMD, CD);
789 }
790
791
792 if (CGM.getLangOpts().ObjCAutoRefCount &&
797 if (ident->isStr("dealloc"))
799 }
800}
801
804
805
806
815
816
817
819 bool isAtomic, bool hasStrong) {
821
822 llvm::Value *src =
825
826
827
829
833
838
843}
844
845
846
847
849
850
851 return false;
852}
853
854
855
857 llvm::Triple::ArchType arch) {
858
859
860
861
862
864}
865
866namespace {
867 class PropertyImplStrategy {
868 public:
869 enum StrategyKind {
870
871
873
874
875 GetSetProperty,
876
877
878
879 SetPropertyAndExpressionGet,
880
881
882 CopyStruct,
883
884
885
887 };
888
889 StrategyKind getKind() const { return StrategyKind(Kind); }
890
891 bool hasStrongMember() const { return HasStrong; }
892 bool isAtomic() const { return IsAtomic; }
893 bool isCopy() const { return IsCopy; }
894
895 CharUnits getIvarSize() const { return IvarSize; }
896 CharUnits getIvarAlignment() const { return IvarAlignment; }
897
898 PropertyImplStrategy(CodeGenModule &CGM,
899 const ObjCPropertyImplDecl *propImpl);
900
901 private:
902 LLVM_PREFERRED_TYPE(StrategyKind)
903 unsigned Kind : 8;
904 LLVM_PREFERRED_TYPE(bool)
905 unsigned IsAtomic : 1;
906 LLVM_PREFERRED_TYPE(bool)
907 unsigned IsCopy : 1;
908 LLVM_PREFERRED_TYPE(bool)
909 unsigned HasStrong : 1;
910
911 CharUnits IvarSize;
912 CharUnits IvarAlignment;
913 };
914}
915
916
917PropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,
918 const ObjCPropertyImplDecl *propImpl) {
919 const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
921
924 HasStrong = false;
925
926
928 QualType ivarType = ivar->getType();
930 IvarSize = TInfo.Width;
931 IvarAlignment = TInfo.Align;
932
933
934
935
936 if (IsCopy) {
937 Kind = IsAtomic ? GetSetProperty : SetPropertyAndExpressionGet;
938 return;
939 }
940
941
943
945
946
947
948
949
950 } else if (CGM.getLangOpts().ObjCAutoRefCount && !IsAtomic) {
951
952
953
954
955
956
959 else
960 Kind = SetPropertyAndExpressionGet;
961 return;
962
963
964
965
966 } else if (!IsAtomic) {
967 Kind = SetPropertyAndExpressionGet;
968 return;
969
970
971 } else {
972 Kind = GetSetProperty;
973 return;
974 }
975 }
976
977
978 if (!IsAtomic) {
980 return;
981 }
982
983
984
987 return;
988 }
989
990
991
992
997 return;
998 }
999
1000
1003 HasStrong = RD->hasObjectMember();
1004
1005
1006
1007
1008 if (HasStrong) {
1009 Kind = CopyStruct;
1010 return;
1011 }
1012
1013
1014
1015
1016
1017
1018 if (!IvarSize.isPowerOfTwo()) {
1019 Kind = CopyStruct;
1020 return;
1021 }
1022
1023 llvm::Triple::ArchType arch =
1025
1026
1027
1028
1030 Kind = CopyStruct;
1031 return;
1032 }
1033
1034
1035
1037 Kind = CopyStruct;
1038 return;
1039 }
1040
1041
1043}
1044
1045
1046
1047
1048
1051 llvm::Constant *AtomicHelperFn =
1052 CodeGenFunction(CGM).GenerateObjCAtomicGetterCopyHelperFunction(PID);
1054 assert(OMD && "Invalid call to generate getter (empty method)");
1056
1058
1060}
1061
1064 if (!getter) return true;
1065
1066
1067
1068
1069
1070
1071
1073 return false;
1074
1075
1076 if (const CXXConstructExpr *construct = dyn_cast(getter))
1077 return (construct->getConstructor()->isTrivial());
1078
1079
1080
1082 return false;
1083}
1084
1085
1086
1088 llvm::Value *returnAddr,
1090 llvm::Constant *AtomicHelperFn) {
1091
1092
1094
1095
1097
1098
1099 llvm::Value *ivarAddr =
1103
1104
1106
1107 llvm::FunctionCallee copyCppAtomicObjectFn =
1113}
1114
1115
1116
1117
1118
1119
1120
1124
1125
1126
1128 return llvm::PoisonValue::get(selType);
1129 }
1130
1132}
1133
1134void
1138 llvm::Constant *AtomicHelperFn) {
1139
1141
1143 if (!AtomicHelperFn) {
1148 } else {
1151 ivar, AtomicHelperFn);
1152 }
1153 return;
1154 }
1155
1156
1158 if (!AtomicHelperFn) {
1161 nullptr);
1163 }
1164 else {
1167 ivar, AtomicHelperFn);
1168 }
1169 return;
1170 }
1171
1175
1176
1177 PropertyImplStrategy strategy(CGM, propImpl);
1178 switch (strategy.getKind()) {
1179 case PropertyImplStrategy::Native: {
1180
1181 if (strategy.getIvarSize().isZero())
1182 return;
1183
1185
1186
1187
1188 uint64_t ivarSize = getContext().toBits(strategy.getIvarSize());
1189 llvm::Type *bitcastType = llvm::Type::getIntNTy(getLLVMContext(), ivarSize);
1190
1191
1194 llvm::LoadInst *load = Builder.CreateLoad(ivarAddr, "load");
1195 load->setAtomic(llvm::AtomicOrdering::Unordered);
1196 llvm::Value *ivarVal = load;
1200 CGM.getPointerAuthInfoForType(getterMethod->getReturnType());
1202 TargetInfo, false);
1203 }
1204
1205
1206
1207
1209 uint64_t retTySize = CGM.getDataLayout().getTypeSizeInBits(retTy);
1210 if (ivarSize > retTySize) {
1211 bitcastType = llvm::Type::getIntNTy(getLLVMContext(), retTySize);
1212 ivarVal = Builder.CreateTrunc(ivarVal, bitcastType);
1213 }
1214 Builder.CreateStore(ivarVal, ReturnValue.withElementType(bitcastType));
1215
1216
1218 return;
1219 }
1220
1221 case PropertyImplStrategy::GetSetProperty: {
1222 llvm::FunctionCallee getPropertyFn =
1223 CGM.getObjCRuntime().GetPropertyGetFunction();
1224
1226
1227
1228
1229 CGM.ErrorUnsupported(propImpl,
1230 "Obj-C getter requiring pointer authentication");
1231 return;
1232 }
1233
1234 if (!getPropertyFn) {
1235 CGM.ErrorUnsupported(propImpl, "Obj-C getter requiring atomic copy");
1236 return;
1237 }
1239
1240
1241
1242
1245 llvm::Value *ivarOffset =
1247
1254
1255
1256
1257 llvm::CallBase *CallInstruction;
1259 getContext().getObjCIdType(), args),
1261 if (llvm::CallInst *call = dyn_castllvm::CallInst(CallInstruction))
1262 call->setTailCall();
1263
1264
1265
1266
1270
1271 EmitReturnOfRValue(RV, propType);
1272
1273
1275
1276 return;
1277 }
1278
1279 case PropertyImplStrategy::CopyStruct:
1281 strategy.hasStrongMember());
1282 return;
1283
1284 case PropertyImplStrategy::Expression:
1285 case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1287
1291 switch (EvaluationKind) {
1295 true);
1296 return;
1297 }
1299
1300
1301
1304 return;
1305 }
1307 llvm::Value *value;
1310 CGM.ErrorUnsupported(propImpl,
1311 "Obj-C getter for authenticated reference type");
1312 return;
1313 }
1315 } else {
1316
1320 } else {
1322 }
1323
1324
1325
1326 } else {
1329 llvm::LoadInst *LoadInst = Builder.CreateLoad(ivarAddr, "load");
1330 llvm::Value *Load = LoadInst;
1333 CGM.getPointerAuthInfoForType(getterMethod->getReturnType());
1335 false);
1336 value = Load;
1337 } else
1339
1341 }
1342
1343 value = Builder.CreateBitCast(
1345 }
1346
1347 EmitReturnOfRValue(RValue::get(value), propType);
1348 return;
1349 }
1350 }
1351 llvm_unreachable("bad evaluation kind");
1352 }
1353
1354 }
1355 llvm_unreachable("bad @property implementation strategy!");
1356}
1357
1358
1359
1362
1363
1365
1366
1367 llvm::Value *ivarAddr =
1370 ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
1372
1373
1380
1381
1382 llvm::Value *size =
1385
1386
1388
1389
1390
1392
1398}
1399
1400
1401
1402
1406 llvm::Constant *AtomicHelperFn) {
1407
1408
1410
1411
1412 llvm::Value *ivarAddr =
1416
1417
1424
1425
1427
1428 llvm::FunctionCallee fn =
1434}
1435
1436
1439 if (!setter) return true;
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449 if (CallExpr *call = dyn_cast(setter)) {
1451 = dyn_cast_or_null(call->getCalleeDecl()))
1452 if (callee->isTrivial())
1453 return true;
1454 return false;
1455 }
1456
1458 return false;
1459}
1460
1466
1467void
1470 llvm::Constant *AtomicHelperFn) {
1473
1476 if (!AtomicHelperFn) {
1477
1478
1480 0);
1483 } else {
1484
1486 }
1487
1489 return;
1490 }
1491
1492
1493
1495 if (!AtomicHelperFn)
1496
1498 else
1499
1501 AtomicHelperFn);
1502 return;
1503 }
1504
1505 PropertyImplStrategy strategy(CGM, propImpl);
1506 switch (strategy.getKind()) {
1507 case PropertyImplStrategy::Native: {
1508
1509 if (strategy.getIvarSize().isZero())
1510 return;
1511
1513
1517
1518
1519
1520 llvm::Type *castType = llvm::Type::getIntNTy(
1522
1523
1526
1527 llvm::Value *load = Builder.CreateLoad(argAddr);
1528
1534 false);
1535 }
1536
1537
1538 llvm::StoreInst *store = Builder.CreateStore(load, ivarAddr);
1539 store->setAtomic(llvm::AtomicOrdering::Unordered);
1540 return;
1541 }
1542
1543 case PropertyImplStrategy::GetSetProperty:
1544 case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1545
1546 llvm::FunctionCallee setOptimizedPropertyFn = nullptr;
1547 llvm::FunctionCallee setPropertyFn = nullptr;
1549
1550 setOptimizedPropertyFn =
1551 CGM.getObjCRuntime().GetOptimizedPropertySetFunction(
1552 strategy.isAtomic(), strategy.isCopy());
1553 if (!setOptimizedPropertyFn) {
1554 CGM.ErrorUnsupported(propImpl, "Obj-C optimized setter - NYI");
1555 return;
1556 }
1557 }
1558 else {
1559 setPropertyFn = CGM.getObjCRuntime().GetPropertySetFunction();
1560 if (!setPropertyFn) {
1561 CGM.ErrorUnsupported(propImpl, "Obj-C setter requiring atomic copy");
1562 return;
1563 }
1564 }
1565
1566
1567
1569 llvm::Value *self =
1571 llvm::Value *ivarOffset =
1574 llvm::Value *arg = Builder.CreateLoad(argAddr, "arg");
1576
1580 if (setOptimizedPropertyFn) {
1586 } else {
1593
1594
1598 }
1599
1600 return;
1601 }
1602
1603 case PropertyImplStrategy::CopyStruct:
1605 return;
1606
1607 case PropertyImplStrategy::Expression:
1608 break;
1609 }
1610
1611
1616 CK_LValueToRValue, &self, VK_PRValue,
1620 &selfLoad, true, true);
1621
1629
1630
1631
1632
1636 argCK = CK_BitCast;
1638 argCK = CK_BlockPointerToObjCPointerCast;
1639 else
1640 argCK = CK_CPointerToObjCPointerCast;
1643 argCK = CK_BitCast;
1644 else
1645 argCK = CK_AnyPointerToBlockPointerCast;
1647 argCK = CK_BitCast;
1650 argCK = CK_AtomicToNonAtomic;
1653 argCK = CK_NonAtomicToAtomic;
1654 }
1657 Expr *finalArg = &argLoad;
1660 finalArg = &argCast;
1661
1666}
1667
1668
1669
1670
1671
1674 llvm::Constant *AtomicHelperFn =
1675 CodeGenFunction(CGM).GenerateObjCAtomicSetterCopyHelperFunction(PID);
1677 assert(OMD && "Invalid call to generate setter (empty method)");
1679
1681
1683}
1684
1685namespace {
1686 struct DestroyIvar final : EHScopeStack::Cleanup {
1687 private:
1688 llvm::Value *addr;
1691 bool useEHCleanupForArray;
1692 public:
1693 DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
1695 bool useEHCleanupForArray)
1696 : addr(addr), ivar(ivar), destroyer(destroyer),
1697 useEHCleanupForArray(useEHCleanupForArray) {}
1698
1703 flags.isForNormalCleanup() && useEHCleanupForArray);
1704 }
1705 };
1706}
1707
1708
1715
1719
1721
1726
1727
1729 if (!dtorKind) continue;
1730
1732
1733
1734
1737
1738
1739 } else {
1741 }
1742
1744
1745 CGF.EHStack.pushCleanup(cleanupKind, self, ivar, destroyer,
1747 }
1748
1749 assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?");
1750}
1751
1754 bool ctor) {
1757
1758
1759 if (ctor) {
1760
1762
1763 for (const auto *IvarInit : IMP->inits()) {
1764 FieldDecl *Field = IvarInit->getAnyMember();
1773 }
1774
1776 QualType IdTy(CGM.getContext().getObjCIdType());
1777 llvm::Value *SelfAsId =
1779 EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
1780
1781
1782 } else {
1784 }
1786}
1787
1795
1803
1805 llvm::FunctionCallee EnumerationMutationFnPtr =
1806 CGM.getObjCRuntime().EnumerationMutationFunction();
1807 if (!EnumerationMutationFnPtr) {
1808 CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
1809 return;
1810 }
1811 CGCallee EnumerationMutationFn =
1813
1815 if (DI)
1817
1819
1820
1824
1826
1827
1828 QualType StateTy = CGM.getObjCFastEnumerationStateType();
1831
1832
1833 static const unsigned NumItems = 16;
1834
1835
1837 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
1838 &CGM.getContext().Idents.get("objects"),
1839 &CGM.getContext().Idents.get("count")};
1841 CGM.getContext().Selectors.getSelector(std::size(II), &II[0]);
1842
1844 getContext().getObjCIdType(), llvm::APInt(32, NumItems), nullptr,
1847
1848
1849 llvm::Value *Collection;
1852
1853
1855 } else {
1857 }
1858
1859
1860
1862
1863
1865
1866
1868
1869
1870
1871
1872
1873
1875
1876
1878 llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumItems);
1880
1881
1885 FastEnumSel, Collection, Args);
1886
1887
1888 llvm::Value *initialBufferLimit = CountRV.getScalarVal();
1889
1890 llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
1891 llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
1892
1893 llvm::Value *zero = llvm::Constant::getNullValue(NSUIntegerTy);
1894
1895
1896
1897
1900 Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"), EmptyBB,
1901 LoopInitBB,
1903
1904
1906
1907
1908
1909
1910 Address StateMutationsPtrPtr =
1911 Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
1912 llvm::Value *StateMutationsPtr
1913 = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
1914
1916 llvm::Value *initialMutations =
1917 Builder.CreateAlignedLoad(UnsignedLongTy, StateMutationsPtr,
1919
1920
1921
1922 llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");
1924
1925
1926 llvm::PHINode *index = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.index");
1927 index->addIncoming(zero, LoopInitBB);
1928
1929
1930 llvm::PHINode *count = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.count");
1931 count->addIncoming(initialBufferLimit, LoopInitBB);
1932
1934
1935
1936
1937
1938 StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
1939 llvm::Value *currentMutations
1940 = Builder.CreateAlignedLoad(UnsignedLongTy, StateMutationsPtr,
1942
1943 llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");
1944 llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");
1945
1946 Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),
1947 WasNotMutatedBB, WasMutatedBB);
1948
1949
1952 llvm::Value *V =
1953 Builder.CreateBitCast(Collection, ObjCIdType);
1956
1957
1961
1962
1964
1965
1967 bool elementIsVariable;
1968 LValue elementLValue;
1971
1973
1977 elementLValue = EmitLValue(&tempDRE);
1978 elementType = D->getType();
1979 elementIsVariable = true;
1980
1983 } else {
1984 elementLValue = LValue();
1986 elementIsVariable = false;
1987 }
1988 llvm::Type *convertedElementType = ConvertType(elementType);
1989
1990
1991
1992
1994 Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
1995 llvm::Value *EnumStateItems =
1996 Builder.CreateLoad(StateItemsPtr, "stateitems");
1997
1998
1999 llvm::Value *CurrentItemPtr = Builder.CreateInBoundsGEP(
2000 ObjCIdType, EnumStateItems, index, "currentitem.ptr");
2001 llvm::Value *CurrentItem =
2003
2004 if (SanOpts.has(SanitizerKind::ObjCCast)) {
2005
2006
2007
2008
2009
2014 if (InterfaceTy) {
2015 auto CheckOrdinal = SanitizerKind::SO_ObjCCast;
2016 auto CheckHandler = SanitizerHandler::InvalidObjCCast;
2018 auto &C = CGM.getContext();
2019 assert(InterfaceTy->getDecl() && "No decl for ObjC interface type");
2022 llvm::Value *Cls =
2023 CGM.getObjCRuntime().GetClass(*this, InterfaceTy->getDecl());
2024 IsKindOfClassArgs.add(RValue::get(Cls), C.getObjCClassType());
2025 llvm::Value *IsClass =
2026 CGM.getObjCRuntime()
2028 IsKindOfClassSel, CurrentItem,
2029 IsKindOfClassArgs)
2030 .getScalarVal();
2031 llvm::Constant *StaticData[] = {
2034 EmitCheck({{IsClass, CheckOrdinal}}, CheckHandler,
2036 }
2037 }
2038
2039
2040 CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,
2041 "currentitem");
2042
2043
2044
2045 if (!elementIsVariable) {
2048 } else {
2050 true);
2051 }
2052
2053
2054
2055 if (elementIsVariable)
2057
2058
2059 BreakContinueStack.push_back(BreakContinue(S, LoopEnd, AfterBody));
2060 {
2063 }
2064 BreakContinueStack.pop_back();
2065
2066
2068
2069
2071
2072 llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
2073
2074
2075 llvm::Value *indexPlusOne =
2076 Builder.CreateNUWAdd(index, llvm::ConstantInt::get(NSUIntegerTy, 1));
2077
2078
2079
2080
2081
2083 Builder.CreateICmpULT(indexPlusOne, count), LoopBodyBB, FetchMoreBB,
2085
2086 index->addIncoming(indexPlusOne, AfterBody.getBlock());
2087 count->addIncoming(count, AfterBody.getBlock());
2088
2089
2091
2092 CountRV =
2095 FastEnumSel, Collection, Args);
2096
2097
2098 llvm::Value *refetchCount = CountRV.getScalarVal();
2099
2100
2101 index->addIncoming(zero, Builder.GetInsertBlock());
2102 count->addIncoming(refetchCount, Builder.GetInsertBlock());
2103
2104 Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),
2105 EmptyBB, LoopBodyBB);
2106
2107
2109
2110 if (!elementIsVariable) {
2111
2112
2113 llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
2116 }
2117
2118 if (DI)
2120
2123}
2124
2126 CGM.getObjCRuntime().EmitTryStmt(*this, S);
2127}
2128
2130 CGM.getObjCRuntime().EmitThrowStmt(*this, S);
2131}
2132
2135 CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
2136}
2137
2138namespace {
2139 struct CallObjCRelease final : EHScopeStack::Cleanup {
2140 CallObjCRelease(llvm::Value *object) : object(object) {}
2141 llvm::Value *object;
2142
2144
2146 }
2147 };
2148}
2149
2150
2151
2153 llvm::Value *object) {
2154
2155
2157 return object;
2158}
2159
2161 llvm::Value *value) {
2163}
2164
2165
2166
2168 llvm::Function *&fn = CGM.getObjCEntrypoints().clang_arc_use;
2169 if (!fn)
2170 fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_use);
2171
2172
2173
2175}
2176
2177
2178
2180 llvm::Function *&fn = CGM.getObjCEntrypoints().clang_arc_noop_use;
2181 if (!fn)
2182 fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_noop_use);
2184}
2185
2187 if (auto *F = dyn_castllvm::Function(RTF)) {
2188
2189
2190
2192 !CGM.getTriple().isOSBinFormatCOFF()) {
2193 F->setLinkage(llvm::Function::ExternalWeakLinkage);
2194 }
2195 }
2196}
2197
2199 llvm::FunctionCallee RTF) {
2201}
2202
2205 llvm::Function *fn = CGM.getIntrinsic(IntID);
2207 return fn;
2208}
2209
2210
2211
2212
2214 CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType,
2215 llvm::Function *&fn, llvm::Intrinsic::ID IntID,
2216 llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) {
2218 return value;
2219
2220 if (!fn)
2222
2223
2224 llvm::Type *origType = returnType ? returnType : value->getType();
2226
2227
2229 call->setTailCallKind(tailKind);
2230
2231
2232 return CGF.Builder.CreateBitCast(call, origType);
2233}
2234
2235
2236
2238 llvm::Function *&fn,
2239 llvm::Intrinsic::ID IntID) {
2240 if (!fn)
2242
2244}
2245
2246
2247
2249 llvm::Value *value,
2250 llvm::Function *&fn,
2251 llvm::Intrinsic::ID IntID,
2252 bool ignored) {
2254
2255 if (!fn)
2257
2258 llvm::Type *origType = value->getType();
2259
2260 llvm::Value *args[] = {
2264
2265 if (ignored) return nullptr;
2266
2267 return CGF.Builder.CreateBitCast(result, origType);
2268}
2269
2270
2271
2273 llvm::Function *&fn,
2274 llvm::Intrinsic::ID IntID) {
2275 assert(dst.getType() == src.getType());
2276
2277 if (!fn)
2279
2280 llvm::Value *args[] = {
2284}
2285
2286
2287
2288
2290 llvm::Value *value,
2291 llvm::Type *returnType,
2292 llvm::FunctionCallee &fn,
2293 StringRef fnName) {
2295 return value;
2296
2297 if (!fn) {
2298 llvm::FunctionType *fnType =
2301
2302
2303 if (llvm::Function *f = dyn_castllvm::Function(fn.getCallee()))
2304 if (fnName == "objc_retain")
2305 f->addFnAttr(llvm::Attribute::NonLazyBind);
2306 }
2307
2308
2309 llvm::Type *origType = returnType ? returnType : value->getType();
2311
2312
2314
2315
2316
2317 if (fnName == "objc_autorelease")
2318 if (auto *Call = dyn_castllvm::CallInst(Inst))
2319 Call->setTailCall();
2320
2321
2322 return CGF.Builder.CreateBitCast(Inst, origType);
2323}
2324
2325
2326
2327
2329 if (type->isBlockPointerType())
2331 else
2333}
2334
2335
2336
2339 CGM.getObjCEntrypoints().objc_retain,
2340 llvm::Intrinsic::objc_retain);
2341}
2342
2343
2344
2345
2346
2347
2348
2350 bool mandatory) {
2351 llvm::Value *result
2353 CGM.getObjCEntrypoints().objc_retainBlock,
2354 llvm::Intrinsic::objc_retainBlock);
2355
2356
2357
2358
2359
2361 llvm::CallInst *call
2363 assert(call->getCalledOperand() ==
2364 CGM.getObjCEntrypoints().objc_retainBlock);
2365
2366 call->setMetadata("clang.arc.copy_on_escape",
2367 llvm::MDNode::get(Builder.getContext(), {}));
2368 }
2369
2370 return result;
2371}
2372
2374
2375
2376 llvm::InlineAsm *&marker
2378 if (!marker) {
2379 StringRef assembly
2382
2383
2384 if (assembly.empty()) {
2385
2386
2387
2389 llvm::FunctionType *type =
2390 llvm::FunctionType::get(CGF.VoidTy, false);
2391
2392 marker = llvm::InlineAsm::get(type, assembly, "", true);
2393
2394
2395
2396
2397 } else {
2398 const char *retainRVMarkerKey = llvm::objcarc::getRVMarkerModuleFlagStr();
2399 if (!CGF.CGM.getModule().getModuleFlag(retainRVMarkerKey)) {
2400 auto *str = llvm::MDString::get(CGF.getLLVMContext(), assembly);
2401 CGF.CGM.getModule().addModuleFlag(llvm::Module::Error,
2402 retainRVMarkerKey, str);
2403 }
2404 }
2405 }
2406
2407
2408 if (marker)
2410}
2411
2413 bool IsRetainRV,
2416
2417
2418
2419
2420
2422 llvm::Function *&EP = IsRetainRV
2425 llvm::Intrinsic::ID IID =
2426 IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue
2427 : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
2429
2430 llvm::Triple::ArchType Arch = CGF.CGM.getTriple().getArch();
2431
2432
2433
2435 (Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_32 ||
2436 Arch == llvm::Triple::x86_64)) {
2437 llvm::Value *bundleArgs[] = {EP};
2438 llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs);
2440 llvm::CallBase *newCall = llvm::CallBase::addOperandBundle(
2441 oldCall, llvm::LLVMContext::OB_clang_arc_attachedcall, OB,
2442 oldCall->getIterator());
2443 newCall->copyMetadata(*oldCall);
2444 oldCall->replaceAllUsesWith(newCall);
2445 oldCall->eraseFromParent();
2447 return newCall;
2448 }
2449
2450 bool isNoTail =
2452 llvm::CallInst::TailCallKind tailKind =
2453 isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None;
2455}
2456
2457
2458
2459
2460
2461
2462llvm::Value *
2466
2467
2468
2469
2470
2471
2472
2473
2474llvm::Value *
2478
2479
2480
2484
2485 llvm::Function *&fn = CGM.getObjCEntrypoints().objc_release;
2486 if (!fn)
2488
2489
2491
2492
2494
2496 call->setMetadata("clang.imprecise_release",
2497 llvm::MDNode::get(Builder.getContext(), {}));
2498 }
2499}
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2512 if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
2515 return;
2516 }
2517
2518 llvm::Value *value = Builder.CreateLoad(addr);
2520}
2521
2522
2523
2525 llvm::Value *value,
2526 bool ignored) {
2528
2529 llvm::Function *&fn = CGM.getObjCEntrypoints().objc_storeStrong;
2530 if (!fn)
2532
2533 llvm::Value *args[] = {
2537
2538 if (ignored) return nullptr;
2539 return value;
2540}
2541
2542
2543
2544
2546 llvm::Value *newValue,
2547 bool ignored) {
2549 bool isBlock = type->isBlockPointerType();
2550
2551
2552
2554 !isBlock &&
2555 (dst.getAlignment().isZero() ||
2558 }
2559
2560
2561
2562
2564
2565
2567
2568
2569
2571
2572
2573 EmitARCRelease(oldValue, dst.isARCPreciseLifetime());
2574
2575 return newValue;
2576}
2577
2578
2579
2582 CGM.getObjCEntrypoints().objc_autorelease,
2583 llvm::Intrinsic::objc_autorelease);
2584}
2585
2586
2587
2588llvm::Value *
2591 CGM.getObjCEntrypoints().objc_autoreleaseReturnValue,
2592 llvm::Intrinsic::objc_autoreleaseReturnValue,
2593 llvm::CallInst::TCK_Tail);
2594}
2595
2596
2597
2598llvm::Value *
2601 CGM.getObjCEntrypoints().objc_retainAutoreleaseReturnValue,
2602 llvm::Intrinsic::objc_retainAutoreleaseReturnValue,
2603 llvm::CallInst::TCK_Tail);
2604}
2605
2606
2607
2608
2609
2610
2612 llvm::Value *value) {
2613 if (->isBlockPointerType())
2615
2617
2618 llvm::Type *origType = value->getType();
2622 return Builder.CreateBitCast(value, origType);
2623}
2624
2625
2626
2627llvm::Value *
2630 CGM.getObjCEntrypoints().objc_retainAutorelease,
2631 llvm::Intrinsic::objc_retainAutorelease);
2632}
2633
2634
2635
2638 CGM.getObjCEntrypoints().objc_loadWeak,
2639 llvm::Intrinsic::objc_loadWeak);
2640}
2641
2642
2645 CGM.getObjCEntrypoints().objc_loadWeakRetained,
2646 llvm::Intrinsic::objc_loadWeakRetained);
2647}
2648
2649
2650
2652 llvm::Value *value,
2653 bool ignored) {
2655 CGM.getObjCEntrypoints().objc_storeWeak,
2656 llvm::Intrinsic::objc_storeWeak, ignored);
2657}
2658
2659
2660
2661
2662
2664
2665
2666
2667
2669 CGM.getCodeGenOpts().OptimizationLevel == 0) {
2670 Builder.CreateStore(value, addr);
2671 return;
2672 }
2673
2675 CGM.getObjCEntrypoints().objc_initWeak,
2676 llvm::Intrinsic::objc_initWeak, true);
2677}
2678
2679
2680
2682 llvm::Function *&fn = CGM.getObjCEntrypoints().objc_destroyWeak;
2683 if (!fn)
2685
2687}
2688
2689
2690
2691
2694 CGM.getObjCEntrypoints().objc_moveWeak,
2695 llvm::Intrinsic::objc_moveWeak);
2696}
2697
2698
2699
2700
2703 CGM.getObjCEntrypoints().objc_copyWeak,
2704 llvm::Intrinsic::objc_copyWeak);
2705}
2706
2713
2721
2722
2723
2725 llvm::Function *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPush;
2726 if (!fn)
2727 fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush, CGM);
2728
2730}
2731
2732
2733
2735 assert(value->getType() == Int8PtrTy);
2736
2738
2739 llvm::FunctionCallee &fn =
2740 CGM.getObjCEntrypoints().objc_autoreleasePoolPopInvoke;
2741 if (!fn) {
2742 llvm::FunctionType *fnType =
2743 llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);
2744 fn = CGM.CreateRuntimeFunction(fnType, "objc_autoreleasePoolPop");
2746 }
2747
2748
2750 } else {
2751 llvm::FunctionCallee &fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop;
2752 if (!fn)
2753 fn = getARCIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop, CGM);
2754
2756 }
2757}
2758
2759
2760
2761
2762
2763
2767
2768 const IdentifierInfo *II = &CGM.getContext().Idents.get("alloc");
2774 AllocSel, Receiver, Args);
2775
2776
2778 II = &CGM.getContext().Idents.get("init");
2783 InitSel, Receiver, Args);
2785}
2786
2787
2788
2790 llvm::Type *resultType) {
2792 CGM.getObjCEntrypoints().objc_alloc,
2793 "objc_alloc");
2794}
2795
2796
2797
2799 llvm::Type *resultType) {
2801 CGM.getObjCEntrypoints().objc_allocWithZone,
2802 "objc_allocWithZone");
2803}
2804
2806 llvm::Type *resultType) {
2808 CGM.getObjCEntrypoints().objc_alloc_init,
2809 "objc_alloc_init");
2810}
2811
2812
2813
2821
2826}
2827
2832}
2833
2838}
2839
2841 QualType type) {
2844}
2845
2846
2847
2849 llvm::Type *returnType) {
2851 *this, value, returnType,
2852 CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction,
2853 "objc_autorelease");
2854}
2855
2856
2857
2859 llvm::Type *returnType) {
2861 *this, value, returnType,
2862 CGM.getObjCEntrypoints().objc_retainRuntimeFunction, "objc_retain");
2863}
2864
2865
2866
2870
2871 llvm::FunctionCallee &fn =
2872 CGM.getObjCEntrypoints().objc_releaseRuntimeFunction;
2873 if (!fn) {
2874 llvm::FunctionType *fnType =
2875 llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);
2876 fn = CGM.CreateRuntimeFunction(fnType, "objc_release");
2878
2879 if (llvm::Function *f = dyn_castllvm::Function(fn.getCallee()))
2880 f->addFnAttr(llvm::Attribute::NonLazyBind);
2881 }
2882
2883
2885
2886
2888
2890 call->setMetadata("clang.imprecise_release",
2891 llvm::MDNode::get(Builder.getContext(), {}));
2892 }
2893}
2894
2895namespace {
2896 struct CallObjCAutoreleasePoolObject final : EHScopeStack::Cleanup {
2897 llvm::Value *Token;
2898
2899 CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
2900
2903 }
2904 };
2905 struct CallObjCMRRAutoreleasePoolObject final : EHScopeStack::Cleanup {
2906 llvm::Value *Token;
2907
2908 CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
2909
2910 void Emit(CodeGenFunction &CGF, Flags flags) override {
2912 }
2913 };
2914}
2915
2917 if (CGM.getLangOpts().ObjCAutoRefCount)
2919 else
2921}
2922
2924 switch (lifetime) {
2929 return true;
2930
2932 return false;
2933 }
2934
2935 llvm_unreachable("impossible lifetime!");
2936}
2937
2939 LValue lvalue,
2941 llvm::Value *result;
2943 if (shouldRetain) {
2945 } else {
2948 }
2950}
2951
2953 const Expr *e) {
2956
2957
2958
2959
2961 .isConstQualified() &&
2963
2965
2966
2969
2970
2972
2974 }
2975
2976
2977
2978
2980 .isVolatileQualified() &&
2985
2986
2987
2988
2989 if (const auto *decl_expr = dyn_cast(e)) {
2990 auto *DRE = const_cast<DeclRefExpr *>(decl_expr);
2994 }
2995
2997}
2998
2999typedef llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
3000 llvm::Value *value)>
3002
3003
3004
3005
3006
3008 llvm::Value *value,
3011 CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
3012 auto *callBase = dyn_castllvm::CallBase(value);
3013
3014 if (callBase && llvm::objcarc::hasAttachedCallOpBundle(callBase)) {
3015
3016 value = doFallback(CGF, value);
3017 } else if (llvm::CallInst *call = dyn_castllvm::CallInst(value)) {
3018
3019 CGF.Builder.SetInsertPoint(call->getParent(),
3020 ++llvm::BasicBlock::iterator(call));
3021 value = doAfterCall(CGF, value);
3022 } else if (llvm::InvokeInst *invoke = dyn_castllvm::InvokeInst(value)) {
3023
3024 llvm::BasicBlock *BB = invoke->getNormalDest();
3025 CGF.Builder.SetInsertPoint(BB, BB->begin());
3026 value = doAfterCall(CGF, value);
3027
3028
3029
3030 } else if (llvm::BitCastInst *bitcast = dyn_castllvm::BitCastInst(value)) {
3031
3032
3033 CGF.Builder.SetInsertPoint(bitcast->getParent(), bitcast->getIterator());
3034 llvm::Value *operand = bitcast->getOperand(0);
3036 bitcast->setOperand(0, operand);
3037 value = bitcast;
3038 } else {
3039 auto *phi = dyn_castllvm::PHINode(value);
3040 if (phi && phi->getNumIncomingValues() == 2 &&
3043
3044
3045 llvm::Value *inVal = phi->getIncomingValue(0);
3047 phi->setIncomingValue(0, inVal);
3048 value = phi;
3049 } else {
3050
3051
3052
3053 value = doFallback(CGF, value);
3054 }
3055 }
3056
3057 CGF.Builder.restoreIP(ip);
3058 return value;
3059}
3060
3061
3062
3064 const Expr *e) {
3069 },
3072 });
3073}
3074
3075
3076
3078 const Expr *e) {
3083 },
3085 return value;
3086 });
3087}
3088
3090 bool allowUnsafeClaim) {
3091 if (allowUnsafeClaim &&
3092 CGM.getLangOpts().ObjCRuntime.hasARCUnsafeClaimAutoreleasedReturnValue()) {
3094 } else {
3097 }
3098}
3099
3100
3101
3102
3106
3107
3108
3110 return false;
3111
3112 if (const CastExpr *cast = dyn_cast(e)) {
3113 switch (cast->getCastKind()) {
3114
3115 case CK_LValueToRValue:
3116 case CK_ARCReclaimReturnedObject:
3117 case CK_ARCConsumeObject:
3118 case CK_ARCProduceObject:
3119 return false;
3120
3121
3122 case CK_NoOp:
3123 case CK_BitCast:
3125
3126
3127 case CK_AnyPointerToBlockPointerCast:
3128 default:
3129 return true;
3130 }
3131 }
3132
3133 return true;
3134}
3135
3136namespace {
3137
3138
3139template <typename Impl, typename Result> class ARCExprEmitter {
3140protected:
3141 CodeGenFunction &CGF;
3142 Impl &asImpl() { return *static_cast<Impl*>(this); }
3143
3144 ARCExprEmitter(CodeGenFunction &CGF) : CGF(CGF) {}
3145
3146public:
3147 Result visit(const Expr *e);
3149 Result visitPseudoObjectExpr(const PseudoObjectExpr *e);
3150 Result visitBlockExpr(const BlockExpr *e);
3151 Result visitBinaryOperator(const BinaryOperator *e);
3152 Result visitBinAssign(const BinaryOperator *e);
3153 Result visitBinAssignUnsafeUnretained(const BinaryOperator *e);
3154 Result visitBinAssignAutoreleasing(const BinaryOperator *e);
3155 Result visitBinAssignWeak(const BinaryOperator *e);
3156 Result visitBinAssignStrong(const BinaryOperator *e);
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168};
3169}
3170
3171
3172
3173
3174template <typename Impl, typename Result>
3176ARCExprEmitter<Impl,Result>::visitPseudoObjectExpr(const PseudoObjectExpr *E) {
3177 SmallVector<CodeGenFunction::OpaqueValueMappingData, 4> opaques;
3178
3179
3181 assert(resultExpr);
3183
3186 const Expr *semantic = *i;
3187
3188
3189
3190 if (const OpaqueValueExpr *ov = dyn_cast(semantic)) {
3192 OVMA opaqueData;
3193
3194
3195
3196 if (ov == resultExpr) {
3197 assert(!OVMA::shouldBindAsLValue(ov));
3198 result = asImpl().visit(ov->getSourceExpr());
3199 opaqueData = OVMA::bind(CGF, ov,
3200 RValue::get(asImpl().getValueOfResult(result)));
3201
3202
3203 } else {
3204 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
3205 }
3206 opaques.push_back(opaqueData);
3207
3208
3209
3210 } else if (semantic == resultExpr) {
3211 result = asImpl().visit(semantic);
3212
3213
3214 } else {
3215 CGF.EmitIgnoredExpr(semantic);
3216 }
3217 }
3218
3219
3221 opaque.unbind(CGF);
3222
3223 return result;
3224}
3225
3226template <typename Impl, typename Result>
3227Result ARCExprEmitter<Impl, Result>::visitBlockExpr(const BlockExpr *e) {
3228
3229 return asImpl().visitExpr(e);
3230}
3231
3232template <typename Impl, typename Result>
3233Result ARCExprEmitter<Impl,Result>::visitCastExpr(const CastExpr *e) {
3235
3236
3237 case CK_NoOp:
3238 return asImpl().visit(e->getSubExpr());
3239
3240
3241 case CK_CPointerToObjCPointerCast:
3242 case CK_BlockPointerToObjCPointerCast:
3243 case CK_AnyPointerToBlockPointerCast:
3244 case CK_BitCast: {
3245 llvm::Type *resultType = CGF.ConvertType(e->getType());
3248 return asImpl().emitBitCast(result, resultType);
3249 }
3250
3251
3252 case CK_LValueToRValue:
3253 return asImpl().visitLValueToRValue(e->getSubExpr());
3254 case CK_ARCConsumeObject:
3255 return asImpl().visitConsumeObject(e->getSubExpr());
3256 case CK_ARCExtendBlockObject:
3257 return asImpl().visitExtendBlockObject(e->getSubExpr());
3258 case CK_ARCReclaimReturnedObject:
3259 return asImpl().visitReclaimReturnedObject(e->getSubExpr());
3260
3261
3262 default:
3263 return asImpl().visitExpr(e);
3264 }
3265}
3266
3267template <typename Impl, typename Result>
3269ARCExprEmitter<Impl,Result>::visitBinaryOperator(const BinaryOperator *e) {
3271 case BO_Comma:
3272 CGF.EmitIgnoredExpr(e->getLHS());
3273 CGF.EnsureInsertPoint();
3274 return asImpl().visit(e->getRHS());
3275
3276 case BO_Assign:
3277 return asImpl().visitBinAssign(e);
3278
3279 default:
3280 return asImpl().visitExpr(e);
3281 }
3282}
3283
3284template <typename Impl, typename Result>
3285Result ARCExprEmitter<Impl,Result>::visitBinAssign(const BinaryOperator *e) {
3288 return asImpl().visitBinAssignUnsafeUnretained(e);
3289
3291 return asImpl().visitBinAssignWeak(e);
3292
3294 return asImpl().visitBinAssignAutoreleasing(e);
3295
3297 return asImpl().visitBinAssignStrong(e);
3298
3300 return asImpl().visitExpr(e);
3301 }
3302 llvm_unreachable("bad ObjC ownership qualifier");
3303}
3304
3305
3306
3307template <typename Impl, typename Result>
3308Result ARCExprEmitter<Impl,Result>::
3309 visitBinAssignUnsafeUnretained(const BinaryOperator *e) {
3310
3311
3312 Result result = asImpl().visit(e->getRHS());
3313
3314
3317 CGF.EmitStoreThroughLValue(RValue::get(asImpl().getValueOfResult(result)),
3318 lvalue);
3319
3320 return result;
3321}
3322
3323template <typename Impl, typename Result>
3325ARCExprEmitter<Impl,Result>::visitBinAssignAutoreleasing(const BinaryOperator *e) {
3326 return asImpl().visitExpr(e);
3327}
3328
3329template <typename Impl, typename Result>
3331ARCExprEmitter<Impl,Result>::visitBinAssignWeak(const BinaryOperator *e) {
3332 return asImpl().visitExpr(e);
3333}
3334
3335template <typename Impl, typename Result>
3337ARCExprEmitter<Impl,Result>::visitBinAssignStrong(const BinaryOperator *e) {
3338 return asImpl().visitExpr(e);
3339}
3340
3341
3342template <typename Impl, typename Result>
3343Result ARCExprEmitter<Impl,Result>::visit(const Expr *e) {
3344
3345
3346
3347
3349
3350
3352
3353
3354 if (const CastExpr *ce = dyn_cast(e)) {
3355 return asImpl().visitCastExpr(ce);
3356
3357
3358 } else if (auto op = dyn_cast(e)) {
3359 return asImpl().visitBinaryOperator(op);
3360
3361
3362
3363
3364
3365
3366
3370 return asImpl().visitCall(e);
3371
3372
3373 } else if (const PseudoObjectExpr *pseudo = dyn_cast(e)) {
3374 return asImpl().visitPseudoObjectExpr(pseudo);
3375 } else if (auto *be = dyn_cast(e))
3376 return asImpl().visitBlockExpr(be);
3377
3378 return asImpl().visitExpr(e);
3379}
3380
3381namespace {
3382
3383
3384struct ARCRetainExprEmitter :
3385 public ARCExprEmitter<ARCRetainExprEmitter, TryEmitResult> {
3386
3387 ARCRetainExprEmitter(CodeGenFunction &CGF) : ARCExprEmitter(CGF) {}
3388
3389 llvm::Value *getValueOfResult(TryEmitResult result) {
3390 return result.getPointer();
3391 }
3392
3394 llvm::Value *value = result.getPointer();
3395 value = CGF.Builder.CreateBitCast(value, resultType);
3396 result.setPointer(value);
3397 return result;
3398 }
3399
3400 TryEmitResult visitLValueToRValue(const Expr *e) {
3402 }
3403
3404
3405
3406 TryEmitResult visitConsumeObject(const Expr *e) {
3407 llvm::Value *result = CGF.EmitScalarExpr(e);
3409 }
3410
3411 TryEmitResult visitBlockExpr(const BlockExpr *e) {
3413
3414
3415 if (CGF.CGM.getCodeGenOpts().ObjCAvoidHeapifyLocalBlocks &&
3417 result.setInt(true);
3418 return result;
3419 }
3420
3421
3422
3423
3424 TryEmitResult visitExtendBlockObject(const Expr *e) {
3425 llvm::Value *result;
3426
3427
3428
3430 result = CGF.EmitScalarExpr(e);
3431
3432
3433 } else {
3435
3436
3437 if (subresult.getInt()) {
3438 return subresult;
3439 }
3440
3441
3442 result = subresult.getPointer();
3443 }
3444
3445
3446 result = CGF.EmitARCRetainBlock(result, true);
3448 }
3449
3450
3451
3452 TryEmitResult visitReclaimReturnedObject(const Expr *e) {
3455 }
3456
3457
3461 }
3462
3463
3464
3466
3467
3468 llvm::Value *result = CGF.EmitScalarExpr(e);
3470 }
3471};
3472}
3473
3476 return ARCRetainExprEmitter(CGF).visit(e);
3477}
3478
3480 LValue lvalue,
3483 llvm::Value *value = result.getPointer();
3484 if (!result.getInt())
3486 return value;
3487}
3488
3489
3490
3491
3492
3494
3495 if (const ExprWithCleanups *cleanups = dyn_cast(e)) {
3498 }
3499
3501 llvm::Value *value = result.getPointer();
3502 if (!result.getInt())
3504 return value;
3505}
3506
3507llvm::Value *
3509
3510 if (const ExprWithCleanups *cleanups = dyn_cast(e)) {
3513 }
3514
3516 llvm::Value *value = result.getPointer();
3517 if (result.getInt())
3519 else
3521 return value;
3522}
3523
3525 llvm::Value *result;
3526 bool doRetain;
3527
3530 doRetain = true;
3531 } else {
3533 result = subresult.getPointer();
3534 doRetain = !subresult.getInt();
3535 }
3536
3537 if (doRetain)
3540}
3541
3543
3545
3546
3548 }
3549
3550
3551
3552
3553
3554
3556}
3557
3558namespace {
3559
3560
3561struct ARCUnsafeUnretainedExprEmitter :
3562 public ARCExprEmitter<ARCUnsafeUnretainedExprEmitter, llvm::Value*> {
3563
3564 ARCUnsafeUnretainedExprEmitter(CodeGenFunction &CGF) : ARCExprEmitter(CGF) {}
3565
3566 llvm::Value *getValueOfResult(llvm::Value *value) {
3567 return value;
3568 }
3569
3570 llvm::Value *emitBitCast(llvm::Value *value, llvm::Type *resultType) {
3571 return CGF.Builder.CreateBitCast(value, resultType);
3572 }
3573
3574 llvm::Value *visitLValueToRValue(const Expr *e) {
3575 return CGF.EmitScalarExpr(e);
3576 }
3577
3578
3579
3580 llvm::Value *visitConsumeObject(const Expr *e) {
3581 llvm::Value *value = CGF.EmitScalarExpr(e);
3582 return CGF.EmitObjCConsumeObject(e->getType(), value);
3583 }
3584
3585
3586
3587 llvm::Value *visitExtendBlockObject(const Expr *e) {
3588 return CGF.EmitARCExtendBlockObject(e);
3589 }
3590
3591
3592 llvm::Value *visitReclaimReturnedObject(const Expr *e) {
3593 return CGF.EmitARCReclaimReturnedObject(e, true);
3594 }
3595
3596
3597
3598 llvm::Value *visitCall(const Expr *e) {
3599 return CGF.EmitScalarExpr(e);
3600 }
3601
3602
3603 llvm::Value *visitExpr(const Expr *e) {
3604 return CGF.EmitScalarExpr(e);
3605 }
3606};
3607}
3608
3610 const Expr *e) {
3611 return ARCUnsafeUnretainedExprEmitter(CGF).visit(e);
3612}
3613
3614
3615
3616
3617
3619
3620 if (const ExprWithCleanups *cleanups = dyn_cast(e)) {
3623 }
3624
3626}
3627
3628std::pair<LValue,llvm::Value*>
3630 bool ignored) {
3631
3632
3633 llvm::Value *value;
3634 if (ignored) {
3636 } else {
3638 }
3639
3640
3643
3644 return std::pair<LValue,llvm::Value*>(std::move(lvalue), value);
3645}
3646
3647std::pair<LValue,llvm::Value*>
3649 bool ignored) {
3650
3652 llvm::Value *value = result.getPointer();
3653
3654 bool hasImmediateRetain = result.getInt();
3655
3656
3657
3658
3661 hasImmediateRetain = true;
3662 }
3663
3665
3666
3667 if (hasImmediateRetain) {
3671 } else {
3673 }
3674
3675 return std::pair<LValue,llvm::Value*>(lvalue, value);
3676}
3677
3678std::pair<LValue,llvm::Value*>
3682
3684
3685 return std::pair<LValue,llvm::Value*>(lvalue, value);
3686}
3687
3692
3694 if (DI)
3696
3697
3699 if (CGM.getLangOpts().ObjCRuntime.hasNativeARC()) {
3702 } else {
3704 EHStack.pushCleanup(NormalCleanup, token);
3705 }
3706
3707 for (const auto *I : S.body())
3709
3710 if (DI)
3712}
3713
3714
3715
3717
3718 llvm::FunctionType *extenderType
3720 llvm::InlineAsm *extender = llvm::InlineAsm::get(extenderType,
3721 "",
3722 "r",
3723 true);
3724
3726}
3727
3728
3729
3730
3731
3732llvm::Constant *
3737 return nullptr;
3738
3741
3743
3744
3745 CharUnits Alignment = C.getTypeAlignInChars(Ty);
3748 return Fn;
3749 }
3750
3753 return nullptr;
3755 return nullptr;
3756 llvm::Constant *HelperFn = nullptr;
3758 return nullptr;
3760 if ((HelperFn = CGM.getAtomicSetterHelperFnMap(Ty)))
3761 return HelperFn;
3762
3764 &CGM.getContext().Idents.get("__assign_helper_atomic_property_");
3765
3767 QualType DestTy = C.getPointerType(Ty);
3770 SrcTy = C.getPointerType(SrcTy);
3771
3773 ArgTys.push_back(DestTy);
3774 ArgTys.push_back(SrcTy);
3775 QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
3776
3779 FunctionTy, nullptr, SC_Static, false, false, false);
3780
3786 nullptr);
3787 args.push_back(Params[0] = DstDecl);
3791 nullptr);
3792 args.push_back(Params[1] = SrcDecl);
3793 FD->setParams(Params);
3794
3796 CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);
3797
3798 llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
3799
3800 llvm::Function *Fn =
3801 llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
3802 "__assign_helper_atomic_property_",
3803 &CGM.getModule());
3804
3805 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
3806
3808
3813
3818
3819 Expr *Args[2] = {DST, SRC};
3824
3826
3828 HelperFn = Fn;
3829 CGM.setAtomicSetterHelperFnMap(Ty, HelperFn);
3830 return HelperFn;
3831}
3832
3837 return nullptr;
3838
3841
3843 CharUnits Alignment = C.getTypeAlignInChars(Ty);
3846 return Fn;
3847 }
3848
3851 return nullptr;
3853 return nullptr;
3854 llvm::Constant *HelperFn = nullptr;
3856 return nullptr;
3858 if ((HelperFn = CGM.getAtomicGetterHelperFnMap(Ty)))
3859 return HelperFn;
3860
3862 &CGM.getContext().Idents.get("__copy_helper_atomic_property_");
3863
3865 QualType DestTy = C.getPointerType(Ty);
3868 SrcTy = C.getPointerType(SrcTy);
3869
3871 ArgTys.push_back(DestTy);
3872 ArgTys.push_back(SrcTy);
3873 QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
3874
3877 FunctionTy, nullptr, SC_Static, false, false, false);
3878
3884 nullptr);
3885 args.push_back(Params[0] = DstDecl);
3889 nullptr);
3890 args.push_back(Params[1] = SrcDecl);
3891 FD->setParams(Params);
3892
3894 CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, args);
3895
3896 llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
3897
3898 llvm::Function *Fn = llvm::Function::Create(
3899 LTy, llvm::GlobalValue::InternalLinkage, "__copy_helper_atomic_property_",
3900 &CGM.getModule());
3901
3902 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
3903
3905
3908
3912
3915
3917 ConstructorArgs.push_back(SRC);
3918 ConstructorArgs.append(std::next(CXXConstExpr->arg_begin()),
3919 CXXConstExpr->arg_end());
3920
3925 ConstructorArgs,
3932
3935
3945
3947 HelperFn = Fn;
3948 CGM.setAtomicGetterHelperFnMap(Ty, HelperFn);
3949 return HelperFn;
3950}
3951
3952llvm::Value *
3954
3959 Selector AutoreleaseSelector =
3961
3962
3964 llvm::Value *Val = Block;
3967 Ty, CopySelector,
3969 Val = Result.getScalarVal();
3971 Ty, AutoreleaseSelector,
3973 Val = Result.getScalarVal();
3974 return Val;
3975}
3976
3978 switch (TT.getOS()) {
3979 case llvm::Triple::Darwin:
3980 case llvm::Triple::MacOSX:
3981 return llvm::MachO::PLATFORM_MACOS;
3982 case llvm::Triple::IOS:
3983 return llvm::MachO::PLATFORM_IOS;
3984 case llvm::Triple::TvOS:
3985 return llvm::MachO::PLATFORM_TVOS;
3986 case llvm::Triple::WatchOS:
3987 return llvm::MachO::PLATFORM_WATCHOS;
3988 case llvm::Triple::XROS:
3989 return llvm::MachO::PLATFORM_XROS;
3990 case llvm::Triple::DriverKit:
3991 return llvm::MachO::PLATFORM_DRIVERKIT;
3992 default:
3993 return llvm::MachO::PLATFORM_UNKNOWN;
3994 }
3995}
3996
3998 const VersionTuple &Version) {
4000
4001
4002
4004
4005 auto EmitArgs = [&](const VersionTuple &Version, const llvm::Triple &TT) {
4006 std::optional Min = Version.getMinor(),
4007 SMin = Version.getSubminor();
4008 Args.push_back(
4010 Args.push_back(llvm::ConstantInt::get(CGM.Int32Ty, Version.getMajor()));
4011 Args.push_back(llvm::ConstantInt::get(CGM.Int32Ty, Min.value_or(0)));
4012 Args.push_back(llvm::ConstantInt::get(CGM.Int32Ty, SMin.value_or(0)));
4013 };
4014
4015 assert(!Version.empty() && "unexpected empty version");
4017
4019 llvm::FunctionType *FTy = llvm::FunctionType::get(
4020 CGM.Int32Ty, {CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty, CGM.Int32Ty},
4021 false);
4024 }
4025
4026 llvm::Value *Check =
4028 return CGF.Builder.CreateICmpNE(Check,
4029 llvm::Constant::getNullValue(CGM.Int32Ty));
4030}
4031
4032llvm::Value *
4034
4035 if (CGM.getTarget().getTriple().isOSDarwin())
4037
4038 if (.IsOSVersionAtLeastFn) {
4039 llvm::FunctionType *FTy =
4041 CGM.IsOSVersionAtLeastFn =
4042 CGM.CreateRuntimeFunction(FTy, "__isOSVersionAtLeast");
4043 }
4044
4045 std::optional Min = Version.getMinor(),
4046 SMin = Version.getSubminor();
4047 llvm::Value *Args[] = {
4048 llvm::ConstantInt::get(CGM.Int32Ty, Version.getMajor()),
4049 llvm::ConstantInt::get(CGM.Int32Ty, Min.value_or(0)),
4050 llvm::ConstantInt::get(CGM.Int32Ty, SMin.value_or(0))};
4051
4052 llvm::Value *CallRes =
4054
4055 return Builder.CreateICmpNE(CallRes, llvm::Constant::getNullValue(Int32Ty));
4056}
4057
4059 const llvm::Triple &TT, const VersionTuple &TargetVersion) {
4060 VersionTuple FoundationDroppedInVersion;
4061 switch (TT.getOS()) {
4062 case llvm::Triple::IOS:
4063 case llvm::Triple::TvOS:
4064 FoundationDroppedInVersion = VersionTuple(13);
4065 break;
4066 case llvm::Triple::WatchOS:
4067 FoundationDroppedInVersion = VersionTuple(6);
4068 break;
4069 case llvm::Triple::Darwin:
4070 case llvm::Triple::MacOSX:
4071 FoundationDroppedInVersion = VersionTuple(10, 15);
4072 break;
4073 case llvm::Triple::XROS:
4074
4075 return false;
4076 case llvm::Triple::DriverKit:
4077
4078 return false;
4079 default:
4080 llvm_unreachable("Unexpected OS");
4081 }
4082 return TargetVersion < FoundationDroppedInVersion;
4083}
4084
4085void CodeGenModule::emitAtAvailableLinkGuard() {
4087 return;
4088
4089 if (!Target.getTriple().isOSDarwin())
4090 return;
4091
4092
4094 Target.getTriple(), Target.getPlatformMinVersion()))
4095 return;
4096
4097
4098
4099
4101 llvm::Metadata *Args[2] = {llvm::MDString::get(Context, "-framework"),
4102 llvm::MDString::get(Context, "CoreFoundation")};
4103 LinkerOptionsMetadata.push_back(llvm::MDNode::get(Context, Args));
4104
4105
4106 llvm::FunctionType *FTy =
4108 llvm::FunctionCallee CFFunc =
4110
4111 llvm::FunctionType *CheckFTy = llvm::FunctionType::get(VoidTy, {}, false);
4113 CheckFTy, "__clang_at_available_requires_core_foundation_framework",
4114 llvm::AttributeList(), true);
4115 llvm::Function *CFLinkCheckFunc =
4117 if (CFLinkCheckFunc->empty()) {
4118 CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
4119 CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility);
4120 CodeGenFunction CGF(*this);
4121 CGF.Builder.SetInsertPoint(CGF.createBasicBlock("", CFLinkCheckFunc));
4122 CGF.EmitNounwindRuntimeCall(CFFunc,
4123 llvm::Constant::getNullValue(VoidPtrTy));
4124 CGF.Builder.CreateUnreachable();
4126 }
4127}
4128
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
static llvm::Value * emitARCUnsafeClaimCallResult(CodeGenFunction &CGF, const Expr *e)
Given that the given expression is some sort of call (which does not return retained),...
Definition CGObjC.cpp:3077
static bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl)
Definition CGObjC.cpp:1062
static bool shouldRetainObjCLifetime(Qualifiers::ObjCLifetime lifetime)
Definition CGObjC.cpp:2923
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...
Definition CGObjC.cpp:3103
static std::optional< llvm::Value * > tryEmitSpecializedAllocInit(CodeGenFunction &CGF, const ObjCMessageExpr *OME)
Instead of '[[MyClass alloc] init]', try to generate 'objc_alloc_init(MyClass)'.
Definition CGObjC.cpp:525
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...
Definition CGObjC.cpp:2289
llvm::function_ref< llvm::Value *(CodeGenFunction &CGF, llvm::Value *value)> ValueTransform
Definition CGObjC.cpp:3001
static llvm::Value * emitARCUnsafeUnretainedScalarExpr(CodeGenFunction &CGF, const Expr *e)
Definition CGObjC.cpp:3609
static llvm::Value * emitARCLoadOperation(CodeGenFunction &CGF, Address addr, llvm::Function *&fn, llvm::Intrinsic::ID IntID)
Perform an operation having the following signature: i8* (i8**)
Definition CGObjC.cpp:2237
static llvm::Constant * getNullForVariable(Address addr)
Given the address of a variable of pointer type, find the correct null to store into it.
Definition CGObjC.cpp:45
static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF)
Definition CGObjC.cpp:2373
static const Expr * findWeakLValue(const Expr *E)
Given an expression of ObjC pointer type, check whether it was immediately loaded from an ARC __weak ...
Definition CGObjC.cpp:350
llvm::PointerIntPair< llvm::Value *, 1, bool > TryEmitResult
Definition CGObjC.cpp:36
static bool hasUnalignedAtomics(llvm::Triple::ArchType arch)
Determine whether the given architecture supports unaligned atomic accesses.
Definition CGObjC.cpp:848
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**)
Definition CGObjC.cpp:2272
static void AppendFirstImpliedRuntimeProtocols(const ObjCProtocolDecl *PD, llvm::UniqueVector< const ObjCProtocolDecl * > &PDs)
Definition CGObjC.cpp:452
static TryEmitResult tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e)
Definition CGObjC.cpp:3475
static llvm::Value * emitOptimizedARCReturnCall(llvm::Value *value, bool IsRetainRV, CodeGenFunction &CGF)
Definition CGObjC.cpp:2412
static llvm::Value * emitCmdValueForGetterSetterBody(CodeGenFunction &CGF, ObjCMethodDecl *MD)
Definition CGObjC.cpp:1121
static llvm::Function * getARCIntrinsic(llvm::Intrinsic::ID IntID, CodeGenModule &CGM)
Definition CGObjC.cpp:2203
static bool isFoundationNeededForDarwinAvailabilityCheck(const llvm::Triple &TT, const VersionTuple &TargetVersion)
Definition CGObjC.cpp:4058
static bool shouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message)
Decide whether to extend the lifetime of the receiver of a returns-inner-pointer message.
Definition CGObjC.cpp:291
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*)
Definition CGObjC.cpp:2248
static unsigned getBaseMachOPlatformID(const llvm::Triple &TT)
Definition CGObjC.cpp:3977
static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF, LValue lvalue, QualType type)
Definition CGObjC.cpp:2938
static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, llvm::Value *RTF)
Definition CGObjC.cpp:2186
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...
Definition CGObjC.cpp:377
static CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM, llvm::Triple::ArchType arch)
Return the maximum size that permits atomic accesses for the given architecture.
Definition CGObjC.cpp:856
static llvm::Value * emitARCRetainCallResult(CodeGenFunction &CGF, const Expr *e)
Given that the given expression is some sort of call (which does not return retained),...
Definition CGObjC.cpp:3063
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.
Definition CGObjC.cpp:1087
static llvm::Value * emitIsPlatformVersionAtLeast(CodeGenFunction &CGF, const VersionTuple &Version)
Definition CGObjC.cpp:3997
static void destroyARCStrongWithStore(CodeGenFunction &CGF, Address addr, QualType type)
Like CodeGenFunction::destroyARCStrong, but do it with a call.
Definition CGObjC.cpp:1709
static llvm::Value * emitARCRetainLoadOfScalar(CodeGenFunction &CGF, LValue lvalue, QualType type)
Definition CGObjC.cpp:3479
static void emitCXXDestructMethod(CodeGenFunction &CGF, ObjCImplementationDecl *impl)
Definition CGObjC.cpp:1716
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.
Definition CGObjC.cpp:818
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...
Definition CGObjC.cpp:2213
static llvm::Value * emitARCOperationAfterCall(CodeGenFunction &CGF, llvm::Value *value, ValueTransform doAfterCall, ValueTransform doFallback)
Insert code immediately after a call.
Definition CGObjC.cpp:3007
static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, ObjCIvarDecl *ivar)
emitStructSetterCall - Call the runtime function to store the value from the first formal parameter i...
Definition CGObjC.cpp:1360
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...
Definition CGObjC.cpp:1403
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,...
Definition CGObjC.cpp:273
static bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID)
Definition CGObjC.cpp:1437
static bool UseOptimizedSetter(CodeGenModule &CGM)
Definition CGObjC.cpp:1461
static Decl::Kind getKind(const Decl *D)
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.
TypeInfoChars getTypeInfoInChars(const Type *T) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
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
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.
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::LoadInst * CreateLoad(Address Addr, const llvm::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 ~CGObjCRuntime()
Definition CGObjC.cpp:4129
virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in getter.
virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction()=0
API for atomic copying of qualified aggregates with non-trivial copy assignment (c++) in setter.
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.
Definition CGObjC.cpp:438
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 GetGetStructFunction()=0
virtual llvm::Value * GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID)=0
GetClass - Return a reference to the class for the given interface decl.
virtual llvm::Value * EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF)
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...
Definition CGObjC.cpp:466
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
An abstract representation of regular/ObjC call/message targets.
static AutoVarEmission invalid()
A non-RAII class containing all the information about a bound opaque value.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
bool requiresCleanups() const
Determine whether this scope requires any cleanups.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
Definition CGObjC.cpp:2152
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
llvm::Value * EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType)
Autorelease the given object.
Definition CGObjC.cpp:2848
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
Definition CGObjC.cpp:573
void EmitARCMoveWeak(Address dst, Address src)
void @objc_moveWeak(i8** dest, i8** src) Disregards the current value in dest.
Definition CGObjC.cpp:2692
llvm::Value * EmitARCRetainAutoreleaseReturnValue(llvm::Value *value)
Do a fused retain/autorelease of the given object.
Definition CGObjC.cpp:2599
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
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...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
Definition CGObjC.cpp:3089
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
Definition CGObjC.cpp:3679
llvm::Value * EmitARCUnsafeUnretainedScalarExpr(const Expr *expr)
EmitARCUnsafeUnretainedScalarExpr - Semantically equivalent to immediately releasing the resut of Emi...
Definition CGObjC.cpp:3618
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
Definition CGObjC.cpp:257
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
void EmitARCInitWeak(Address addr, llvm::Value *value)
i8* @objc_initWeak(i8** addr, i8* value) Returns value.
Definition CGObjC.cpp:2663
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
Definition CGObjC.cpp:251
llvm::Type * ConvertType(QualType T)
static Destroyer destroyARCWeak
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
Definition CGObjC.cpp:265
llvm::CallBase * EmitCallOrInvoke(llvm::FunctionCallee Callee, ArrayRef< llvm::Value * > Args, const Twine &Name="")
Emits a call or invoke instruction to the given function, depending on the current state of the EH st...
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
llvm::Value * EmitARCAutoreleaseReturnValue(llvm::Value *value)
Autorelease the given object.
Definition CGObjC.cpp:2589
llvm::Value * EmitARCRetain(QualType type, llvm::Value *value)
Produce the code to do a retain.
Definition CGObjC.cpp:2328
CleanupKind getARCCleanupKind()
Retrieves the default cleanup kind for an ARC cleanup.
llvm::Value * EmitARCAutorelease(llvm::Value *value)
Autorelease the given object.
Definition CGObjC.cpp:2580
llvm::Value * EmitARCRetainAutoreleaseScalarExpr(const Expr *expr)
Definition CGObjC.cpp:3508
bool shouldUseFusedARCCalls()
void EmitARCDestroyWeak(Address addr)
void @objc_destroyWeak(i8** addr) Essentially objc_storeWeak(addr, nil).
Definition CGObjC.cpp:2681
void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
Release the given object.
Definition CGObjC.cpp:2867
llvm::Value * EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType)
Definition CGObjC.cpp:2805
void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
Definition CGObjC.cpp:2129
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)
Definition CGObjC.cpp:2916
void EmitAutoVarInit(const AutoVarEmission &emission)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
Definition CGObjC.cpp:247
const LangOptions & getLangOpts() const
llvm::Value * EmitARCRetainAutorelease(QualType type, llvm::Value *value)
Do a fused retain/autorelease of the given object.
Definition CGObjC.cpp:2611
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
Definition CGObjC.cpp:2545
llvm::Value * EmitARCRetainAutoreleasedReturnValue(llvm::Value *value)
Retain the given object which is the result of a function call.
Definition CGObjC.cpp:2463
void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD)
StartObjCMethod - Begin emission of an ObjCMethod.
Definition CGObjC.cpp:752
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
llvm::Value * EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value)
Claim a possibly-autoreleased return value at +0.
Definition CGObjC.cpp:2475
llvm::Value * EmitObjCMRRAutoreleasePoolPush()
Produce the code to do an MRR version objc_autoreleasepool_push.
Definition CGObjC.cpp:2764
LValue EmitLValueForIvar(QualType ObjectTy, llvm::Value *Base, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)
void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, ObjCMethodDecl *MD, bool ctor)
Definition CGObjC.cpp:1752
llvm::Value * EmitObjCAllocWithZone(llvm::Value *value, llvm::Type *returnType)
Allocate the given objc object.
Definition CGObjC.cpp:2798
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
llvm::Value * EmitObjCThrowOperand(const Expr *expr)
Definition CGObjC.cpp:3542
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
Release the given object.
Definition CGObjC.cpp:2481
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
Definition CGObjC.cpp:3629
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void GenerateObjCGetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID)
GenerateObjCGetter - Synthesize an Objective-C property getter function.
Definition CGObjC.cpp:1049
llvm::Value * EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
Definition CGObjC.cpp:3953
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
Destroy a __strong variable.
Definition CGObjC.cpp:2510
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
QualType TypeOfSelfObject()
TypeOfSelfObject - Return type of object that this self represents.
Definition CGObjC.cpp:1796
static Destroyer destroyARCStrongImprecise
void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S)
Definition CGObjC.cpp:3688
llvm::BasicBlock * getInvokeDest()
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.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
Definition CGObjC.cpp:64
void generateObjCSetterBody(const ObjCImplementationDecl *classImpl, const ObjCPropertyImplDecl *propImpl, llvm::Constant *AtomicHelperFn)
Definition CGObjC.cpp:1468
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void EmitExtendGCLifetime(llvm::Value *object)
EmitExtendGCLifetime - Given a pointer to an Objective-C object, make sure it survives garbage collec...
Definition CGObjC.cpp:3716
LValue EmitDeclRefLValue(const DeclRefExpr *E)
void callCStructCopyConstructor(LValue Dst, LValue Src)
llvm::Value * EmitARCRetainBlock(llvm::Value *value, bool mandatory)
Retain the given block, with _Block_copy semantics.
Definition CGObjC.cpp:2349
llvm::Value * EmitObjCCollectionLiteral(const Expr *E, const ObjCMethodDecl *MethodWithObjects)
Definition CGObjC.cpp:123
CGDebugInfo * getDebugInfo()
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...
Definition CGObjC.cpp:3493
void EmitObjCAtTryStmt(const ObjCAtTryStmt &S)
Definition CGObjC.cpp:2125
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,...
CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Emit the concrete pointer authentication informaton for the given authentication schema.
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
llvm::Value * EmitObjCAlloc(llvm::Value *value, llvm::Type *returnType)
Allocate the given objc object.
Definition CGObjC.cpp:2789
llvm::Value * LoadObjCSelf()
LoadObjCSelf - Load the value of self.
Definition CGObjC.cpp:1788
void GenerateObjCMethod(const ObjCMethodDecl *OMD)
Generate an Objective-C method.
Definition CGObjC.cpp:807
void callCStructMoveAssignmentOperator(LValue Dst, LValue Src)
llvm::Value * EmitARCLoadWeakRetained(Address addr)
i8* @objc_loadWeakRetained(i8** addr)
Definition CGObjC.cpp:2643
llvm::Value * emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
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 emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)
Definition CGObjC.cpp:2714
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
llvm::Constant * GenerateObjCAtomicSetterCopyHelperFunction(const ObjCPropertyImplDecl *PID)
GenerateObjCAtomicSetterCopyHelperFunction - Given a c++ object type with non-trivial copy assignment...
Definition CGObjC.cpp:3733
void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S)
Definition CGObjC.cpp:2133
void EmitARCNoopIntrinsicUse(ArrayRef< llvm::Value * > values)
Emit a call to "clang.arc.noop.use", which consumes the result of a call that has operand bundle "cla...
Definition CGObjC.cpp:2179
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...
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.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
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="")
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
Definition CGObjC.cpp:2337
llvm::Type * ConvertTypeForMem(QualType T)
void generateObjCGetterBody(const ObjCImplementationDecl *classImpl, const ObjCPropertyImplDecl *propImpl, const ObjCMethodDecl *GetterMothodDecl, llvm::Constant *AtomicHelperFn)
Definition CGObjC.cpp:1135
llvm::Value * EmitARCRetainAutoreleaseNonBlock(llvm::Value *value)
Do a fused retain/autorelease of the given object.
Definition CGObjC.cpp:2628
llvm::Value * EmitObjCAutoreleasePoolPush()
Produce the code to do a objc_autoreleasepool_push.
Definition CGObjC.cpp:2724
void GenerateObjCSetter(ObjCImplementationDecl *IMP, const ObjCPropertyImplDecl *PID)
GenerateObjCSetter - Synthesize an Objective-C property setter function for the given property.
Definition CGObjC.cpp:1672
llvm::Value * EmitARCLoadWeak(Address addr)
i8* @objc_loadWeak(i8** addr) Essentially objc_autorelease(objc_loadWeakRetained(addr)).
Definition CGObjC.cpp:2636
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
llvm::Constant * GenerateObjCAtomicGetterCopyHelperFunction(const ObjCPropertyImplDecl *PID)
Definition CGObjC.cpp:3833
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 * EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr)
Definition CGObjC.cpp:2160
AggValueSlot::Overlap_t getOverlapForReturnValue()
Determine whether a return value slot may overlap some other object.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
Definition CGObjC.cpp:4033
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitReturnStmt(const ReturnStmt &S)
EmitReturnStmt - Note that due to GCC extensions, this can have an operand if the function returns vo...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
llvm::Value * EmitARCStoreStrongCall(Address addr, llvm::Value *value, bool resultIgnored)
Store into a strong object.
Definition CGObjC.cpp:2524
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
Definition CGObjC.cpp:51
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr)
Produce the code to do a primitive release.
Definition CGObjC.cpp:2814
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 * EmitARCExtendBlockObject(const Expr *expr)
Definition CGObjC.cpp:3524
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
Definition CGObjC.cpp:2651
llvm::LLVMContext & getLLVMContext()
static Destroyer destroyARCStrongPrecise
void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
Definition CGObjC.cpp:1804
void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr)
Produce the code to do a primitive release.
Definition CGObjC.cpp:2734
llvm::Value * EmitObjCRetainNonBlock(llvm::Value *value, llvm::Type *returnType)
Retain the given object, with normal retain semantics.
Definition CGObjC.cpp:2858
void EmitARCCopyWeak(Address dst, Address src)
void @objc_copyWeak(i8** dest, i8** src) Disregards the current value in dest.
Definition CGObjC.cpp:2701
void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr)
Definition CGObjC.cpp:2707
static Destroyer emitARCIntrinsicUse
void EmitARCIntrinsicUse(ArrayRef< llvm::Value * > values)
Given a number of pointers, inform the optimizer that they're being intrinsically used up until this ...
Definition CGObjC.cpp:2167
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...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
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.
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
ObjCEntrypoints & getObjCEntrypoints() const
const llvm::Triple & getTriple() const
ASTContext & getContext() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
llvm::FunctionCallee IsPlatformVersionAtLeastFn
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
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.
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
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 }.
SourceLocation getLBracLoc() const
SourceLocation getRBracLoc() const
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, const AssociatedConstraint &TrailingRequiresClause={})
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.
ObjCMethodDecl * getArrayWithObjectsMethod() const
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.
ObjCMethodDecl * getBoxingMethod() const
bool isExpressibleAsConstantInitializer() const
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.
ObjCMethodDecl * getDictWithObjectsMethod() const
ObjCDictionaryElement getKeyValueElement(unsigned Index) const
Represents Objective-C's collection statement.
SourceLocation getBeginLoc() const LLVM_READONLY
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
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
ObjCInterfaceDecl * getDecl() const
Get the declaration of this interface.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCIvarDecl * getNextIvar()
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
bool isDelegateInitCall() const
isDelegateInitCall - Answers whether this message send has been tagged as a "delegate init call",...
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.
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
llvm::iterator_range< arg_iterator > arguments()
QualType getSuperType() const
Retrieve the type referred to by 'super'.
const ObjCMethodDecl * getMethodDecl() const
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 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.
ObjCProtocolDecl * getProtocol() const
The basic abstraction for the target Objective-C runtime.
bool hasAtomicCopyHelper() const
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.
Selector getSelector() const
ObjCStringLiteral, used for Objective-C string literals i.e.
StringLiteral * getString()
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)
Pointer-authentication qualifiers.
semantics_iterator semantics_end()
semantics_iterator semantics_begin()
const Expr *const * const_semantics_iterator
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
PointerAuthQualifier getPointerAuth() const
@ 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)
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.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
Exposes information about the current target.
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
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() 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 isAtomicType() const
bool isObjCObjectPointerType() const
bool isObjCClassType() const
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.
bool isARCPseudoStrong() const
Determine whether this variable is an ARC pseudo-__strong variable.
@ 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 internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ 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.
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::BasicBlock * getBlock() const
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::InlineAsm * retainAutoreleasedReturnValueMarker
A void(void) inline asm to use to mark that the return value of a call will be immediately retain.
llvm::Function * objc_unsafeClaimAutoreleasedReturnValue
id objc_unsafeClaimAutoreleasedReturnValue(id);
Expr * Value
The value of the dictionary element.
Expr * Key
The key for the dictionary element.